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

eldenmoon pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new 4cf769b39fb [Improve](table-function) explode json array with json 
args  (#39491)
4cf769b39fb is described below

commit 4cf769b39fb60e77630bd3a2d2c8b1309b000e2e
Author: amory <wangqian...@selectdb.com>
AuthorDate: Tue Aug 27 14:53:17 2024 +0800

    [Improve](table-function) explode json array with json args  (#39491)
---
 .../exprs/table_function/vexplode_json_array.cpp   |  24 +++-
 .../vec/exprs/table_function/vexplode_json_array.h | 151 +++++++++++++++++++++
 be/src/vec/functions/function_fake.cpp             |  52 ++++---
 be/src/vec/functions/function_fake.h               |   5 +
 .../generator/ExplodeJsonArrayDouble.java          |   2 +
 .../generator/ExplodeJsonArrayDoubleOuter.java     |   2 +
 .../functions/generator/ExplodeJsonArrayInt.java   |   2 +
 .../generator/ExplodeJsonArrayIntOuter.java        |   2 +
 .../functions/generator/ExplodeJsonArrayJson.java  |   2 +
 .../generator/ExplodeJsonArrayJsonOuter.java       |   2 +
 .../generator/ExplodeJsonArrayString.java          |   2 +
 .../generator/ExplodeJsonArrayStringOuter.java     |   2 +
 .../data/nereids_function_p0/gen_function/gen.out  |  41 ++++++
 .../table_function/explode_json_array.out          |  16 ++-
 .../nereids_function_p0/gen_function/gen.groovy    |   3 +
 .../table_function/explode_json_array.groovy       |   6 +-
 16 files changed, 291 insertions(+), 23 deletions(-)

diff --git a/be/src/vec/exprs/table_function/vexplode_json_array.cpp 
b/be/src/vec/exprs/table_function/vexplode_json_array.cpp
index 00c4d92a359..3c22ef4e078 100644
--- a/be/src/vec/exprs/table_function/vexplode_json_array.cpp
+++ b/be/src/vec/exprs/table_function/vexplode_json_array.cpp
@@ -26,6 +26,8 @@
 #include <limits>
 
 #include "common/status.h"
+#include "util/jsonb_parser.h"
+#include "util/jsonb_utils.h"
 #include "vec/columns/column.h"
 #include "vec/columns/column_nullable.h"
 #include "vec/columns/columns_number.h"
@@ -50,6 +52,7 @@ Status 
VExplodeJsonArrayTableFunction<DataImpl>::process_init(Block* block, Runt
     
RETURN_IF_ERROR(_expr_context->root()->children()[0]->execute(_expr_context.get(),
 block,
                                                                   
&text_column_idx));
     _text_column = block->get_by_position(text_column_idx).column;
+    _text_datatype = 
remove_nullable(block->get_by_position(text_column_idx).type);
     return Status::OK();
 }
 
@@ -59,10 +62,20 @@ void 
VExplodeJsonArrayTableFunction<DataImpl>::process_row(size_t row_idx) {
 
     StringRef text = _text_column->get_data_at(row_idx);
     if (text.data != nullptr) {
-        rapidjson::Document document;
-        document.Parse(text.data, text.size);
-        if (!document.HasParseError() && document.IsArray() && 
document.GetArray().Size()) {
-            _cur_size = _parsed_data.set_output(document, 
document.GetArray().Size());
+        if (WhichDataType(_text_datatype).is_json()) {
+            JsonbDocument* doc = JsonbDocument::createDocument(text.data, 
text.size);
+            if (doc && doc->getValue() && doc->getValue()->isArray()) {
+                auto* a = (ArrayVal*)doc->getValue();
+                if (a->numElem() > 0) {
+                    _cur_size = _parsed_data.set_output(*a, a->numElem());
+                }
+            }
+        } else {
+            rapidjson::Document document;
+            document.Parse(text.data, text.size);
+            if (!document.HasParseError() && document.IsArray() && 
document.GetArray().Size()) {
+                _cur_size = _parsed_data.set_output(document, 
document.GetArray().Size());
+            }
         }
     }
 }
@@ -70,6 +83,7 @@ void 
VExplodeJsonArrayTableFunction<DataImpl>::process_row(size_t row_idx) {
 template <typename DataImpl>
 void VExplodeJsonArrayTableFunction<DataImpl>::process_close() {
     _text_column = nullptr;
+    _text_datatype = nullptr;
     _parsed_data.reset();
 }
 
@@ -141,4 +155,4 @@ template class 
VExplodeJsonArrayTableFunction<ParsedDataDouble>;
 template class VExplodeJsonArrayTableFunction<ParsedDataString>;
 template class VExplodeJsonArrayTableFunction<ParsedDataJSON>;
 
-} // namespace doris::vectorized
\ No newline at end of file
+} // namespace doris::vectorized
diff --git a/be/src/vec/exprs/table_function/vexplode_json_array.h 
b/be/src/vec/exprs/table_function/vexplode_json_array.h
index 1d89d9fa57d..acf31ed40d9 100644
--- a/be/src/vec/exprs/table_function/vexplode_json_array.h
+++ b/be/src/vec/exprs/table_function/vexplode_json_array.h
@@ -32,6 +32,7 @@
 #include "vec/core/types.h"
 #include "vec/data_types/data_type.h"
 #include "vec/exprs/table_function/table_function.h"
+#include "vec/functions/function_string.h"
 
 namespace doris::vectorized {
 
@@ -44,6 +45,7 @@ struct ParsedData {
         _values_null_flag.clear();
     }
     virtual int set_output(rapidjson::Document& document, int value_size) = 0;
+    virtual int set_output(ArrayVal& array_doc, int value_size) = 0;
     virtual void insert_result_from_parsed_data(MutableColumnPtr& column, 
int64_t cur_offset,
                                                 int max_step) = 0;
     virtual void insert_many_same_value_from_parsed_data(MutableColumnPtr& 
column,
@@ -90,6 +92,36 @@ struct ParsedDataInt : public ParsedData<int64_t> {
         }
         return value_size;
     }
+    int set_output(ArrayVal& array_doc, int value_size) override {
+        _values_null_flag.resize(value_size, 0);
+        _backup_data.resize(value_size);
+        int i = 0;
+        for (auto& val : array_doc) {
+            if (val.isInt8()) {
+                _backup_data[i] = static_cast<const JsonbInt8Val&>(val).val();
+            } else if (val.isInt16()) {
+                _backup_data[i] = static_cast<const JsonbInt16Val&>(val).val();
+            } else if (val.isInt32()) {
+                _backup_data[i] = static_cast<const JsonbInt32Val&>(val).val();
+            } else if (val.isInt64()) {
+                _backup_data[i] = static_cast<const JsonbInt64Val&>(val).val();
+            } else if (val.isDouble()) {
+                auto value = static_cast<const JsonbDoubleVal&>(val).val();
+                if (value > MAX_VALUE) {
+                    _backup_data[i] = MAX_VALUE;
+                } else if (value < MIN_VALUE) {
+                    _backup_data[i] = MIN_VALUE;
+                } else {
+                    _backup_data[i] = long(value);
+                }
+            } else {
+                _values_null_flag[i] = 1;
+                _backup_data[i] = 0;
+            }
+            ++i;
+        }
+        return value_size;
+    }
 
     void insert_result_from_parsed_data(MutableColumnPtr& column, int64_t 
cur_offset,
                                         int max_step) override {
@@ -121,6 +153,22 @@ struct ParsedDataDouble : public ParsedData<double> {
         return value_size;
     }
 
+    int set_output(ArrayVal& array_doc, int value_size) override {
+        _values_null_flag.resize(value_size, 0);
+        _backup_data.resize(value_size);
+        int i = 0;
+        for (auto& val : array_doc) {
+            if (val.isDouble()) {
+                _backup_data[i] = static_cast<const 
JsonbDoubleVal&>(val).val();
+            } else {
+                _backup_data[i] = 0;
+                _values_null_flag[i] = 1;
+            }
+            ++i;
+        }
+        return value_size;
+    }
+
     void insert_result_from_parsed_data(MutableColumnPtr& column, int64_t 
cur_offset,
                                         int max_step) override {
         assert_cast<ColumnFloat64*>(column.get())
@@ -220,6 +268,83 @@ struct ParsedDataString : public ParsedDataStringBase {
         }
         return value_size;
     }
+
+    int set_output(ArrayVal& array_doc, int value_size) override {
+        _data_string_ref.clear();
+        _backup_data.clear();
+        _values_null_flag.clear();
+        int32_t wbytes = 0;
+        for (auto& val : array_doc) {
+            switch (val.type()) {
+            case JsonbType::T_String: {
+                _backup_data.emplace_back(static_cast<const 
JsonbStringVal&>(val).getBlob(),
+                                          static_cast<const 
JsonbStringVal&>(val).getBlobLen());
+                _values_null_flag.emplace_back(false);
+                break;
+                // do not set _data_string here.
+                // Because the address of the string stored in `_backup_data` 
may
+                // change each time `emplace_back()` is called.
+            }
+            case JsonbType::T_Int8: {
+                wbytes = snprintf(tmp_buf, sizeof(tmp_buf), "%d",
+                                  static_cast<const JsonbInt8Val&>(val).val());
+                _backup_data.emplace_back(tmp_buf, wbytes);
+                _values_null_flag.emplace_back(false);
+                break;
+            }
+            case JsonbType::T_Int16: {
+                wbytes = snprintf(tmp_buf, sizeof(tmp_buf), "%d",
+                                  static_cast<const 
JsonbInt16Val&>(val).val());
+                _backup_data.emplace_back(tmp_buf, wbytes);
+                _values_null_flag.emplace_back(false);
+                break;
+            }
+            case JsonbType::T_Int64: {
+                wbytes = snprintf(tmp_buf, sizeof(tmp_buf), "%" PRId64,
+                                  static_cast<const 
JsonbInt64Val&>(val).val());
+                _backup_data.emplace_back(tmp_buf, wbytes);
+                _values_null_flag.emplace_back(false);
+                break;
+            }
+            case JsonbType::T_Double: {
+                wbytes = snprintf(tmp_buf, sizeof(tmp_buf), "%f",
+                                  static_cast<const 
JsonbDoubleVal&>(val).val());
+                _backup_data.emplace_back(tmp_buf, wbytes);
+                _values_null_flag.emplace_back(false);
+                break;
+            }
+            case JsonbType::T_Int32: {
+                wbytes = snprintf(tmp_buf, sizeof(tmp_buf), "%d",
+                                  static_cast<const 
JsonbInt32Val&>(val).val());
+                _backup_data.emplace_back(tmp_buf, wbytes);
+                _values_null_flag.emplace_back(false);
+                break;
+            }
+            case JsonbType::T_True:
+                _backup_data.emplace_back(TRUE_VALUE);
+                _values_null_flag.emplace_back(false);
+                break;
+            case JsonbType::T_False:
+                _backup_data.emplace_back(FALSE_VALUE);
+                _values_null_flag.emplace_back(false);
+                break;
+            case JsonbType::T_Null:
+                _backup_data.emplace_back();
+                _values_null_flag.emplace_back(true);
+                break;
+            default:
+                _backup_data.emplace_back();
+                _values_null_flag.emplace_back(true);
+                break;
+            }
+        }
+        // Must set _data_string at the end, so that we can
+        // save the real addr of string in `_backup_data` to `_data_string`.
+        for (auto& str : _backup_data) {
+            _data_string_ref.emplace_back(str.data(), str.length());
+        }
+        return value_size;
+    }
 };
 
 struct ParsedDataJSON : public ParsedDataStringBase {
@@ -246,6 +371,31 @@ struct ParsedDataJSON : public ParsedDataStringBase {
         }
         return value_size;
     }
+
+    int set_output(ArrayVal& array_doc, int value_size) override {
+        _data_string_ref.clear();
+        _backup_data.clear();
+        _values_null_flag.clear();
+        auto writer = std::make_unique<JsonbWriter>();
+        for (auto& v : array_doc) {
+            if (v.isObject()) {
+                writer->reset();
+                writer->writeValue(&v);
+                _backup_data.emplace_back(writer->getOutput()->getBuffer(),
+                                          writer->getOutput()->getSize());
+                _values_null_flag.emplace_back(false);
+            } else {
+                _backup_data.emplace_back();
+                _values_null_flag.emplace_back(true);
+            }
+        }
+        // Must set _data_string at the end, so that we can
+        // save the real addr of string in `_backup_data` to `_data_string`.
+        for (auto& str : _backup_data) {
+            _data_string_ref.emplace_back(str);
+        }
+        return value_size;
+    }
 };
 
 template <typename DataImpl>
@@ -267,6 +417,7 @@ private:
     void _insert_values_into_column(MutableColumnPtr& column, int max_step);
     DataImpl _parsed_data;
     ColumnPtr _text_column;
+    DataTypePtr _text_datatype;
 };
 
 } // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_fake.cpp 
