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]

Reply via email to