Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions be/src/vec/data_types/serde/data_type_struct_serde.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ Status DataTypeStructSerDe::deserialize_one_cell_from_json(IColumn& column, Slic
}
Slice next(slice.data + start_pos, idx - start_pos);
next.trim_prefix();
if (field_pos > elem_size) {
// field_pos should always less than elem_size, if not, we should return error
if (field_pos >= elem_size) {
// we should do column revert if error
for (size_t j = 0; j < field_pos; j++) {
struct_column.get_column(j).pop_back(1);
Expand Down Expand Up @@ -188,7 +189,8 @@ Status DataTypeStructSerDe::deserialize_one_cell_from_json(IColumn& column, Slic
(key_added || !is_explicit_names)) {
Slice next(slice.data + start_pos, idx - start_pos);
next.trim_prefix();
if (field_pos > elem_size) {
/// field_pos should always less than elem_size, if not, we should return error
if (field_pos >= elem_size) {
// we should do column revert if error
for (size_t j = 0; j < field_pos; j++) {
struct_column.get_column(j).pop_back(1);
Expand Down
40 changes: 40 additions & 0 deletions regression-test/data/insert_p0/test_struct_insert.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,43 @@
3 \N {"f1":null, "f2":null, "f3":null} {"f1":"2023-02-23", "f2":"2023-02-23 00:10:19", "f3":"2023-02-23", "f4":"2023-02-23 00:10:19"} {"f1":"", "f2":"", "f3":""}
4 \N \N {"f1":null, "f2":null, "f3":null, "f4":null} {"f1":"abc", "f2":"def", "f3":"hij"}

-- !select --
1 {"a":1} {"a":1, "b":"a"} {"a":1, "s":{"a":1}} {"a":1, "s":{"a":1, "b":"a"}} {"a":1, "s":{"b":1, "s":{"c":1}}} {"a":1, "b":{"c":1, "d":"a"}, "e":1}

-- !select --
1 {"a":1} {"a":1, "b":"a"} {"a":1, "s":{"a":1}} {"a":1, "s":{"a":1, "b":"a"}} {"a":1, "s":{"b":1, "s":{"c":1}}} {"a":1, "b":{"c":1, "d":"a"}, "e":1}
2 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":{"a":31}} {"a":40, "s":{"a":41, "b":"nested"}} {"a":50, "s":{"b":51, "s":{"c":52}}} {"a":60, "b":{"c":61, "d":"text"}, "e":70}

-- !select --
1 {"a":1} {"a":1, "b":"a"} {"a":1, "s":{"a":1}} {"a":1, "s":{"a":1, "b":"a"}} {"a":1, "s":{"b":1, "s":{"c":1}}} {"a":1, "b":{"c":1, "d":"a"}, "e":1}
2 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":{"a":31}} {"a":40, "s":{"a":41, "b":"nested"}} {"a":50, "s":{"b":51, "s":{"c":52}}} {"a":60, "b":{"c":61, "d":"text"}, "e":70}
3 \N {"a":30, "b":"valid"} \N {"a":40, "s":{"a":41, "b":"valid"}} {"a":50, "s":{"b":51, "s":null}} {"a":60, "b":null, "e":70}

-- !select --
1 {"a":1} {"a":1, "b":"a"} {"a":1, "s":{"a":1}} {"a":1, "s":{"a":1, "b":"a"}} {"a":1, "s":{"b":1, "s":{"c":1}}} {"a":1, "b":{"c":1, "d":"a"}, "e":1}
2 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":{"a":31}} {"a":40, "s":{"a":41, "b":"nested"}} {"a":50, "s":{"b":51, "s":{"c":52}}} {"a":60, "b":{"c":61, "d":"text"}, "e":70}
3 \N {"a":30, "b":"valid"} \N {"a":40, "s":{"a":41, "b":"valid"}} {"a":50, "s":{"b":51, "s":null}} {"a":60, "b":null, "e":70}
4 {"a":null} {"a":40, "b":"50"} {"a":50, "s":{"a":null}} {"a":60, "s":{"a":70, "b":"80"}} {"a":90, "s":{"b":null, "s":{"c":100}}} {"a":100, "b":{"c":110, "d":"120"}, "e":null}

-- !select --
1 {"a":1} {"a":1, "b":"a"} {"a":1, "s":{"a":1}} {"a":1, "s":{"a":1, "b":"a"}} {"a":1, "s":{"b":1, "s":{"c":1}}} {"a":1, "b":{"c":1, "d":"a"}, "e":1}
2 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":{"a":31}} {"a":40, "s":{"a":41, "b":"nested"}} {"a":50, "s":{"b":51, "s":{"c":52}}} {"a":60, "b":{"c":61, "d":"text"}, "e":70}
3 \N {"a":30, "b":"valid"} \N {"a":40, "s":{"a":41, "b":"valid"}} {"a":50, "s":{"b":51, "s":null}} {"a":60, "b":null, "e":70}
4 {"a":null} {"a":40, "b":"50"} {"a":50, "s":{"a":null}} {"a":60, "s":{"a":70, "b":"80"}} {"a":90, "s":{"b":null, "s":{"c":100}}} {"a":100, "b":{"c":110, "d":"120"}, "e":null}
5 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":null} {"a":40, "s":null} {"a":50, "s":{"b":51, "s":null}} {"a":60, "b":null, "e":70}

-- !select --
1 {"a":1} {"a":1, "b":"a"} {"a":1, "s":{"a":1}} {"a":1, "s":{"a":1, "b":"a"}} {"a":1, "s":{"b":1, "s":{"c":1}}} {"a":1, "b":{"c":1, "d":"a"}, "e":1}
2 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":{"a":31}} {"a":40, "s":{"a":41, "b":"nested"}} {"a":50, "s":{"b":51, "s":{"c":52}}} {"a":60, "b":{"c":61, "d":"text"}, "e":70}
3 \N {"a":30, "b":"valid"} \N {"a":40, "s":{"a":41, "b":"valid"}} {"a":50, "s":{"b":51, "s":null}} {"a":60, "b":null, "e":70}
4 {"a":null} {"a":40, "b":"50"} {"a":50, "s":{"a":null}} {"a":60, "s":{"a":70, "b":"80"}} {"a":90, "s":{"b":null, "s":{"c":100}}} {"a":100, "b":{"c":110, "d":"120"}, "e":null}
5 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":null} {"a":40, "s":null} {"a":50, "s":{"b":51, "s":null}} {"a":60, "b":null, "e":70}

-- !select --
1 {"a":1} {"a":1, "b":"a"} {"a":1, "s":{"a":1}} {"a":1, "s":{"a":1, "b":"a"}} {"a":1, "s":{"b":1, "s":{"c":1}}} {"a":1, "b":{"c":1, "d":"a"}, "e":1}
2 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":{"a":31}} {"a":40, "s":{"a":41, "b":"nested"}} {"a":50, "s":{"b":51, "s":{"c":52}}} {"a":60, "b":{"c":61, "d":"text"}, "e":70}
3 \N {"a":30, "b":"valid"} \N {"a":40, "s":{"a":41, "b":"valid"}} {"a":50, "s":{"b":51, "s":null}} {"a":60, "b":null, "e":70}
4 {"a":null} {"a":40, "b":"50"} {"a":50, "s":{"a":null}} {"a":60, "s":{"a":70, "b":"80"}} {"a":90, "s":{"b":null, "s":{"c":100}}} {"a":100, "b":{"c":110, "d":"120"}, "e":null}
5 {"a":10} {"a":20, "b":"valid"} {"a":30, "s":null} {"a":40, "s":null} {"a":50, "s":{"b":51, "s":null}} {"a":60, "b":null, "e":70}
7 {"a":10} {"a":20, "b":""} {"a":30, "s":null} {"a":40, "s":{"a":41, "b":"nested"}} {"a":50, "s":{"b":51, "s":{"c":52}}} {"a":60, "b":{"c":61, "d":""}, "e":70}

101 changes: 100 additions & 1 deletion regression-test/suites/insert_p0/test_struct_insert.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,103 @@ suite("test_struct_insert") {

// select the table and check whether the data is correct
qt_select "select * from ${testTable} order by k1"
}

sql "DROP TABLE IF EXISTS test_struct_insert_into"
sql """
CREATE TABLE IF NOT EXISTS test_struct_insert_into (
id INT,
s STRUCT<a:INT>,
s1 STRUCT<a:INT, b:VARCHAR(20)>,
s2 struct<a:int, s:struct<a:int>>,
s3 struct<a:int, s:struct<a:int, b:varchar(20)>>,
s4 STRUCT<a:INT, s:STRUCT<b:INT, s:STRUCT<c:INT>>>,
s5 STRUCT<a:INT, b:STRUCT<c:INT, d:VARCHAR(10)>, e:INT>
) PROPERTIES ("replication_allocation" = "tag.location.default: 1");
"""

// insert into table
// right cases
sql "INSERT INTO test_struct_insert_into VALUES(1, {1}, {1, 'a'}, {1, {1}}, {1, {1, 'a'}}, {1, {1, {1}}}, {1, {1, 'a'}, 1})"

qt_select "select * from test_struct_insert_into order by id"

sql """INSERT INTO test_struct_insert_into VALUES (
2,
'{10}', -- s: right
'{20, "valid"}', -- s1: right
'{30, {31}}', -- s2: right(outer a=30,s.a=31)
'{40, {41, "nested"}}', -- s3: right(a=40,s.a=41, s.b="nested")
'{50, {51, {52}}}', -- s4: right(a=50 -> s.b=51 -> s.s.c=52)
'{60, {61, "text"}, 70}' -- s5: right(a=60, b.c=61, b.d="text", e=70)
);"""

qt_select "select * from test_struct_insert_into order by id"

sql """
INSERT INTO test_struct_insert_into VALUES (
3,
'{10, 20}', -- s: more -> NULL
'{30, "valid"}', -- s1: right
NULL, -- s2: NULL
'{40, {41, "valid"}}', -- s3: right
'{50, {51, null}}', -- s4: s.s is null
'{60, NULL, 70}' -- s5: b is NULL
);
"""

qt_select "select * from test_struct_insert_into order by id"

sql """
INSERT INTO test_struct_insert_into VALUES (
4,
'{"invalid"}', -- s.a type invalid cast -> s.a is NULL
'{40, 50}', -- right
'{50, {"invalid"}}',-- s2.s.a type invalid cast -> s2.s is {"a":null}
'{60, {70, 80}}', -- right
'{90, {"invalid", {100}}}', -- s4.s.b type invalid cast -> s4.s is NULL
'{100, {110, 120}, "invalid"}' -- s5.e type invalid cast -> s5.e is NULL
);
"""
qt_select "select * from test_struct_insert_into order by id"

sql """
INSERT INTO test_struct_insert_into VALUES (
5,
'{10}',
'{20, "valid"}',
'{30, {31, 32}}', -- s2.s more -> s2.s is NULL
'{40, {41, "nested", 42}}', -- s3.s more -> s3.s is NULL
'{50, {51, {52, 53}}}', -- s4.s.s more -> s4.s.s is NULL
'{60, {61, "text", 62}, 70}' -- s5.b more -> s5.b is NULL
);
"""
qt_select "select * from test_struct_insert_into order by id"
test {
sql """
INSERT INTO test_struct_insert_into VALUES (
6,
'{10}',
'{20}', -- s1 less -> s1 is NULL
'{30, {31}}', -- s2 right
'{40, {41}}', -- s3.s less -> s3.s is NULL
'{50, {51}}', -- s4.s less -> s4.s is NULL
'{60, {61}, 70}' -- s5.b less -> s5.b is NULL
);
"""
exception("Size of offsets doesn't match size of column")
}
qt_select "select * from test_struct_insert_into order by id"

sql """
INSERT INTO test_struct_insert_into VALUES (
7,
'{10}', -- right
'{20, }', -- s1.b is empty
'{30, }', -- s2.s is empty
'{40, {41, "nested"}}', -- right
'{50, {51, {52}}}', -- right
'{60, {61, }, 70}' -- s5.b.d is empty
);
"""
qt_select "select * from test_struct_insert_into order by id"
}
Loading