b/be/src/vec/functions/function_fake.cpp
index 0353b3a2a7c..c7edcf4df8f 100644
--- a/be/src/vec/functions/function_fake.cpp
+++ b/be/src/vec/functions/function_fake.cpp
@@ -38,7 +38,7 @@
 
 namespace doris::vectorized {
 
-template <typename ReturnType, bool AlwaysNullable = false>
+template <typename ReturnType, bool AlwaysNullable = false, bool VARIADIC = 
false>
 struct FunctionFakeBaseImpl {
     static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
         if constexpr (AlwaysNullable) {
@@ -46,6 +46,16 @@ struct FunctionFakeBaseImpl {
         }
         return std::make_shared<ReturnType>();
     }
+    static DataTypes get_variadic_argument_types() {
+        if constexpr (VARIADIC) {
+            if constexpr (AlwaysNullable) {
+                return {make_nullable(std::make_shared<ReturnType>())};
+            }
+            return {std::make_shared<ReturnType>()};
+        } else {
+            return {};
+        }
+    }
     static std::string get_error_msg() { return "Fake function do not support 
execute"; }
 };
 
@@ -55,6 +65,7 @@ struct FunctionExplode {
         return make_nullable(
                 
check_and_get_data_type<DataTypeArray>(arguments[0].get())->get_nested_type());
     }
+    static DataTypes get_variadic_argument_types() { return {}; }
     static std::string get_error_msg() { return "Fake function do not support 
execute"; }
 };
 
@@ -67,6 +78,7 @@ struct FunctionExplodeMap {
         fieldTypes[1] = 
check_and_get_data_type<DataTypeMap>(arguments[0].get())->get_value_type();
         return 
make_nullable(std::make_shared<vectorized::DataTypeStruct>(fieldTypes));
     }
+    static DataTypes get_variadic_argument_types() { return {}; }
     static std::string get_error_msg() { return "Fake function do not support 
execute"; }
 };
 
@@ -80,6 +92,7 @@ struct FunctionExplodeJsonObject {
         fieldTypes[1] = make_nullable(std::make_shared<DataTypeJsonb>());
         return 
make_nullable(std::make_shared<vectorized::DataTypeStruct>(fieldTypes));
     }
+    static DataTypes get_variadic_argument_types() { return {}; }
     static std::string get_error_msg() { return "Fake function do not support 
execute"; }
 };
 
@@ -87,6 +100,7 @@ struct FunctionEsquery {
     static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
         return 
FunctionFakeBaseImpl<DataTypeUInt8>::get_return_type_impl(arguments);
     }
+    static DataTypes get_variadic_argument_types() { return {}; }
     static std::string get_error_msg() { return "esquery only supported on es 
table"; }
 };
 
@@ -102,11 +116,13 @@ void 
register_table_function_expand(SimpleFunctionFactory& factory, const std::s
     factory.register_function<FunctionFake<FunctionImpl>>(name + suffix);
 };
 
-template <typename ReturnType>
+template <typename ReturnType, bool VARIADIC>
 void register_table_function_expand_default(SimpleFunctionFactory& factory, 
const std::string& name,
                                             const std::string& suffix) {
-    
factory.register_function<FunctionFake<FunctionFakeBaseImpl<ReturnType>>>(name);
-    factory.register_function<FunctionFake<FunctionFakeBaseImpl<ReturnType, 
true>>>(name + suffix);
+    factory.register_function<FunctionFake<FunctionFakeBaseImpl<ReturnType, 
false, VARIADIC>>>(
+            name);
+    factory.register_function<FunctionFake<FunctionFakeBaseImpl<ReturnType, 
true, VARIADIC>>>(
+            name + suffix);
 };
 
 template <typename FunctionImpl>
@@ -114,10 +130,11 @@ void 
register_table_function_expand_outer(SimpleFunctionFactory& factory, const
     register_table_function_expand<FunctionImpl>(factory, name, 
COMBINATOR_SUFFIX_OUTER);
 };
 
-template <typename ReturnType>
+template <typename ReturnType, bool VARIADIC>
 void register_table_function_expand_outer_default(SimpleFunctionFactory& 
factory,
                                                   const std::string& name) {
-    register_table_function_expand_default<ReturnType>(factory, name, 
COMBINATOR_SUFFIX_OUTER);
+    register_table_function_expand_default<ReturnType, VARIADIC>(factory, name,
+                                                                 
COMBINATOR_SUFFIX_OUTER);
 };
 
 void register_function_fake(SimpleFunctionFactory& factory) {
@@ -127,16 +144,19 @@ void register_function_fake(SimpleFunctionFactory& 
factory) {
     register_table_function_expand_outer<FunctionExplodeMap>(factory, 
"explode_map");
 
     register_table_function_expand_outer<FunctionExplodeJsonObject>(factory, 
"explode_json_object");
-    register_table_function_expand_outer_default<DataTypeString>(factory, 
"explode_split");
-    register_table_function_expand_outer_default<DataTypeInt32>(factory, 
"explode_numbers");
-    register_table_function_expand_outer_default<DataTypeInt64>(factory, 
"explode_json_array_int");
-    register_table_function_expand_outer_default<DataTypeString>(factory,
-                                                                 
"explode_json_array_string");
-    register_table_function_expand_outer_default<DataTypeString>(factory,
-                                                                 
"explode_json_array_json");
-    register_table_function_expand_outer_default<DataTypeFloat64>(factory,
-                                                                  
"explode_json_array_double");
-    register_table_function_expand_outer_default<DataTypeInt64>(factory, 
"explode_bitmap");
+    register_table_function_expand_outer_default<DataTypeString, 
false>(factory, "explode_split");
+    register_table_function_expand_outer_default<DataTypeInt32, 
false>(factory, "explode_numbers");
+    register_table_function_expand_outer_default<DataTypeInt64, false>(factory,
+                                                                       
"explode_json_array_int");
+    register_table_function_expand_outer_default<DataTypeString, false>(
+            factory, "explode_json_array_string");
+    register_table_function_expand_outer_default<DataTypeJsonb, true>(factory,
+                                                                      
"explode_json_array_json");
+    register_table_function_expand_outer_default<DataTypeString, true>(factory,
+                                                                       
"explode_json_array_json");
+    register_table_function_expand_outer_default<DataTypeFloat64, false>(
+            factory, "explode_json_array_double");
+    register_table_function_expand_outer_default<DataTypeInt64, 
false>(factory, "explode_bitmap");
 }
 
 } // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_fake.h 
b/be/src/vec/functions/function_fake.h
index 0dabdfb3c83..dfbfce2127d 100644
--- a/be/src/vec/functions/function_fake.h
+++ b/be/src/vec/functions/function_fake.h
@@ -35,6 +35,7 @@ class Block;
 } // namespace doris
 
 namespace doris::vectorized {
+
 // FunctionFake is use for some function call expr only work at prepare/open 
phase, do not support execute().
 template <typename Impl>
 class FunctionFake : public IFunction {
@@ -55,6 +56,10 @@ public:
 
     bool use_default_implementation_for_nulls() const override { return true; }
 
+    DataTypes get_variadic_argument_types_impl() const override {
+        return Impl::get_variadic_argument_types();
+    }
+
     bool use_default_implementation_for_constants() const override { return 
false; }
 
     Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDouble.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDouble.java
index e6072931325..c24477c20d1 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDouble.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDouble.java
@@ -23,6 +23,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.DoubleType;
+import org.apache.doris.nereids.types.JsonType;
 import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
@@ -36,6 +37,7 @@ import java.util.List;
 public class ExplodeJsonArrayDouble extends TableGeneratingFunction implements 
UnaryExpression, PropagateNullable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            FunctionSignature.ret(DoubleType.INSTANCE).args(JsonType.INSTANCE),
             
FunctionSignature.ret(DoubleType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT)
     );
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDoubleOuter.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDoubleOuter.java
index 1bb8c0383f4..a2e3609c48c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDoubleOuter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDoubleOuter.java
@@ -23,6 +23,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.DoubleType;
+import org.apache.doris.nereids.types.JsonType;
 import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
@@ -36,6 +37,7 @@ import java.util.List;
 public class ExplodeJsonArrayDoubleOuter extends TableGeneratingFunction 
implements UnaryExpression, AlwaysNullable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            FunctionSignature.ret(DoubleType.INSTANCE).args(JsonType.INSTANCE),
             
FunctionSignature.ret(DoubleType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT)
     );
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayInt.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayInt.java
index 17277e1c967..86db7573375 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayInt.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayInt.java
@@ -23,6 +23,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
+import org.apache.doris.nereids.types.JsonType;
 import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
@@ -36,6 +37,7 @@ import java.util.List;
 public class ExplodeJsonArrayInt extends TableGeneratingFunction implements 
UnaryExpression, PropagateNullable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            FunctionSignature.ret(BigIntType.INSTANCE).args(JsonType.INSTANCE),
             
FunctionSignature.ret(BigIntType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT)
     );
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayIntOuter.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayIntOuter.java
index 2a8820c717c..fb7360959a4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayIntOuter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayIntOuter.java
@@ -23,6 +23,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
+import org.apache.doris.nereids.types.JsonType;
 import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
