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

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

commit ec36d27fc0ce00dac962c41cbcd17d7541a1e5d7
Author: zy-kkk <[email protected]>
AuthorDate: Mon Jul 17 11:40:02 2023 +0800

    [Feature](table function) support explode_json_array_json (#21795)
---
 .../table_function/table_function_factory.cpp      |   3 +
 .../exprs/table_function/vexplode_json_array.cpp   |  25 ++++
 .../vec/exprs/table_function/vexplode_json_array.h |   7 +-
 be/src/vec/functions/function_fake.cpp             |   3 +
 .../table-functions/explode-json-array.md          |  16 +++
 .../table-functions/explode-json-array.md          | 150 +++++++++++++++++----
 .../catalog/BuiltinTableGeneratingFunctions.java   |   6 +-
 .../java/org/apache/doris/catalog/FunctionSet.java |   6 +
 .../functions/generator/ExplodeJsonArrayJson.java  |  66 +++++++++
 .../generator/ExplodeJsonArrayJsonOuter.java       |  66 +++++++++
 .../visitor/TableGeneratingFunctionVisitor.java    |  11 ++
 .../doris/planner/TableFunctionPlanTest.java       |   6 +
 .../table_function/explode_json_array.out          |  14 ++
 .../table_function/explode_json_array.groovy       |   3 +
 14 files changed, 355 insertions(+), 27 deletions(-)

diff --git a/be/src/vec/exprs/table_function/table_function_factory.cpp 
b/be/src/vec/exprs/table_function/table_function_factory.cpp
index 06b69a27c7..bafe47b69e 100644
--- a/be/src/vec/exprs/table_function/table_function_factory.cpp
+++ b/be/src/vec/exprs/table_function/table_function_factory.cpp
@@ -49,6 +49,8 @@ inline auto VExplodeJsonArrayDoubleCreator =
         TableFunctionCreator<VExplodeJsonArrayTableFunction> 
{ExplodeJsonArrayType::DOUBLE};
 inline auto VExplodeJsonArrayStringCreator =
         TableFunctionCreator<VExplodeJsonArrayTableFunction> 
{ExplodeJsonArrayType::STRING};
+inline auto VExplodeJsonArrayJsonCreator =
+        TableFunctionCreator<VExplodeJsonArrayTableFunction> 
{ExplodeJsonArrayType::JSON};
 
 const std::unordered_map<std::string, 
std::function<std::unique_ptr<TableFunction>()>>
         TableFunctionFactory::_function_map {
@@ -57,6 +59,7 @@ const std::unordered_map<std::string, 
std::function<std::unique_ptr<TableFunctio
                 {"explode_json_array_int", VExplodeJsonArrayIntCreator},
                 {"explode_json_array_double", VExplodeJsonArrayDoubleCreator},
                 {"explode_json_array_string", VExplodeJsonArrayStringCreator},
+                {"explode_json_array_json", VExplodeJsonArrayJsonCreator},
                 {"explode_bitmap", 
TableFunctionCreator<VExplodeBitmapTableFunction>()},
                 {"explode", TableFunctionCreator<VExplodeTableFunction> {}}};
 
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 16f6c39bf7..840923d018 100644
--- a/be/src/vec/exprs/table_function/vexplode_json_array.cpp
+++ b/be/src/vec/exprs/table_function/vexplode_json_array.cpp
@@ -24,6 +24,8 @@
 #include <algorithm>
 
 #include "common/status.h"
+#include "rapidjson/stringbuffer.h"
+#include "rapidjson/writer.h"
 #include "vec/columns/column.h"
 #include "vec/core/block.h"
 #include "vec/core/column_with_type_and_name.h"
@@ -125,6 +127,29 @@ int ParsedData::set_output(ExplodeJsonArrayType type, 
rapidjson::Document& docum
         }
         break;
     }
