diff --git a/be/src/vec/functions/function_fake.cpp b/be/src/vec/functions/function_fake.cpp index 350f6b4e95faef..6997d9c93855c1 100644 --- a/be/src/vec/functions/function_fake.cpp +++ b/be/src/vec/functions/function_fake.cpp @@ -117,17 +117,20 @@ struct FunctionExplodeMap { template struct FunctionPoseExplode { static DataTypePtr get_return_type_impl(const DataTypes& arguments) { - DCHECK(arguments[0]->get_primitive_type() == TYPE_ARRAY) - << arguments[0]->get_name() << " not supported"; - DataTypes fieldTypes(2); + DataTypes fieldTypes(arguments.size() + 1); fieldTypes[0] = std::make_shared(); - fieldTypes[1] = - check_and_get_data_type(arguments[0].get())->get_nested_type(); + for (int i = 0; i < arguments.size(); i++) { + DCHECK_EQ(arguments[i]->get_primitive_type(), TYPE_ARRAY) + << arguments[i]->get_name() << " not supported"; + auto nestedType = + check_and_get_data_type(arguments[i].get())->get_nested_type(); + fieldTypes[i + 1] = make_nullable(nestedType); + } auto struct_type = std::make_shared(fieldTypes); if constexpr (AlwaysNullable) { return make_nullable(struct_type); } else { - return arguments[0]->is_nullable() ? make_nullable(struct_type) : struct_type; + return struct_type; } } static DataTypes get_variadic_argument_types() { return {}; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplode.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplode.java index b5091c09f1d6b2..d9f984cf175322 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplode.java @@ -20,7 +20,7 @@ import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.trees.expressions.Expression; -import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable; +import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision; import org.apache.doris.nereids.trees.expressions.functions.CustomSignature; import org.apache.doris.nereids.trees.expressions.functions.SearchSignature; @@ -44,7 +44,8 @@ * pose column: 0, 1, 2 * value column: 'a', 'b', 'c' */ -public class PosExplode extends TableGeneratingFunction implements CustomSignature, ComputePrecision, AlwaysNullable { +public class PosExplode extends TableGeneratingFunction implements + CustomSignature, ComputePrecision, AlwaysNotNullable { public static final String POS_COLUMN = "pos"; /** diff --git a/regression-test/data/nereids_p0/sql_functions/table_function/posexplode.out b/regression-test/data/nereids_p0/sql_functions/table_function/posexplode.out index e21701f6baee71..30593a55d3f91d 100644 --- a/regression-test/data/nereids_p0/sql_functions/table_function/posexplode.out +++ b/regression-test/data/nereids_p0/sql_functions/table_function/posexplode.out @@ -331,3 +331,140 @@ 2 tom ["t1_c"] ["t2_d", "t2_e"] {"pos":1, "col1":null, "col2":"t2_e"} {"pos":0, "col1":"t1_c", "col2":"t2_d"} 2 tom ["t1_c"] ["t2_d", "t2_e"] {"pos":1, "col1":null, "col2":"t2_e"} {"pos":1, "col1":null, "col2":"t2_e"} +-- !mixed_nullable_all -- +1 ["t_not_null1_a", "t_not_null1_b"] ["t_not_null2_a", "t_not_null2_b"] ["t_null1_a", "t_null1_b"] ["t_null2_a", "t_null2_b"] +2 ["t_not_null1_c"] ["t_not_null2_c", "t_not_null2_d"] ["t_null1_c"] ["t_null2_c", "t_null2_d"] +3 ["t_not_null1_d", "t_not_null1_e"] ["t_not_null2_e"] ["t_null1_d", "t_null1_e"] ["t_null2_e"] +4 ["t_not_null1_f"] ["t_not_null2_f"] \N ["t_null2_f"] +5 ["t_not_null1_g"] ["t_not_null2_g"] ["t_null1_f"] \N +6 ["t_not_null1_h"] ["t_not_null2_h"] \N \N + +-- !mixed_nullable_not_null0 -- +1 {"pos":0, "col1":"t_not_null1_a"} +1 {"pos":1, "col1":"t_not_null1_b"} +2 {"pos":0, "col1":"t_not_null1_c"} +3 {"pos":0, "col1":"t_not_null1_d"} +3 {"pos":1, "col1":"t_not_null1_e"} +4 {"pos":0, "col1":"t_not_null1_f"} +5 {"pos":0, "col1":"t_not_null1_g"} +6 {"pos":0, "col1":"t_not_null1_h"} + +-- !mixed_nullable_not_null1 -- +1 0 t_not_null1_a +1 1 t_not_null1_b +2 0 t_not_null1_c +3 0 t_not_null1_d +3 1 t_not_null1_e +4 0 t_not_null1_f +5 0 t_not_null1_g +6 0 t_not_null1_h + +-- !mixed_nullable_not_null2 -- +1 {"pos":0, "col1":"t_not_null1_a", "col2":"t_not_null2_a"} +1 {"pos":1, "col1":"t_not_null1_b", "col2":"t_not_null2_b"} +2 {"pos":0, "col1":"t_not_null1_c", "col2":"t_not_null2_c"} +2 {"pos":1, "col1":null, "col2":"t_not_null2_d"} +3 {"pos":0, "col1":"t_not_null1_d", "col2":"t_not_null2_e"} +3 {"pos":1, "col1":"t_not_null1_e", "col2":null} +4 {"pos":0, "col1":"t_not_null1_f", "col2":"t_not_null2_f"} +5 {"pos":0, "col1":"t_not_null1_g", "col2":"t_not_null2_g"} +6 {"pos":0, "col1":"t_not_null1_h", "col2":"t_not_null2_h"} + +-- !mixed_nullable_not_null3 -- +1 0 t_not_null1_a t_not_null2_a +1 1 t_not_null1_b t_not_null2_b +2 0 t_not_null1_c t_not_null2_c +2 1 \N t_not_null2_d +3 0 t_not_null1_d t_not_null2_e +3 1 t_not_null1_e \N +4 0 t_not_null1_f t_not_null2_f +5 0 t_not_null1_g t_not_null2_g +6 0 t_not_null1_h t_not_null2_h + +-- !mixed_nullable_not_null_outer0 -- +1 {"pos":0, "col1":"t_not_null1_a"} +1 {"pos":1, "col1":"t_not_null1_b"} +2 {"pos":0, "col1":"t_not_null1_c"} +3 {"pos":0, "col1":"t_not_null1_d"} +3 {"pos":1, "col1":"t_not_null1_e"} +4 {"pos":0, "col1":"t_not_null1_f"} +5 {"pos":0, "col1":"t_not_null1_g"} +6 {"pos":0, "col1":"t_not_null1_h"} + +-- !mixed_nullable_not_null_outer1 -- +1 0 t_not_null1_a +1 1 t_not_null1_b +2 0 t_not_null1_c +3 0 t_not_null1_d +3 1 t_not_null1_e +4 0 t_not_null1_f +5 0 t_not_null1_g +6 0 t_not_null1_h + +-- !mixed_nullable_not_null_outer2 -- +1 {"pos":0, "col1":"t_not_null1_a", "col2":"t_not_null2_a"} +1 {"pos":1, "col1":"t_not_null1_b", "col2":"t_not_null2_b"} +2 {"pos":0, "col1":"t_not_null1_c", "col2":"t_not_null2_c"} +2 {"pos":1, "col1":null, "col2":"t_not_null2_d"} +3 {"pos":0, "col1":"t_not_null1_d", "col2":"t_not_null2_e"} +3 {"pos":1, "col1":"t_not_null1_e", "col2":null} +4 {"pos":0, "col1":"t_not_null1_f", "col2":"t_not_null2_f"} +5 {"pos":0, "col1":"t_not_null1_g", "col2":"t_not_null2_g"} +6 {"pos":0, "col1":"t_not_null1_h", "col2":"t_not_null2_h"} + +-- !mixed_nullable_not_null_outer3 -- +1 0 t_not_null1_a t_not_null2_a +1 1 t_not_null1_b t_not_null2_b +2 0 t_not_null1_c t_not_null2_c +2 1 \N t_not_null2_d +3 0 t_not_null1_d t_not_null2_e +3 1 t_not_null1_e \N +4 0 t_not_null1_f t_not_null2_f +5 0 t_not_null1_g t_not_null2_g +6 0 t_not_null1_h t_not_null2_h + +-- !mixed_nullable2 -- +1 {"pos":0, "col1":"t_not_null1_a", "col2":"t_null1_a"} +1 {"pos":1, "col1":"t_not_null1_b", "col2":"t_null1_b"} +2 {"pos":0, "col1":"t_not_null1_c", "col2":"t_null1_c"} +3 {"pos":0, "col1":"t_not_null1_d", "col2":"t_null1_d"} +3 {"pos":1, "col1":"t_not_null1_e", "col2":"t_null1_e"} +4 {"pos":0, "col1":"t_not_null1_f", "col2":null} +5 {"pos":0, "col1":"t_not_null1_g", "col2":"t_null1_f"} +6 {"pos":0, "col1":"t_not_null1_h", "col2":null} + +-- !mixed_nullable3 -- +1 0 t_not_null1_a t_null1_a +1 1 t_not_null1_b t_null1_b +2 0 t_not_null1_c t_null1_c +3 0 t_not_null1_d t_null1_d +3 1 t_not_null1_e t_null1_e +4 0 t_not_null1_f \N +5 0 t_not_null1_g t_null1_f +6 0 t_not_null1_h \N + +-- !mixed_nullable_outer2 -- +1 {"pos":0, "col1":"t_not_null1_a", "col2":"t_null1_a"} +1 {"pos":1, "col1":"t_not_null1_b", "col2":"t_null1_b"} +2 {"pos":0, "col1":"t_not_null1_c", "col2":"t_null1_c"} +3 {"pos":0, "col1":"t_not_null1_d", "col2":"t_null1_d"} +3 {"pos":1, "col1":"t_not_null1_e", "col2":"t_null1_e"} +4 {"pos":0, "col1":"t_not_null1_f", "col2":null} +5 {"pos":0, "col1":"t_not_null1_g", "col2":"t_null1_f"} +6 {"pos":0, "col1":"t_not_null1_h", "col2":null} + +-- !mixed_nullable_outer3 -- +1 0 t_not_null1_a t_null1_a +1 1 t_not_null1_b t_null1_b +2 0 t_not_null1_c t_null1_c +3 0 t_not_null1_d t_null1_d +3 1 t_not_null1_e t_null1_e +4 0 t_not_null1_f \N +5 0 t_not_null1_g t_null1_f +6 0 t_not_null1_h \N + +-- !fix_return_type -- +1 [1, 2, 3] [10.50, 20.00] {"pos":0, "col1":1, "col2":10.50} +1 [1, 2, 3] [10.50, 20.00] {"pos":1, "col1":2, "col2":20.00} +1 [1, 2, 3] [10.50, 20.00] {"pos":2, "col1":3, "col2":null} + diff --git a/regression-test/suites/nereids_p0/sql_functions/table_function/posexplode.groovy b/regression-test/suites/nereids_p0/sql_functions/table_function/posexplode.groovy index 3a7c69396fb535..b43bd6f2a3e33c 100644 --- a/regression-test/suites/nereids_p0/sql_functions/table_function/posexplode.groovy +++ b/regression-test/suites/nereids_p0/sql_functions/table_function/posexplode.groovy @@ -100,6 +100,7 @@ suite("posexplode") { (4, "lily", ["t1_d","t1_e"], null), (5, "alice", null, null); """ + order_qt_pos_exp_multi_args_all """ select * from test_posexplode_multi_args; """ @@ -132,4 +133,77 @@ suite("posexplode") { lateral view posexplode_outer(tags1, tags2) tmp as s2 where tags1 is not null and tags2 is not null order by 1,2; """ + + sql """ DROP TABLE IF EXISTS test_posexplode_mixed_nullable""" + sql """ + CREATE TABLE `test_posexplode_mixed_nullable`( + `id` INT NULL, + `tags_not_null1` array NOT NULL, + `tags_not_null2` array NOT NULL, + `tags_null1` array NULL, + `tags_null2` array NULL, + ) PROPERTIES ("replication_num" = "1"); + """ + sql """ + insert into test_posexplode_mixed_nullable values + (1, ["t_not_null1_a","t_not_null1_b"], ["t_not_null2_a","t_not_null2_b"], ["t_null1_a","t_null1_b"], ["t_null2_a","t_null2_b"]), + (2, ["t_not_null1_c"], ["t_not_null2_c","t_not_null2_d"], ["t_null1_c"], ["t_null2_c","t_null2_d"]), + (3, ["t_not_null1_d", "t_not_null1_e"], ["t_not_null2_e"], ["t_null1_d", "t_null1_e"], ["t_null2_e"]), + (4, ["t_not_null1_f"], ["t_not_null2_f"], null, ["t_null2_f"]), + (5, ["t_not_null1_g"], ["t_not_null2_g"], ["t_null1_f"], null), + (6, ["t_not_null1_h"], ["t_not_null2_h"], null, null); + """ + order_qt_mixed_nullable_all """ + select * from test_posexplode_mixed_nullable; + """ + order_qt_mixed_nullable_not_null0 """ + select id, st from test_posexplode_mixed_nullable lateral view posexplode(tags_not_null1) tmp as st order by 1, 2; + """ + order_qt_mixed_nullable_not_null1 """ + select id, pos, tmp0 from test_posexplode_mixed_nullable lateral view posexplode(tags_not_null1) tmp as pos, tmp0 order by 1, 2, 3; + """ + order_qt_mixed_nullable_not_null2 """ + select id, st from test_posexplode_mixed_nullable lateral view posexplode(tags_not_null1, tags_not_null2) tmp as st order by 1, 2; + """ + order_qt_mixed_nullable_not_null3 """ + select id, pos, tmp0, tmp1 from test_posexplode_mixed_nullable lateral view posexplode(tags_not_null1, tags_not_null2) tmp as pos, tmp0, tmp1 order by 1, 2, 3, 4; + """ + + order_qt_mixed_nullable_not_null_outer0 """ + select id, st from test_posexplode_mixed_nullable lateral view posexplode_outer(tags_not_null1) tmp as st order by 1, 2; + """ + order_qt_mixed_nullable_not_null_outer1 """ + select id, pos, tmp0 from test_posexplode_mixed_nullable lateral view posexplode_outer(tags_not_null1) tmp as pos, tmp0 order by 1, 2, 3; + """ + order_qt_mixed_nullable_not_null_outer2 """ + select id, st from test_posexplode_mixed_nullable lateral view posexplode_outer(tags_not_null1, tags_not_null2) tmp as st order by 1, 2; + """ + order_qt_mixed_nullable_not_null_outer3 """ + select id, pos, tmp0, tmp1 from test_posexplode_mixed_nullable lateral view posexplode_outer(tags_not_null1, tags_not_null2) tmp as pos, tmp0, tmp1 order by 1, 2, 3, 4; + """ + + order_qt_mixed_nullable2 """ + select id, st from test_posexplode_mixed_nullable lateral view posexplode(tags_not_null1, tags_null1) tmp as st order by 1, 2; + """ + order_qt_mixed_nullable3 """ + select id, pos, tmp0, tmp1 from test_posexplode_mixed_nullable lateral view posexplode(tags_not_null1, tags_null1) tmp as pos, tmp0, tmp1 order by 1, 2, 3, 4; + """ + + order_qt_mixed_nullable_outer2 """ + select id, st from test_posexplode_mixed_nullable lateral view posexplode_outer(tags_not_null1, tags_null1) tmp as st order by 1, 2; + """ + order_qt_mixed_nullable_outer3 """ + select id, pos, tmp0, tmp1 from test_posexplode_mixed_nullable lateral view posexplode_outer(tags_not_null1, tags_null1) tmp as pos, tmp0, tmp1 order by 1, 2, 3, 4; + """ + + qt_fix_return_type """ + SELECT + * + FROM ( + SELECT + 1 AS id, + ARRAY(1, 2, 3) AS arr_int, + ARRAY(CAST(10.5 AS DECIMAL(10,2)), CAST(20.0 AS DECIMAL(10,2))) AS arr_decimal + ) t lateral view posexplode(t.arr_int, t.arr_decimal) t2 AS v order by 1,2,3,4; + """ }