@@ -36,6 +37,7 @@ import java.util.List;
 public class ExplodeJsonArrayIntOuter extends TableGeneratingFunction 
implements UnaryExpression, AlwaysNullable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            FunctionSignature.ret(BigIntType.INSTANCE).args(JsonType.INSTANCE),
             
FunctionSignature.ret(BigIntType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT)
     );
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java
index a07e0e5d8fa..6209f23a7dd 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java
@@ -22,6 +22,7 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.JsonType;
 import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
@@ -35,6 +36,7 @@ import java.util.List;
  */
 public class ExplodeJsonArrayJson extends TableGeneratingFunction implements 
UnaryExpression, PropagateNullable {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            FunctionSignature.ret(JsonType.INSTANCE).args(JsonType.INSTANCE),
             
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT)
     );
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java
index bb4a34905a4..ab358855196 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java
@@ -22,6 +22,7 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.JsonType;
 import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
@@ -35,6 +36,7 @@ import java.util.List;
  */
 public class ExplodeJsonArrayJsonOuter extends TableGeneratingFunction 
implements UnaryExpression, PropagateNullable {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            FunctionSignature.ret(JsonType.INSTANCE).args(JsonType.INSTANCE),
             
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT)
     );
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayString.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayString.java
index 653cb36ca21..04717cd5c09 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayString.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayString.java
@@ -22,6 +22,7 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.JsonType;
 import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
