This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new 91635f0219b branch-4.0: [fix](posexplode) fix return type check
failure #59734 (#59996)
91635f0219b is described below
commit 91635f0219bac2bc351a75b1539fd185a4bbf86c
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sun Jan 18 18:17:56 2026 +0800
branch-4.0: [fix](posexplode) fix return type check failure #59734 (#59996)
Cherry-picked from #59734
Co-authored-by: TengJianPing <[email protected]>
---
be/src/vec/functions/function_fake.cpp | 15 ++-
.../functions/generator/PosExplode.java | 5 +-
.../sql_functions/table_function/posexplode.out | 137 +++++++++++++++++++++
.../sql_functions/table_function/posexplode.groovy | 74 +++++++++++
4 files changed, 223 insertions(+), 8 deletions(-)
diff --git a/be/src/vec/functions/function_fake.cpp
b/be/src/vec/functions/function_fake.cpp
index 350f6b4e95f..6997d9c9385 100644
--- a/be/src/vec/functions/function_fake.cpp
+++ b/be/src/vec/functions/function_fake.cpp
@@ -117,17 +117,20 @@ struct FunctionExplodeMap {
template <bool AlwaysNullable = false>
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<DataTypeInt32>();
- fieldTypes[1] =
-
check_and_get_data_type<DataTypeArray>(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<DataTypeArray>(arguments[i].get())->get_nested_type();
+ fieldTypes[i + 1] = make_nullable(nestedType);
+ }
auto struct_type =
std::make_shared<vectorized::DataTypeStruct>(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 b5091c09f1d..d9f984cf175 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 @@ package
org.apache.doris.nereids.trees.expressions.functions.generator;
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 @@ import java.util.List;
* 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 e21701f6bae..30593a55d3f 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 3a7c69396fb..b43bd6f2a3e 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<string> NOT NULL,
+ `tags_not_null2` array<string> NOT NULL,
+ `tags_null1` array<string> NULL,
+ `tags_null2` array<string> 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;
+ """
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]