This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 50123ad8a83 [opt](function) Enhance the handling of a single 
struct-type argument in the EXPLODE function (#57050)
50123ad8a83 is described below

commit 50123ad8a838e5ddbde8f77f674d3d172cbb73ec
Author: Jerry Hu <[email protected]>
AuthorDate: Fri Oct 17 12:06:32 2025 +0800

    [opt](function) Enhance the handling of a single struct-type argument in 
the EXPLODE function (#57050)
    
    ### What problem does this PR solve?
    
    Since the EXPLODE function supports multiple arguments, its return value
    is defined as a STRUCT type. Even when it has only a single argument, it
    still returns a STRUCT.
    Consider the following example:
    
    ```sql
    SELECT *
    FROM (SELECT 1) t1
    LATERAL VIEW explode(array(struct('a', 1), struct('b', 2))) t2 AS c1, c2;
    ```
    
    ```text
    +------+------------------------+
    | 1    | c1                     |
    +------+------------------------+
    |    1 | {"col1":"a", "col2":1} |
    |    1 | {"col1":"b", "col2":2} |
    +------+------------------------+
    ```
    
    In this SQL statement, the return value of the EXPLODE function is a
    nested STRUCT (that is, the child column inside the struct is struct
    too).
    As a result, the final output extracts the child column from the outer
    struct, but those child columns themselves are not correctly assigned to
    c1 and c2.
    
    With this PR, the result will be like this:
    ```text
    +------+------+------+
    | 1    | c1   | c2   |
    +------+------+------+
    |    1 | a    |    1 |
    |    1 | b    |    2 |
    +------+------+------+
    ```
    
    Related PR: #xxx
    
    Problem Summary:
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [ ] Regression test
        - [ ] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [ ] No need to test or manual test. Explain why:
    - [ ] This is a refactor/code format and no logic has been changed.
            - [ ] Previous test can cover this change.
            - [ ] No code files have been changed.
            - [ ] Other reason <!-- Add your reason?  -->
    
    - Behavior changed:
        - [ ] No.
        - [ ] Yes. <!-- Explain the behavior change -->
    
    - Does this need documentation?
        - [ ] No.
    - [ ] Yes. <!-- Add document PR link here. eg:
    https://github.com/apache/doris-website/pull/1214 -->
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
---
 be/src/vec/exprs/table_function/vexplode_v2.cpp    | 71 ++++++++++++++--------
 be/src/vec/functions/function_fake.cpp             |  6 +-
 be/test/vec/function/table_function_test.cpp       | 46 ++++++--------
 .../nereids/rules/analysis/BindExpression.java     | 22 ++++---
 .../expressions/functions/generator/Explode.java   |  7 ++-
 .../functions/generator/ExplodeOuter.java          |  7 ++-
 .../functions/generator/ExplodeVariantArray.java   |  7 ++-
 .../sql_functions/table_function/explode.out       | 16 +++++
 .../hive/test_parquet_nested_types.groovy          |  8 +--
 .../sql_functions/table_function/explode.groovy    | 22 +++++++
 10 files changed, 142 insertions(+), 70 deletions(-)

diff --git a/be/src/vec/exprs/table_function/vexplode_v2.cpp 
b/be/src/vec/exprs/table_function/vexplode_v2.cpp
index 47a4f41147b..dbeef4f438b 100644
--- a/be/src/vec/exprs/table_function/vexplode_v2.cpp
+++ b/be/src/vec/exprs/table_function/vexplode_v2.cpp
@@ -29,6 +29,7 @@
 #include "vec/columns/column_array.h"
 #include "vec/columns/column_nothing.h"
 #include "vec/columns/column_variant.h"
+#include "vec/common/assert_cast.h"
 #include "vec/core/block.h"
 #include "vec/core/column_with_type_and_name.h"
 #include "vec/data_types/data_type.h"
@@ -134,18 +135,28 @@ void 
VExplodeV2TableFunction::get_same_many_values(MutableColumnPtr& column, int
         return;
     }
     ColumnStruct* struct_column = nullptr;
-    if (_is_nullable) {
-        auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
-        struct_column = 
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
-        auto* nullmap_column =
-                
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
-        nullmap_column->insert_many_defaults(length);
+    std::vector<IColumn*> columns;
+
+    const bool multi_sub_columns = _multi_detail.size() > 1 || 
_generate_row_index;
+
+    if (multi_sub_columns) {
+        if (_is_nullable) {
+            auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
+            struct_column =
+                    
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
+            auto* nullmap_column =
+                    
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+            nullmap_column->insert_many_defaults(length);
+
+        } else {
+            struct_column = assert_cast<ColumnStruct*>(column.get());
+        }
+
+        for (size_t i = 0; i != _multi_detail.size(); ++i) {
+            columns.emplace_back(&struct_column->get_column(i + 
(_generate_row_index ? 1 : 0)));
+        }
     } else {
-        struct_column = assert_cast<ColumnStruct*>(column.get());
-    }
-    if (!struct_column) {
-        throw Exception(ErrorCode::INTERNAL_ERROR,
-                        "Only multiple columns can be returned within a 
struct.");
+        columns.push_back(column.get());
     }
 
     if (_generate_row_index) {
@@ -157,7 +168,7 @@ void 
VExplodeV2TableFunction::get_same_many_values(MutableColumnPtr& column, int
         auto& detail = _multi_detail[i];
         size_t pos = _array_offsets[i] + _cur_offset;
         size_t element_size = _multi_detail[i].array_col->size_at(_row_idx);
-        auto& struct_field = struct_column->get_column(i + 
(_generate_row_index ? 1 : 0));
+        auto& struct_field = *columns.at(i);
         if ((detail.array_nullmap_data && 
detail.array_nullmap_data[_row_idx])) {
             struct_field.insert_many_defaults(length);
         } else {
@@ -179,25 +190,33 @@ void 
VExplodeV2TableFunction::get_same_many_values(MutableColumnPtr& column, int
 
 int VExplodeV2TableFunction::get_value(MutableColumnPtr& column, int max_step) 
{
     max_step = std::min(max_step, (int)(_cur_size - _cur_offset));
+    const bool multi_sub_columns = _multi_detail.size() > 1 || 
_generate_row_index;
+
+    ColumnStruct* struct_column = nullptr;
+    std::vector<IColumn*> columns;
+
     if (current_empty()) {
         column->insert_default();
         max_step = 1;
     } else {
-        ColumnStruct* struct_column = nullptr;
-        if (_is_nullable) {
-            auto* nullable_column = assert_cast<ColumnNullable*>(column.get());
-            struct_column =
-                    
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
-            auto* nullmap_column =
-                    
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
-            nullmap_column->insert_many_defaults(max_step);
+        if (multi_sub_columns) {
+            if (_is_nullable) {
+                auto* nullable_column = 
assert_cast<ColumnNullable*>(column.get());
+                struct_column =
+                        
assert_cast<ColumnStruct*>(nullable_column->get_nested_column_ptr().get());
+                auto* nullmap_column =
+                        
assert_cast<ColumnUInt8*>(nullable_column->get_null_map_column_ptr().get());
+                nullmap_column->insert_many_defaults(max_step);
+
+            } else {
+                struct_column = assert_cast<ColumnStruct*>(column.get());
+            }
 
+            for (size_t i = 0; i != _multi_detail.size(); ++i) {
+                columns.emplace_back(&struct_column->get_column(i + 
(_generate_row_index ? 1 : 0)));
+            }
         } else {
-            struct_column = assert_cast<ColumnStruct*>(column.get());
-        }
-        if (!struct_column) {
-            throw Exception(ErrorCode::INTERNAL_ERROR,
-                            "Only multiple columns can be returned within a 
struct.");
+            columns.emplace_back(column.get());
         }
 
         if (_generate_row_index) {
@@ -210,7 +229,7 @@ int VExplodeV2TableFunction::get_value(MutableColumnPtr& 
column, int max_step) {
             auto& detail = _multi_detail[i];
             size_t pos = _array_offsets[i] + _cur_offset;
             size_t element_size = 
_multi_detail[i].array_col->size_at(_row_idx);
-            auto& struct_field = struct_column->get_column(i + 
(_generate_row_index ? 1 : 0));
+            auto& struct_field = *columns.at(i);
             if (detail.array_nullmap_data && 
detail.array_nullmap_data[_row_idx]) {
                 struct_field.insert_many_defaults(max_step);
             } else {
diff --git a/be/src/vec/functions/function_fake.cpp 
b/be/src/vec/functions/function_fake.cpp
index db20245683f..350f6b4e95f 100644
--- a/be/src/vec/functions/function_fake.cpp
+++ b/be/src/vec/functions/function_fake.cpp
@@ -90,7 +90,11 @@ struct FunctionExplodeV2 {
             }
         }
 
-        return 
make_nullable(std::make_shared<vectorized::DataTypeStruct>(fieldTypes));
+        if (fieldTypes.size() > 1) {
+            return 
make_nullable(std::make_shared<vectorized::DataTypeStruct>(fieldTypes));
+        } else {
+            return make_nullable(fieldTypes[0]);
+        }
     }
     static DataTypes get_variadic_argument_types() { return {}; }
     static std::string get_error_msg() { return "Fake function do not support 
execute"; }
diff --git a/be/test/vec/function/table_function_test.cpp 
b/be/test/vec/function/table_function_test.cpp
index fb25913e304..7ef2e9f56af 100644
--- a/be/test/vec/function/table_function_test.cpp
+++ b/be/test/vec/function/table_function_test.cpp
@@ -132,11 +132,10 @@ TEST_F(TableFunctionTest, vexplode_outer_v2) {
         TestArray vec = {Int32(1), Null(), Int32(2), Int32(3)};
         InputDataSet input_set = {{AnyType {vec}}, {Null()}, {AnyType 
{TestArray {}}}};
 
-        InputTypeSet output_types = {PrimitiveType::TYPE_STRUCT, 
PrimitiveType::TYPE_INT};
+        InputTypeSet output_types = {PrimitiveType::TYPE_INT};
 
-        InputDataSet output_set = {{{TestArray {Int32(1)}}}, {{TestArray 
{Null()}}},
-                                   {{TestArray {Int32(2)}}}, {{TestArray 
{Int32(3)}}},
-                                   {{TestArray {Null()}}},   {{TestArray 
{Null()}}}};
+        InputDataSet output_set = {{Int32(1)}, {Null()}, {Int32(2)},
+                                   {Int32(3)}, {Null()}, {Null()}};
 
         check_vec_table_function(&explode_outer, input_types, input_set, 
output_types, output_set);
     }
@@ -147,29 +146,26 @@ TEST_F(TableFunctionTest, vexplode_outer_v2) {
         TestArray vec = {std::string("abc"), std::string(""), 
std::string("def")};
         InputDataSet input_set = {{Null()}, {AnyType {TestArray {}}}, {AnyType 
{vec}}};
 
-        InputTypeSet output_types = {PrimitiveType::TYPE_STRUCT, 
PrimitiveType::TYPE_VARCHAR};
+        InputTypeSet output_types = {PrimitiveType::TYPE_VARCHAR};
 
-        InputDataSet output_set = {{{TestArray {Null()}}},
-                                   {{TestArray {Null()}}},
-                                   {{TestArray {std::string("abc")}}},
-                                   {{TestArray {std::string("")}}},
-                                   {{TestArray {std::string("def")}}}};
+        InputDataSet output_set = {
+                {Null()}, {Null()}, {std::string("abc")}, {std::string("")}, 
{std::string("def")}};
 
         check_vec_table_function(&explode_outer, input_types, input_set, 
output_types, output_set);
     }
 
-    // explode_outer(Array<Decimal>)
+    // // explode_outer(Array<Decimal>)
     {
         InputTypeSet input_types = {PrimitiveType::TYPE_ARRAY, 
PrimitiveType::TYPE_DECIMALV2};
         TestArray vec = {ut_type::DECIMALV2(17014116.67), 
ut_type::DECIMALV2(-17014116.67)};
         InputDataSet input_set = {{Null()}, {AnyType {TestArray {}}}, {AnyType 
{vec}}};
 
-        InputTypeSet output_types = {PrimitiveType::TYPE_STRUCT, 
PrimitiveType::TYPE_DECIMALV2};
+        InputTypeSet output_types = {PrimitiveType::TYPE_DECIMALV2};
 
-        InputDataSet output_set = {{{TestArray {Null()}}},
-                                   {{TestArray {Null()}}},
-                                   {{TestArray 
{ut_type::DECIMALV2(17014116.67)}}},
-                                   {{TestArray 
{ut_type::DECIMALV2(-17014116.67)}}}};
+        InputDataSet output_set = {{Null()},
+                                   {Null()},
+                                   {ut_type::DECIMALV2(17014116.67)},
+                                   {ut_type::DECIMALV2(-17014116.67)}};
 
         check_vec_table_function(&explode_outer, input_types, input_set, 
output_types, output_set);
     }
@@ -230,11 +226,8 @@ TEST_F(TableFunctionTest, vexplode_v2) {
         TestArray vec = {Int32(1), Null(), Int32(2), Int32(3)};
         InputDataSet input_set = {{AnyType {vec}}, {Null()}, {AnyType 
{TestArray {}}}};
 
-        InputTypeSet output_types = {PrimitiveType::TYPE_STRUCT, 
PrimitiveType::TYPE_INT};
-        InputDataSet output_set = {{{TestArray {Int32(1)}}},
-                                   {{TestArray {Null()}}},
-                                   {{TestArray {Int32(2)}}},
-                                   {{TestArray {Int32(3)}}}};
+        InputTypeSet output_types = {PrimitiveType::TYPE_INT};
+        InputDataSet output_set = {{Int32(1)}, {Null()}, {Int32(2)}, 
{Int32(3)}};
 
         check_vec_table_function(&explode, input_types, input_set, 
output_types, output_set);
     }
@@ -245,11 +238,9 @@ TEST_F(TableFunctionTest, vexplode_v2) {
         TestArray vec = {std::string("abc"), std::string(""), 
std::string("def")};
         InputDataSet input_set = {{Null()}, {AnyType {TestArray {}}}, {AnyType 
{vec}}};
 
-        InputTypeSet output_types = {PrimitiveType::TYPE_STRUCT, 
PrimitiveType::TYPE_VARCHAR};
+        InputTypeSet output_types = {PrimitiveType::TYPE_VARCHAR};
 
-        InputDataSet output_set = {{{TestArray {std::string("abc")}}},
-                                   {{TestArray {std::string("")}}},
-                                   {{TestArray {std::string("def")}}}};
+        InputDataSet output_set = {{std::string("abc")}, {std::string("")}, 
{std::string("def")}};
         check_vec_table_function(&explode, input_types, input_set, 
output_types, output_set);
     }
 
@@ -259,10 +250,9 @@ TEST_F(TableFunctionTest, vexplode_v2) {
         TestArray vec = {Null(), std::string("2022-01-02")};
         InputDataSet input_set = {{Null()}, {AnyType {TestArray {}}}, {AnyType 
{vec}}};
 
-        InputTypeSet output_types = {PrimitiveType::TYPE_STRUCT, 
PrimitiveType::TYPE_DATE};
+        InputTypeSet output_types = {PrimitiveType::TYPE_DATE};
 
-        InputDataSet output_set = {{{TestArray {Null()}}},
-                                   {{TestArray {std::string("2022-01-02")}}}};
+        InputDataSet output_set = {{Null()}, {std::string("2022-01-02")}};
         check_vec_table_function(&explode, input_types, input_set, 
output_types, output_set);
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
index 20d8e981af1..b41968450ec 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
@@ -294,14 +294,20 @@ public class BindExpression implements 
AnalysisRuleFactory {
             // 2. the expandColumnsAlias is empty, we should use origin 
boundSlot
             if (generate.getExpandColumnAlias() != null && i < 
generate.getExpandColumnAlias().size()
                     && 
!CollectionUtils.isEmpty(generate.getExpandColumnAlias().get(i))) {
-                // if the alias is not empty, we should bind it with 
struct_element as child expr with alias
-                // struct_element(#expand_col#k, #k) as #k
-                // struct_element(#expand_col#v, #v) as #v
-                List<StructField> fields = ((StructType) 
boundSlot.getDataType()).getFields();
-                for (int idx = 0; idx < fields.size(); ++idx) {
-                    expandAlias.add(new Alias(new StructElement(
-                            boundSlot, new 
StringLiteral(fields.get(idx).getName())),
-                            generate.getExpandColumnAlias().get(i).get(idx),
+                if (boundSlot.getDataType() instanceof StructType
+                        && generate.getExpandColumnAlias().get(i).size() > 1) {
+                    // if the alias is not empty, we should bind it with 
struct_element as child expr with alias
+                    // struct_element(#expand_col#k, #k) as #k
+                    // struct_element(#expand_col#v, #v) as #v
+                    List<StructField> fields = ((StructType) 
boundSlot.getDataType()).getFields();
+                    for (int idx = 0; idx < fields.size(); ++idx) {
+                        expandAlias.add(new Alias(new StructElement(
+                                boundSlot, new 
StringLiteral(fields.get(idx).getName())),
+                                
generate.getExpandColumnAlias().get(i).get(idx),
+                                slot.getQualifier()));
+                    }
+                } else {
+                    expandAlias.add(new Alias(boundSlot, 
generate.getExpandColumnAlias().get(i).get(0),
                             slot.getQualifier()));
                 }
             }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/Explode.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/Explode.java
index 472e6d7461b..c8e23b2a0b7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/Explode.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/Explode.java
@@ -87,7 +87,12 @@ public class Explode extends TableGeneratingFunction 
implements CustomSignature,
                 
SearchSignature.throwCanNotFoundFunctionException(this.getName(), 
getArguments());
             }
         }
-        return FunctionSignature.of(new StructType(structFields.build()), 
arguments);
+
+        StructType structType = new StructType(structFields.build());
+        if (arguments.size() == 1) {
+            return 
FunctionSignature.of(structType.getFields().get(0).getDataType(), arguments);
+        }
+        return FunctionSignature.of(structType, arguments);
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuter.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuter.java
index 15b2772e128..4a26ea14fb6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuter.java
@@ -87,7 +87,12 @@ public class ExplodeOuter extends TableGeneratingFunction 
implements CustomSigna
                 
SearchSignature.throwCanNotFoundFunctionException(this.getName(), 
getArguments());
             }
         }
-        return FunctionSignature.of(new StructType(structFields.build()), 
arguments);
+
+        StructType structType = new StructType(structFields.build());
+        if (arguments.size() == 1) {
+            return 
FunctionSignature.of(structType.getFields().get(0).getDataType(), arguments);
+        }
+        return FunctionSignature.of(structType, arguments);
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeVariantArray.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeVariantArray.java
index 5ba897c3c33..8b0d29683af 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeVariantArray.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeVariantArray.java
@@ -82,7 +82,12 @@ public class ExplodeVariantArray extends 
TableGeneratingFunction implements
                 
SearchSignature.throwCanNotFoundFunctionException(this.getName(), 
getArguments());
             }
         }
-        return FunctionSignature.of(new StructType(structFields.build()), 
arguments);
+
+        StructType structType = new StructType(structFields.build());
+        if (arguments.size() == 1) {
+            return 
FunctionSignature.of(structType.getFields().get(0).getDataType(), arguments);
+        }
+        return FunctionSignature.of(structType, arguments);
     }
 
     @Override
diff --git 
a/regression-test/data/query_p0/sql_functions/table_function/explode.out 
b/regression-test/data/query_p0/sql_functions/table_function/explode.out
index 1a6280bb84f..377a757a429 100644
--- a/regression-test/data/query_p0/sql_functions/table_function/explode.out
+++ b/regression-test/data/query_p0/sql_functions/table_function/explode.out
@@ -747,3 +747,19 @@ j  \N      2       cd      \N
 j      \N      4       \N      2
 j      \N      5       \N      3
 
+-- !select25 --
+1      {"col1":1, "col2":"a"}
+1      {"col1":2, "col2":"b"}
+
+-- !select26 --
+1      1       a
+1      2       b
+
+-- !select27 --
+1      {"col1":{"col1":1, "col2":"a"}, "col2":{"col1":3, "col2":"c"}}
+1      {"col1":{"col1":2, "col2":"b"}, "col2":{"col1":4, "col2":"d"}}
+
+-- !select28 --
+1      {"col1":1, "col2":"a"}  {"col1":3, "col2":"c"}
+1      {"col1":2, "col2":"b"}  {"col1":4, "col2":"d"}
+
diff --git 
a/regression-test/suites/external_table_p0/hive/test_parquet_nested_types.groovy
 
b/regression-test/suites/external_table_p0/hive/test_parquet_nested_types.groovy
index 034559aaa78..d94f909142e 100644
--- 
a/regression-test/suites/external_table_p0/hive/test_parquet_nested_types.groovy
+++ 
b/regression-test/suites/external_table_p0/hive/test_parquet_nested_types.groovy
@@ -132,11 +132,11 @@ suite("test_parquet_nested_types", 
"p0,external,hive,external_docker,external_do
         order_qt_nested_cross_page2_parquet_q5 """
             SELECT
                 id,
-                STRUCT_ELEMENT(item, 'x'),
-                STRUCT_ELEMENT(item, 'y')
+                item_x as x_value,
+                item_y as y_value
             FROM nested_cross_page2_parquet
-            LATERAL VIEW EXPLODE(array_struct_col) tmp AS item
-            WHERE id = 1 AND STRUCT_ELEMENT(item, 'x') > 100
+            LATERAL VIEW EXPLODE(array_struct_col) tmp AS item_x, item_y
+            WHERE id = 1 AND item_x > 100
         """
 
         order_qt_nested_cross_page2_parquet_q6 """
diff --git 
a/regression-test/suites/query_p0/sql_functions/table_function/explode.groovy 
b/regression-test/suites/query_p0/sql_functions/table_function/explode.groovy
index fb1a9e29e09..51b8dcf4ec6 100644
--- 
a/regression-test/suites/query_p0/sql_functions/table_function/explode.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/table_function/explode.groovy
@@ -213,4 +213,26 @@ suite("explode") {
         lateral view explode([], [1, 2, null, 4, 5], ["ab", "cd", "ef"], 
[null, null, 1, 2, 3, 4, 5]) t2 as c0, c1, c2, c3 
         order by 1,2,3,4,5;
     """
+
+    qt_select25 """
+        select * from (select 1) t1 lateral view explode(array(struct(1, "a"), 
struct(2, "b"))) t2 as c1 order by 1,2;
+    """
+    qt_select26 """
+        select * from (select 1) t1 lateral view explode(array(struct(1, "a"), 
struct(2, "b"))) t2 as c1, c2 order by 1,2,3;
+    """
+
+    qt_select27 """
+        select * from (select 1) t1 
+            lateral view explode(
+                array(struct(1, "a"), struct(2, "b")),
+                array(struct(3, "c"), struct(4, "d"))
+            ) t2 as c1 order by 1,2;
+    """
+    qt_select28 """
+        select * from (select 1) t1 
+            lateral view explode(
+                array(struct(1, "a"), struct(2, "b")),
+                array(struct(3, "c"), struct(4, "d"))
+            ) t2 as c1, c2 order by 1,2;
+    """
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to