@@ -35,6 +36,7 @@ import java.util.List;
 public class ExplodeJsonArrayString extends TableGeneratingFunction implements 
UnaryExpression, PropagateNullable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(JsonType.INSTANCE),
             
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT)
     );
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayStringOuter.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayStringOuter.java
index dfb21ab826f..03507aa9799 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayStringOuter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayStringOuter.java
@@ -22,6 +22,7 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.JsonType;
 import org.apache.doris.nereids.types.VarcharType;
 
 import com.google.common.base.Preconditions;
@@ -35,6 +36,7 @@ import java.util.List;
 public class ExplodeJsonArrayStringOuter extends TableGeneratingFunction 
implements UnaryExpression, AlwaysNullable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(JsonType.INSTANCE),
             
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT)
     );
 
diff --git a/regression-test/data/nereids_function_p0/gen_function/gen.out 
b/regression-test/data/nereids_function_p0/gen_function/gen.out
index 17f86d875e0..286a05ee85b 100644
--- a/regression-test/data/nereids_function_p0/gen_function/gen.out
+++ b/regression-test/data/nereids_function_p0/gen_function/gen.out
@@ -757,6 +757,47 @@
 11     {"id":2,"name":"Mary"}
 11     {"id":3,"name":"Bob"}
 