+    case ExplodeJsonArrayType::JSON: {
+        _data_string.clear();
+        _backup_string.clear();
+        _string_nulls.clear();
+        for (auto& v : document.GetArray()) {
+            if (v.IsObject()) {
+                rapidjson::StringBuffer buffer;
+                rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+                v.Accept(writer);
+                _backup_string.emplace_back(buffer.GetString(), 
buffer.GetSize());
+                _string_nulls.push_back(false);
+            } else {
+                _data_string.push_back({});
+                _string_nulls.push_back(true);
+            }
+        }
+        // Must set _data_string at the end, so that we can
+        // save the real addr of string in `_backup_string` to `_data_string`.
+        for (auto& str : _backup_string) {
+            _data_string.emplace_back(str);
+        }
+        break;
+    }
     default:
         CHECK(false) << type;
         break;
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 2bdae9ed8e..db1784e5ad 100644
--- a/be/src/vec/exprs/table_function/vexplode_json_array.h
+++ b/be/src/vec/exprs/table_function/vexplode_json_array.h
@@ -40,7 +40,7 @@ class Block;
 
 namespace doris::vectorized {
 
-enum ExplodeJsonArrayType { INT = 0, DOUBLE, STRING };
+enum ExplodeJsonArrayType { INT = 0, DOUBLE, STRING, JSON };
 
 struct ParsedData {
     static std::string true_value;
@@ -66,6 +66,7 @@ struct ParsedData {
             _data.clear();
             _backup_double.clear();
             break;
+        case ExplodeJsonArrayType::JSON:
         case ExplodeJsonArrayType::STRING:
             _data_string.clear();
             _backup_string.clear();
@@ -82,6 +83,7 @@ struct ParsedData {
         case ExplodeJsonArrayType::INT:
         case ExplodeJsonArrayType::DOUBLE:
             return _data[offset];
+        case ExplodeJsonArrayType::JSON:
         case ExplodeJsonArrayType::STRING:
             return _string_nulls[offset] ? nullptr
                    : real                ? 
reinterpret_cast<void*>(_backup_string[offset].data())
@@ -92,7 +94,8 @@ struct ParsedData {
     }
 
     int64 get_value_length(ExplodeJsonArrayType type, int64_t offset) {
-        if (type == ExplodeJsonArrayType::STRING && !_string_nulls[offset]) {
+        if ((type == ExplodeJsonArrayType::STRING || type == 
ExplodeJsonArrayType::JSON) &&
+            !_string_nulls[offset]) {
             return _backup_string[offset].size();
         }
         return 0;
diff --git a/be/src/vec/functions/function_fake.cpp 
b/be/src/vec/functions/function_fake.cpp
index 4fd626d17b..26896c028c 100644
--- a/be/src/vec/functions/function_fake.cpp
+++ b/be/src/vec/functions/function_fake.cpp
@@ -26,6 +26,7 @@
 
 #include "vec/aggregate_functions/aggregate_function.h"
 #include "vec/data_types/data_type_array.h"
+#include "vec/data_types/data_type_jsonb.h"
 #include "vec/data_types/data_type_nullable.h"
 #include "vec/data_types/data_type_number.h"
 #include "vec/data_types/data_type_string.h"
@@ -102,6 +103,8 @@ void register_function_fake(SimpleFunctionFactory& factory) 
{
     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");
diff --git 
a/docs/en/docs/sql-manual/sql-functions/table-functions/explode-json-array.md 
b/docs/en/docs/sql-manual/sql-functions/table-functions/explode-json-array.md
index ee4cfe1d8f..daff67381f 100644
--- 
a/docs/en/docs/sql-manual/sql-functions/table-functions/explode-json-array.md
+++ 
b/docs/en/docs/sql-manual/sql-functions/table-functions/explode-json-array.md
@@ -38,6 +38,7 @@ Expand a json array. According to the array element type, 
there are three functi
 explode_json_array_int(json_str)
 explode_json_array_double(json_str)
 explode_json_array_string(json_str)
+explode_json_array_json(json_str)
 ```
 
 ### example
@@ -276,6 +277,21 @@ mysql> select k1, e1 from example1 lateral view 
explode_json_array_string('{"a":
 |    2 | NULL |
 |    3 | NULL |
 +------+------+
+
+mysql> select k1, e1 from example1 lateral view 
explode_json_array_json('[{"id":1,"name":"John"},{"id":2,"name":"Mary"},{"id":3,"name":"Bob"}]')
 tmp1 as e1 order by k1, e1;
++------+------------------------+
+| k1   | e1                     |
++------+------------------------+
+|    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"}  |
++------+------------------------+
 ```
 
 ### keywords
diff --git 
a/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/explode-json-array.md
 
b/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/explode-json-array.md
index 15591a595c..c7f09139e1 100644
--- 
a/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/explode-json-array.md
+++ 
b/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/explode-json-array.md
@@ -37,28 +37,22 @@ under the License.
 explode_json_array_int(json_str)
 explode_json_array_double(json_str)
 explode_json_array_string(json_str)
+explode_json_array_json(json_str)
 ```
 
 ### example
 
 原表数据:
 
-```
-mysql> select k1 from example1 order by k1;
-+------+
-| k1   |
-+------+
-|    1 |
-|    2 |
-|    3 |
-+------+
-```
-
-Lateral View:
-
 ```
 mysql> select k1, e1 from example1 lateral view explode_json_array_int('[]') 
tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    2 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_int('[1,2,3]') tmp1 as e1 order by k1, e1;
 +------+------+
@@ -79,28 +73,79 @@ mysql> select k1, e1 from example1 lateral view 
explode_json_array_int('[1,"b",3
 +------+------+
 | k1   | e1   |
 +------+------+
+|    1 | NULL |
 |    1 |    1 |
 |    1 |    3 |
+|    2 | NULL |
 |    2 |    1 |
 |    2 |    3 |
+|    3 | NULL |
 |    3 |    1 |
 |    3 |    3 |
 +------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_int('["a","b","c"]') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    1 | NULL |
+|    1 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    3 | NULL |
+|    3 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view explode_json_array_int('{"a": 
3}') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    2 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_double('[]') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    2 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_double('[1,2,3]') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    1 | NULL |
+|    1 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    3 | NULL |
+|    3 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_double('[1,"b",3]') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    1 | NULL |
+|    1 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    3 | NULL |
+|    3 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_double('[1.0,2.0,3.0]') tmp1 as e1 order by k1, e1;
 +------+------+
@@ -118,16 +163,52 @@ mysql> select k1, e1 from example1 lateral view 
explode_json_array_double('[1.0,
 +------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_double('[1,"b",3]') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    1 | NULL |
+|    1 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    3 | NULL |
+|    3 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_double('["a","b","c"]') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    1 | NULL |
+|    1 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    2 | NULL |
+|    3 | NULL |
+|    3 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_double('{"a": 3}') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    2 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_string('[]') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    2 | NULL |
+|    3 | NULL |
++------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_string('[1.0,2.0,3.0]') tmp1 as e1 order by k1, e1;
 +------+----------+
@@ -175,7 +256,28 @@ mysql> select k1, e1 from example1 lateral view 
explode_json_array_string('["a",
 +------+------+
 
 mysql> select k1, e1 from example1 lateral view 
explode_json_array_string('{"a": 3}') tmp1 as e1 order by k1, e1;
-Empty set
++------+------+
+| k1   | e1   |
++------+------+
+|    1 | NULL |
+|    2 | NULL |
+|    3 | NULL |
++------+------+
+
+mysql> select k1, e1 from example1 lateral view 
explode_json_array_json('[{"id":1,"name":"John"},{"id":2,"name":"Mary"},{"id":3,"name":"Bob"}]')
 tmp1 as e1 order by k1, e1;
++------+------------------------+
+| k1   | e1                     |
++------+------------------------+
+|    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"}  |
++------+------------------------+
 ```
 
 ### keywords
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinTableGeneratingFunctions.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinTableGeneratingFunctions.java
index fc82eafcbb..b1dd9c8306 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinTableGeneratingFunctions.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinTableGeneratingFunctions.java
@@ -23,6 +23,8 @@ import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJso
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayDoubleOuter;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayInt;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayIntOuter;
+import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayJson;
+import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayJsonOuter;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayString;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayStringOuter;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeNumbers;
@@ -53,7 +55,9 @@ public class BuiltinTableGeneratingFunctions implements 
FunctionHelper {
             tableGenerating(ExplodeJsonArrayDouble.class, 
"explode_json_array_double"),
             tableGenerating(ExplodeJsonArrayDoubleOuter.class, 
"explode_json_array_double_outer"),
             tableGenerating(ExplodeJsonArrayString.class, 
"explode_json_array_string"),
-            tableGenerating(ExplodeJsonArrayStringOuter.class, 
"explode_json_array_string_outer")
+            tableGenerating(ExplodeJsonArrayStringOuter.class, 
"explode_json_array_string_outer"),
+            tableGenerating(ExplodeJsonArrayJson.class, 
"explode_json_array_json"),
+            tableGenerating(ExplodeJsonArrayJsonOuter.class, 
"explode_json_array_json_outer")
     );
 
     public static final BuiltinTableGeneratingFunctions INSTANCE = new 
BuiltinTableGeneratingFunctions();
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
index f86bba5006..558d328de2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
@@ -1588,6 +1588,7 @@ public class FunctionSet<T> {
     public static final String EXPLODE_JSON_ARRAY_INT = 
"explode_json_array_int";
     public static final String EXPLODE_JSON_ARRAY_DOUBLE = 
"explode_json_array_double";
     public static final String EXPLODE_JSON_ARRAY_STRING = 
"explode_json_array_string";
+    public static final String EXPLODE_JSON_ARRAY_JSON = 
"explode_json_array_json";
     public static final String EXPLODE_NUMBERS = "explode_numbers";
     public static final String EXPLODE = "explode";
 
@@ -1635,6 +1636,11 @@ public class FunctionSet<T> {
                 Function.NullableMode.DEPEND_ON_ARGUMENT, 
Lists.newArrayList(Type.VARCHAR), false,
                 
"_ZN5doris19DummyTableFunctions25explode_json_array_stringEPN9doris_udf15FunctionContextERKNS1_9StringValE");
 
+        initTableFunctionListWithCombinator(EXPLODE_JSON_ARRAY_JSON);
+        addTableFunctionWithCombinator(EXPLODE_JSON_ARRAY_JSON, Type.VARCHAR,
+                Function.NullableMode.DEPEND_ON_ARGUMENT, 
Lists.newArrayList(Type.VARCHAR), false,
+                
"_ZN5doris19DummyTableFunctions25explode_json_array_jsonEPN9doris_udf15FunctionContextERKNS1_9StringValE");
+
         initTableFunctionListWithCombinator(EXPLODE_NUMBERS);
         addTableFunctionWithCombinator(EXPLODE_NUMBERS, Type.INT, 
Function.NullableMode.DEPEND_ON_ARGUMENT,
                 Lists.newArrayList(Type.INT), false,
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
new file mode 100644
index 0000000000..a07e0e5d8f
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java
@@ -0,0 +1,66 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.generator;
+
+import org.apache.doris.catalog.FunctionSignature;
+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.VarcharType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * 
explode_json_array_json("[{"id":1,"name":"John"},{"id":2,"name":"Mary"},{"id":3,"name":"Bob"}]"),
+ * generate 3 lines include '{"id":1,"name":"John"}', '{"id":2,"name":"Mary"}' 
and '{"id":3,"name":"Bob"}'.
+ */
+public class ExplodeJsonArrayJson extends TableGeneratingFunction implements 
UnaryExpression, PropagateNullable {
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT)
+    );
+
+    /**
+     * constructor with 1 argument.
+     */
+    public ExplodeJsonArrayJson(Expression arg) {
+        super("explode_json_array_json", arg);
+    }
+
+    /**
+     * withChildren.
+     */
+    @Override
+    public ExplodeJsonArrayJson withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 1);
+        return new ExplodeJsonArrayJson(children.get(0));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitExplodeJsonArrayJson(this, context);
+    }
+}
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
new file mode 100644
index 0000000000..bb4a34905a
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java
@@ -0,0 +1,66 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.generator;
+
+import org.apache.doris.catalog.FunctionSignature;
+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.VarcharType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * 
explode_json_array_json_outer("[{"id":1,"name":"John"},{"id":2,"name":"Mary"},{"id":3,"name":"Bob"}]"),
+ * generate 3 lines include '{"id":1,"name":"John"}', '{"id":2,"name":"Mary"}' 
and '{"id":3,"name":"Bob"}'.
+ */
+public class ExplodeJsonArrayJsonOuter extends TableGeneratingFunction 
implements UnaryExpression, PropagateNullable {
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT)
+    );
+
+    /**
+     * constructor with 1 argument.
+     */
+    public ExplodeJsonArrayJsonOuter(Expression arg) {
+        super("explode_json_array_json_outer", arg);
+    }
+
+    /**
+     * withChildren.
+     */
+    @Override
+    public ExplodeJsonArrayJsonOuter withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 1);
+        return new ExplodeJsonArrayJsonOuter(children.get(0));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitExplodeJsonArrayJsonOuter(this, context);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/TableGeneratingFunctionVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/TableGeneratingFunctionVisitor.java
index a869ab0d7e..040b279df8 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/TableGeneratingFunctionVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/TableGeneratingFunctionVisitor.java
@@ -23,6 +23,8 @@ import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJso
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayDoubleOuter;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayInt;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayIntOuter;
+import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayJson;
+import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayJsonOuter;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayString;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonArrayStringOuter;
 import 
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeNumbers;
@@ -84,4 +86,13 @@ public interface TableGeneratingFunctionVisitor<R, C> {
     default R visitExplodeJsonArrayStringOuter(ExplodeJsonArrayStringOuter 
explodeJsonArrayStringOuter, C context) {
         return visitTableGeneratingFunction(explodeJsonArrayStringOuter, 
context);
     }
+
+    default R visitExplodeJsonArrayJson(ExplodeJsonArrayJson 
explodeJsonArrayJson, C context) {
+        return visitTableGeneratingFunction(explodeJsonArrayJson, context);
+    }
+
+    default R visitExplodeJsonArrayJsonOuter(ExplodeJsonArrayJsonOuter 
explodeJsonArrayJsonOuter, C context) {
+        return visitTableGeneratingFunction(explodeJsonArrayJsonOuter, 
context);
+    }
+
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java
index 0b1308c9b1..f1e187ccc0 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java
@@ -447,6 +447,12 @@ public class TableFunctionPlanTest {
         System.out.println(explainString);
         Assert.assertTrue(explainString.contains("table function: 
explode_json_array_double('[1.1, 2.2, 3.3]')"));
         Assert.assertTrue(explainString.contains("output slot id: 0 1"));
+
+        sql = "desc select /*+ SET_VAR(enable_nereids_planner=false) */ k1, e1 
from db1.tbl2 lateral view 
explode_json_array_json('[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Mary\"},{\"id\":3,\"name\":\"Bob\"}]')
 tmp1 as e1 ";
+        explainString = UtFrameUtils.getSQLPlanOrErrorMsg(ctx, sql, true);
+        System.out.println(explainString);
+        Assert.assertTrue(explainString.contains("table function: 
explode_json_array_json('[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Mary\"},{\"id\":3,\"name\":\"Bob\"}]')"));
+        Assert.assertTrue(explainString.contains("output slot id: 0 1"));
     }
 
     /*
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 a9f68ee30c..0b1994a22c 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
@@ -75,3 +75,17 @@
 \N     80      3
 \N     80      b
 
+-- !outer_join_explode_json_array11 --
+\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"}
+
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 fc94aa5655..7ee801702b 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
@@ -57,4 +57,7 @@ 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 
                                         ${tableName} a LEFT JOIN ${tableName} 
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
+                                        ${tableName} a LEFT JOIN ${tableName} 
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"""
 }


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

Reply via email to