+-- !sql_explode_json_array_json_Json --
+\N     {"id":1,"name":"John"}
+\N     {"id":2,"name":"Mary"}
+\N     {"id":3,"name":"Bob"}
+0      {"id":1,"name":"John"}
+0      {"id":2,"name":"Mary"}
+0      {"id":3,"name":"Bob"}
+1      {"id":1,"name":"John"}
+1      {"id":2,"name":"Mary"}
+1      {"id":3,"name":"Bob"}
+2      {"id":1,"name":"John"}
+2      {"id":2,"name":"Mary"}
+2      {"id":3,"name":"Bob"}
+3      {"id":1,"name":"John"}
+3      {"id":2,"name":"Mary"}
+3      {"id":3,"name":"Bob"}
+4      {"id":1,"name":"John"}
+4      {"id":2,"name":"Mary"}
+4      {"id":3,"name":"Bob"}
+5      {"id":1,"name":"John"}
+5      {"id":2,"name":"Mary"}
+5      {"id":3,"name":"Bob"}
+6      {"id":1,"name":"John"}
+6      {"id":2,"name":"Mary"}
+6      {"id":3,"name":"Bob"}
+7      {"id":1,"name":"John"}
+7      {"id":2,"name":"Mary"}
+7      {"id":3,"name":"Bob"}
+8      {"id":1,"name":"John"}
+8      {"id":2,"name":"Mary"}
+8      {"id":3,"name":"Bob"}
+9      {"id":1,"name":"John"}
+9      {"id":2,"name":"Mary"}
+9      {"id":3,"name":"Bob"}
+10     {"id":1,"name":"John"}
+10     {"id":2,"name":"Mary"}
+10     {"id":3,"name":"Bob"}
+11     {"id":1,"name":"John"}
+11     {"id":2,"name":"Mary"}
+11     {"id":3,"name":"Bob"}
+
 -- !sql_explode_Double --
 0      0.1
 1      0.2
diff --git 
a/regression-test/data/query_p0/sql_functions/table_function/explode_json_array.out
 
b/regression-test/data/query_p0/sql_functions/table_function/explode_json_array.out
index ccc012e1121..f75b56b3305 100644
--- 
a/regression-test/data/query_p0/sql_functions/table_function/explode_json_array.out
+++ 
b/regression-test/data/query_p0/sql_functions/table_function/explode_json_array.out
@@ -79,7 +79,21 @@
 \N     80      3
 \N     80      b
 
--- !outer_join_explode_json_array11 --
+-- !outer_join_explode_json_array111 --
+\N     \N      {"id":1,"name":"John"}
+\N     \N      {"id":2,"name":"Mary"}
+\N     \N      {"id":3,"name":"Bob"}
+\N     30      {"id":1,"name":"John"}
+\N     30      {"id":2,"name":"Mary"}
+\N     30      {"id":3,"name":"Bob"}
+\N     50      {"id":1,"name":"John"}
+\N     50      {"id":2,"name":"Mary"}
+\N     50      {"id":3,"name":"Bob"}
+\N     80      {"id":1,"name":"John"}
+\N     80      {"id":2,"name":"Mary"}
+\N     80      {"id":3,"name":"Bob"}
+
+-- !outer_join_explode_json_array112 --
 \N     \N      {"id":1,"name":"John"}
 \N     \N      {"id":2,"name":"Mary"}
 \N     \N      {"id":3,"name":"Bob"}
diff --git a/regression-test/suites/nereids_function_p0/gen_function/gen.groovy 
b/regression-test/suites/nereids_function_p0/gen_function/gen.groovy
index 547ee40a220..7f30c9a2b6a 100644
--- a/regression-test/suites/nereids_function_p0/gen_function/gen.groovy
+++ b/regression-test/suites/nereids_function_p0/gen_function/gen.groovy
@@ -62,6 +62,9 @@ suite("nereids_gen_fn") {
        qt_sql_explode_json_array_json_Varchar '''
                select id, e from fn_test lateral view 
explode_json_array_json('[{"id":1,"name":"John"},{"id":2,"name":"Mary"},{"id":3,"name":"Bob"}]')
 lv as e order by id, e'''
 
+       qt_sql_explode_json_array_json_Json '''
+               select id, e from fn_test lateral view 
explode_json_array_json(cast('[{"id":1,"name":"John"},{"id":2,"name":"Mary"},{"id":3,"name":"Bob"}]'
 as json)) lv as e order by id, cast(e as string); '''
+
        // explode
        order_qt_sql_explode_Double "select id, e from fn_test lateral view 
explode(kadbl) lv as e order by id, e"
        order_qt_sql_explode_Double_notnull "select id, e from 
fn_test_not_nullable lateral view explode(kadbl) lv as e order by id, e"
diff --git 
a/regression-test/suites/query_p0/sql_functions/table_function/explode_json_array.groovy
 
b/regression-test/suites/query_p0/sql_functions/table_function/explode_json_array.groovy
index e6ed1b62a24..edc1bc7fa1a 100644
--- 
a/regression-test/suites/query_p0/sql_functions/table_function/explode_json_array.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/table_function/explode_json_array.groovy
@@ -60,10 +60,14 @@ suite("explode_json_array") {
     qt_outer_join_explode_json_array11 """SELECT id, age, e1 FROM (SELECT id, 
age, e1 FROM (SELECT b.id, a.age FROM 
                                         person a LEFT JOIN person b ON 
a.id=b.age)T LATERAL VIEW EXPLODE_JSON_ARRAY_STRING('[1, "b", 3]')
                                         TMP AS e1) AS T ORDER BY age, e1"""
-    qt_outer_join_explode_json_array11 """SELECT id, age, e1 FROM (SELECT id, 
age, e1 FROM (SELECT b.id, a.age FROM
+    qt_outer_join_explode_json_array111 """SELECT id, age, e1 FROM (SELECT id, 
age, e1 FROM (SELECT b.id, a.age FROM
                                         person a LEFT JOIN person b ON 
a.id=b.age)T LATERAL VIEW 
EXPLODE_JSON_ARRAY_JSON('[{"id":1,"name":"John"},{"id":2,"name":"Mary"},{"id":3,"name":"Bob"}]')
                                         TMP AS e1) AS T ORDER BY age, e1"""
 
+    qt_outer_join_explode_json_array112 """SELECT id, age, e1 FROM (SELECT id, 
age, e1 FROM (SELECT b.id, a.age FROM
+                                        person a LEFT JOIN person b ON 
a.id=b.age)T LATERAL VIEW 
EXPLODE_JSON_ARRAY_JSON(cast('[{"id":1,"name":"John"},{"id":2,"name":"Mary"},{"id":3,"name":"Bob"}]'
 as Json))
+                                        TMP AS e1) AS T ORDER BY age, cast(e1 
as string)"""
+
     qt_explode_json_array12 """ SELECT c_age, COUNT(1) FROM person
                         LATERAL VIEW 
EXPLODE_JSON_ARRAY_INT('[9223372036854775807,9223372036854775808]') t1 as c_age 
                         GROUP BY c_age ORDER BY c_age """


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org


Reply via email to