This is an automated email from the ASF dual-hosted git repository.
kxiao 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 3cb1d4e842a [feature](json)support explode_json_object func #36887
(#37378)
3cb1d4e842a is described below
commit 3cb1d4e842a4824b2ff4707f9bf76277233fa162
Author: amory <[email protected]>
AuthorDate: Tue Jul 16 10:59:11 2024 +0800
[feature](json)support explode_json_object func #36887 (#37378)
---
be/src/vec/exprs/table_function/table_function.h | 1 +
.../vec/exprs/table_function/vexplode_bitmap.cpp | 2 +-
.../vec/exprs/table_function/vexplode_json_array.h | 2 +-
.../exprs/table_function/vexplode_json_object.cpp | 160 +++++++++++++++++++++
.../exprs/table_function/vexplode_json_object.h | 59 ++++++++
be/src/vec/functions/function_fake.cpp | 14 ++
.../catalog/BuiltinTableGeneratingFunctions.java | 4 +
.../functions/generator/ExplodeJsonObject.java | 70 +++++++++
.../generator/ExplodeJsonObjectOuter.java | 68 +++++++++
.../visitor/TableGeneratingFunctionVisitor.java | 10 ++
.../jsonb_p0/test_jsonb_load_and_function.out | 79 +++++++++-
.../jsonb_p0/test_jsonb_load_and_function.groovy | 9 ++
.../jsonb_p0/test_jsonb_load_and_function.groovy | 4 +
13 files changed, 478 insertions(+), 4 deletions(-)
diff --git a/be/src/vec/exprs/table_function/table_function.h
b/be/src/vec/exprs/table_function/table_function.h
index bd926c36570..fc3d3882b50 100644
--- a/be/src/vec/exprs/table_function/table_function.h
+++ b/be/src/vec/exprs/table_function/table_function.h
@@ -54,6 +54,7 @@ public:
}
virtual void get_same_many_values(MutableColumnPtr& column, int length =
0) = 0;
+
virtual int get_value(MutableColumnPtr& column, int max_step) = 0;
virtual Status close() { return Status::OK(); }
diff --git a/be/src/vec/exprs/table_function/vexplode_bitmap.cpp
b/be/src/vec/exprs/table_function/vexplode_bitmap.cpp
index 5327c2e1633..e6e4c843075 100644
--- a/be/src/vec/exprs/table_function/vexplode_bitmap.cpp
+++ b/be/src/vec/exprs/table_function/vexplode_bitmap.cpp
@@ -90,7 +90,7 @@ void
VExplodeBitmapTableFunction::get_same_many_values(MutableColumnPtr& column,
void VExplodeBitmapTableFunction::process_row(size_t row_idx) {
TableFunction::process_row(row_idx);
- //FIXME: use ColumnComplex instead
+
StringRef value = _value_column->get_data_at(row_idx);
if (value.data) {
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 968fa5e91a4..1d89d9fa57d 100644
--- a/be/src/vec/exprs/table_function/vexplode_json_array.h
+++ b/be/src/vec/exprs/table_function/vexplode_json_array.h
@@ -269,4 +269,4 @@ private:
ColumnPtr _text_column;
};
-} // namespace doris::vectorized
\ No newline at end of file
+} // namespace doris::vectorized
diff --git a/be/src/vec/exprs/table_function/vexplode_json_object.cpp
b/be/src/vec/exprs/table_function/vexplode_json_object.cpp
new file mode 100644
index 00000000000..1981f48f62c
--- /dev/null
+++ b/be/src/vec/exprs/table_function/vexplode_json_object.cpp
@@ -0,0 +1,160 @@
+// 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.
+
+#include "vec/exprs/table_function/vexplode_json_object.h"
+
+#include <glog/logging.h>
+
+#include <ostream>
+#include <vector>
+
+#include "common/status.h"
+#include "vec/columns/column.h"
+#include "vec/common/string_ref.h"
+#include "vec/core/block.h"
+#include "vec/core/column_with_type_and_name.h"
+#include "vec/exprs/vexpr.h"
+#include "vec/exprs/vexpr_context.h"
+
+namespace doris::vectorized {
+
+VExplodeJsonObjectTableFunction::VExplodeJsonObjectTableFunction() {
+ _fn_name = "vexplode_json_object";
+}
+
+Status VExplodeJsonObjectTableFunction::process_init(Block* block,
RuntimeState* state) {
+ CHECK(_expr_context->root()->children().size() == 1)
+ << "VExplodeJsonObjectTableFunction only support 1 child but has "
+ << _expr_context->root()->children().size();
+
+ int text_column_idx = -1;
+
RETURN_IF_ERROR(_expr_context->root()->children()[0]->execute(_expr_context.get(),
block,
+
&text_column_idx));
+
+ _json_object_column = block->get_by_position(text_column_idx).column;
+ return Status::OK();
+}
+
+void VExplodeJsonObjectTableFunction::process_row(size_t row_idx) {
+ TableFunction::process_row(row_idx);
+
+ StringRef text = _json_object_column->get_data_at(row_idx);
+ if (text.data != nullptr) {
+ JsonbDocument* doc = JsonbDocument::createDocument(text.data,
text.size);
+ if (UNLIKELY(!doc || !doc->getValue())) {
+ // error jsonb, put null into output, cur_size = 0 , we will
insert_default
+ return;
+ }
+ // value is NOT necessary to be deleted since JsonbValue will not
allocate memory
+ JsonbValue* value = doc->getValue();
+ auto writer = std::make_unique<JsonbWriter>();
+ if (value->isObject()) {
+ _cur_size = value->length();
+ ObjectVal* obj = (ObjectVal*)value;
+ _object_pairs.first =
+ ColumnNullable::create(ColumnString::create(),
ColumnUInt8::create());
+ _object_pairs.second =
+ ColumnNullable::create(ColumnString::create(),
ColumnUInt8::create());
+ _object_pairs.first->reserve(_cur_size);
+ _object_pairs.second->reserve(_cur_size);
+ for (auto it = obj->begin(); it != obj->end(); ++it) {
+ _object_pairs.first->insert_data(it->getKeyStr(), it->klen());
+ writer->reset();
+ writer->writeValue(it->value());
+ if (it->value()->isNull()) {
+ _object_pairs.second->insert_default();
+ } else {
+ const std::string_view& jsonb_value = std::string_view(
+ writer->getOutput()->getBuffer(),
writer->getOutput()->getSize());
+ _object_pairs.second->insert_data(jsonb_value.data(),
jsonb_value.size());
+ }
+ }
+ }
+ // we do not support other json type except object
+ }
+}
+
+void VExplodeJsonObjectTableFunction::process_close() {
+ _json_object_column = nullptr;
+ _object_pairs.first = nullptr;
+ _object_pairs.second = nullptr;
+}
+
+void VExplodeJsonObjectTableFunction::get_same_many_values(MutableColumnPtr&
column, int length) {
+ // if current is empty map row, also append a default value
+ if (current_empty()) {
+ column->insert_many_defaults(length);
+ return;
+ }
+ ColumnStruct* ret = nullptr;
+ // this _is_nullable is whole output column's nullable
+ if (_is_nullable) {
+ // make map kv value into struct
+ ret = assert_cast<ColumnStruct*>(
+
assert_cast<ColumnNullable*>(column.get())->get_nested_column_ptr().get());
+ assert_cast<ColumnUInt8*>(
+
assert_cast<ColumnNullable*>(column.get())->get_null_map_column_ptr().get())
+ ->insert_many_defaults(length);
+ } else if (column->is_column_struct()) {
+ ret = assert_cast<ColumnStruct*>(column.get());
+ } else {
+ throw Exception(ErrorCode::INTERNAL_ERROR,
+ "only support expand json object int to struct(kv
pair), but given: ",
+ column->get_name());
+ }
+ if (!ret || ret->tuple_size() != 2) {
+ throw Exception(ErrorCode::INTERNAL_ERROR,
+ "only support expand json object int to kv pair
column, but given: ",
+ ret->tuple_size());
+ }
+ ret->get_column(0).insert_many_from(*_object_pairs.first, _cur_offset,
length);
+ ret->get_column(1).insert_many_from(*_object_pairs.second, _cur_offset,
length);
+}
+
+int VExplodeJsonObjectTableFunction::get_value(MutableColumnPtr& column, int
max_step) {
+ max_step = std::min(max_step, (int)(_cur_size - _cur_offset));
+ 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());
+ // here nullmap_column insert max_step many defaults as if
MAP[row_idx] is NULL
+ // will be not update value, _cur_size = 0, means current_empty;
+ // so here could insert directly
+ nullmap_column->insert_many_defaults(max_step);
+ } else {
+ struct_column = assert_cast<ColumnStruct*>(column.get());
+ }
+ if (!struct_column || struct_column->tuple_size() != 2) {
+ throw Exception(ErrorCode::INTERNAL_ERROR,
+ "only support expand json object int to kv pair
column, but given: ",
+ struct_column->tuple_size());
+ }
+ struct_column->get_column(0).insert_range_from(*_object_pairs.first,
_cur_offset, max_step);
+ struct_column->get_column(1).insert_range_from(*_object_pairs.second,
_cur_offset,
+ max_step);
+ }
+ forward(max_step);
+ return max_step;
+}
+} // namespace doris::vectorized
diff --git a/be/src/vec/exprs/table_function/vexplode_json_object.h
b/be/src/vec/exprs/table_function/vexplode_json_object.h
new file mode 100644
index 00000000000..9173fd9cbac
--- /dev/null
+++ b/be/src/vec/exprs/table_function/vexplode_json_object.h
@@ -0,0 +1,59 @@
+// 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.
+
+#pragma once
+
+#include <stddef.h>
+
+#include "common/status.h"
+#include "vec/columns/column_map.h"
+#include "vec/data_types/data_type.h"
+#include "vec/data_types/data_type_array.h"
+#include "vec/data_types/data_type_map.h"
+#include "vec/exprs/table_function/table_function.h"
+#include "vec/functions/array/function_array_utils.h"
+
+namespace doris::vectorized {
+class Block;
+} // namespace doris::vectorized
+
+namespace doris::vectorized {
+
+// explode_json_object("{\"a\": 1, \"b\": 2}") ->
+// | key | value |
+// | a | 1 |
+// | b | 2 |
+class VExplodeJsonObjectTableFunction : public TableFunction {
+ ENABLE_FACTORY_CREATOR(VExplodeJsonObjectTableFunction);
+
+public:
+ VExplodeJsonObjectTableFunction();
+
+ ~VExplodeJsonObjectTableFunction() override = default;
+
+ Status process_init(Block* block, RuntimeState* state) override;
+ void process_row(size_t row_idx) override;
+ void process_close() override;
+ void get_same_many_values(MutableColumnPtr& column, int length) override;
+ int get_value(MutableColumnPtr& column, int max_step) override;
+
+private:
+ ColumnPtr _json_object_column;
+ std::pair<MutableColumnPtr, MutableColumnPtr> _object_pairs; //
ColumnNullable<ColumnString>
+};
+
+} // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_fake.cpp
b/be/src/vec/functions/function_fake.cpp
index 2d8e258d529..0353b3a2a7c 100644
--- a/be/src/vec/functions/function_fake.cpp
+++ b/be/src/vec/functions/function_fake.cpp
@@ -70,6 +70,19 @@ struct FunctionExplodeMap {
static std::string get_error_msg() { return "Fake function do not support
execute"; }
};
+// explode json-object: expands json-object to struct with a pair of key and
value in column string
+struct FunctionExplodeJsonObject {
+ static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
+ DCHECK(WhichDataType(arguments[0]).is_json())
+ << " explode json object " << arguments[0]->get_name() << "
not supported";
+ DataTypes fieldTypes(2);
+ fieldTypes[0] = make_nullable(std::make_shared<DataTypeString>());
+ fieldTypes[1] = make_nullable(std::make_shared<DataTypeJsonb>());
+ return
make_nullable(std::make_shared<vectorized::DataTypeStruct>(fieldTypes));
+ }
+ static std::string get_error_msg() { return "Fake function do not support
execute"; }
+};
+
struct FunctionEsquery {
static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
return
FunctionFakeBaseImpl<DataTypeUInt8>::get_return_type_impl(arguments);
@@ -113,6 +126,7 @@ void register_function_fake(SimpleFunctionFactory& factory)
{
register_table_function_expand_outer<FunctionExplode>(factory, "explode");
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");
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 6fab5cfc04e..84894db95c5 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
@@ -28,6 +28,8 @@ import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJso
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.ExplodeJsonObject;
+import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonObjectOuter;
import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeMap;
import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeMapOuter;
import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeNumbers;
@@ -52,6 +54,8 @@ public class BuiltinTableGeneratingFunctions implements
FunctionHelper {
tableGenerating(ExplodeOuter.class, "explode_outer"),
tableGenerating(ExplodeMap.class, "explode_map"),
tableGenerating(ExplodeMapOuter.class, "explode_map_outer"),
+ tableGenerating(ExplodeJsonObject.class, "explode_json_object"),
+ tableGenerating(ExplodeJsonObjectOuter.class,
"explode_json_object_outer"),
tableGenerating(ExplodeNumbers.class, "explode_numbers"),
tableGenerating(ExplodeNumbersOuter.class,
"explode_numbers_outer"),
tableGenerating(ExplodeBitmap.class, "explode_bitmap"),
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonObject.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonObject.java
new file mode 100644
index 00000000000..e4546205b7f
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonObject.java
@@ -0,0 +1,70 @@
+// 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.AlwaysNullable;
+import org.apache.doris.nereids.trees.expressions.literal.StructLiteral;
+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.StringType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * explode_json_object("{"amory":1, "doris": 2}") generate two column and two
lines with:
+ * key column: amory, doris
+ * value column: 1, 2
+ */
+public class ExplodeJsonObject extends TableGeneratingFunction implements
UnaryExpression, AlwaysNullable {
+
+ public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+ FunctionSignature.ret(StructLiteral.constructStructType(
+ ImmutableList.of(StringType.INSTANCE,
JsonType.INSTANCE))).args(JsonType.INSTANCE));
+
+ /**
+ * constructor with 1 argument.
+ */
+ public ExplodeJsonObject(Expression arg) {
+ super("explode_json_object", arg);
+ }
+
+ /**
+ * withChildren.
+ */
+ @Override
+ public ExplodeJsonObject withChildren(List<Expression> children) {
+ Preconditions.checkArgument(children.size() == 1);
+ return new ExplodeJsonObject(children.get(0));
+ }
+
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return SIGNATURES;
+ }
+
+ @Override
+ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitExplodeJsonObject(this, context);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonObjectOuter.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonObjectOuter.java
new file mode 100644
index 00000000000..7f927c90e9d
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonObjectOuter.java
@@ -0,0 +1,68 @@
+// 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.AlwaysNullable;
+import org.apache.doris.nereids.trees.expressions.literal.StructLiteral;
+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.StringType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * explode_json_object_out is explode_json_object without null value.
+ */
+public class ExplodeJsonObjectOuter extends TableGeneratingFunction implements
UnaryExpression, AlwaysNullable {
+
+ public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+ FunctionSignature.ret(StructLiteral.constructStructType(
+ ImmutableList.of(StringType.INSTANCE,
JsonType.INSTANCE))).args(JsonType.INSTANCE));
+
+ /**
+ * constructor with 1 argument.
+ */
+ public ExplodeJsonObjectOuter(Expression arg) {
+ super("explode_json_object_outer", arg);
+ }
+
+ /**
+ * withChildren.
+ */
+ @Override
+ public ExplodeJsonObjectOuter withChildren(List<Expression> children) {
+ Preconditions.checkArgument(children.size() == 1);
+ return new ExplodeJsonObjectOuter(children.get(0));
+ }
+
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return SIGNATURES;
+ }
+
+ @Override
+ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitExplodeJsonObjectOuter(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 4e4c8ab2bd4..f66d72f6409 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
@@ -28,6 +28,8 @@ import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJso
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.ExplodeJsonObject;
+import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeJsonObjectOuter;
import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeMap;
import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeMapOuter;
import
org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeNumbers;
@@ -59,6 +61,14 @@ public interface TableGeneratingFunctionVisitor<R, C> {
return visitTableGeneratingFunction(explodeOuter, context);
}
+ default R visitExplodeJsonObject(ExplodeJsonObject explode, C context) {
+ return visitTableGeneratingFunction(explode, context);
+ }
+
+ default R visitExplodeJsonObjectOuter(ExplodeJsonObjectOuter explodeOuter,
C context) {
+ return visitTableGeneratingFunction(explodeOuter, context);
+ }
+
default R visitExplodeNumbers(ExplodeNumbers explodeNumbers, C context) {
return visitTableGeneratingFunction(explodeNumbers, context);
}
diff --git
a/regression-test/data/nereids_p0/jsonb_p0/test_jsonb_load_and_function.out
b/regression-test/data/nereids_p0/jsonb_p0/test_jsonb_load_and_function.out
index 80a3880a549..0d33127ad20 100644
--- a/regression-test/data/nereids_p0/jsonb_p0/test_jsonb_load_and_function.out
+++ b/regression-test/data/nereids_p0/jsonb_p0/test_jsonb_load_and_function.out
@@ -8315,6 +8315,82 @@ false
33 {"":1,"":"v1"} [null,null,null]
34 {"":1,"ab":"v1","":"v1","":2} [null,null,null]
+-- !order_select_explode_json_object --
+1 \N \N \N
+2 null \N \N
+3 true \N \N
+4 false \N \N
+5 100 \N \N
+6 10000 \N \N
+7 1000000000 \N \N
+8 1152921504606846976 \N \N
+9 6.18 \N \N
+10 "abcd" \N \N
+11 {} \N \N
+12 {"k1":"v31","k2":300} k1 "v31"
+12 {"k1":"v31","k2":300} k2 300
+13 [] \N \N
+14 [123,456] \N \N
+15 ["abc","def"] \N \N
+16 [null,true,false,100,6.18,"abc"] \N \N
+17 [{"k1":"v41","k2":400},1,"a",3.14] \N \N
+18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} a1
[{"k1":"v41","k2":400},1,"a",3.14]
+18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} k1
"v31"
+18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} k2
300
+26 \N \N \N
+27 {"k1":"v1","k2":200} k1 "v1"
+27 {"k1":"v1","k2":200} k2 200
+28 {"a.b.c":{"k1.a1":"v31","k2":300},"a":"niu"} a "niu"
+28 {"a.b.c":{"k1.a1":"v31","k2":300},"a":"niu"} a.b.c
{"k1.a1":"v31","k2":300}
+29 12524337771678448270 \N \N
+30 -9223372036854775808 \N \N
+31 18446744073709551615 \N \N
+32 {"":"v1"} "v1"
+33 {"":1,"":"v1"} 1
+33 {"":1,"":"v1"} "v1"
+34 {"":1,"ab":"v1","":"v1","":2} 1
+34 {"":1,"ab":"v1","":"v1","":2} "v1"
+34 {"":1,"ab":"v1","":"v1","":2} 2
+34 {"":1,"ab":"v1","":"v1","":2} ab "v1"
+
+-- !order_select_explode_json_object_out --
+1 \N \N \N
+2 null \N \N
+3 true \N \N
+4 false \N \N
+5 100 \N \N
+6 10000 \N \N
+7 1000000000 \N \N
+8 1152921504606846976 \N \N
+9 6.18 \N \N
+10 "abcd" \N \N
+11 {} \N \N
+12 {"k1":"v31","k2":300} k1 "v31"
+12 {"k1":"v31","k2":300} k2 300
+13 [] \N \N
+14 [123,456] \N \N
+15 ["abc","def"] \N \N
+16 [null,true,false,100,6.18,"abc"] \N \N
+17 [{"k1":"v41","k2":400},1,"a",3.14] \N \N
+18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} a1
[{"k1":"v41","k2":400},1,"a",3.14]
+18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} k1
"v31"
+18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} k2
300
+26 \N \N \N
+27 {"k1":"v1","k2":200} k1 "v1"
+27 {"k1":"v1","k2":200} k2 200
+28 {"a.b.c":{"k1.a1":"v31","k2":300},"a":"niu"} a "niu"
+28 {"a.b.c":{"k1.a1":"v31","k2":300},"a":"niu"} a.b.c
{"k1.a1":"v31","k2":300}
+29 12524337771678448270 \N \N
+30 -9223372036854775808 \N \N
+31 18446744073709551615 \N \N
+32 {"":"v1"} "v1"
+33 {"":1,"":"v1"} 1
+33 {"":1,"":"v1"} "v1"
+34 {"":1,"ab":"v1","":"v1","":2} 1
+34 {"":1,"ab":"v1","":"v1","":2} "v1"
+34 {"":1,"ab":"v1","":"v1","":2} 2
+34 {"":1,"ab":"v1","":"v1","":2} ab "v1"
+
-- !sql_json_parse --
{"":"v1"}
@@ -8322,5 +8398,4 @@ false
{"":1,"":"v1"}
-- !sql_json_parse --
-{"":1,"ab":"v1","":"v1","":2}
-
+{"":1,"ab":"v1","":"v1","":2}
\ No newline at end of file
diff --git
a/regression-test/suites/jsonb_p0/test_jsonb_load_and_function.groovy
b/regression-test/suites/jsonb_p0/test_jsonb_load_and_function.groovy
index f8ce6aa2f63..00740d88a62 100644
--- a/regression-test/suites/jsonb_p0/test_jsonb_load_and_function.groovy
+++ b/regression-test/suites/jsonb_p0/test_jsonb_load_and_function.groovy
@@ -579,6 +579,15 @@ suite("test_jsonb_load_and_function", "p0") {
qt_select_json_contains """SELECT id, j, json_contains(j,
cast('{"k1":"v41","k2":400}' as json), '\$.a1') FROM ${testTable} ORDER BY id"""
qt_select_json_contains """SELECT id, j, json_contains(j, cast('[123,456]'
as json)) FROM ${testTable} ORDER BY id"""
+ // old planner do not support explode_json_object
+ test {
+ sql """ select /*+SET_VAR(experimental_enable_nereids_planner=false)*/
id, j, k,v from ${testTable} lateral view explode_json_object_outer(j) tmp as
k,v order by id; """
+ exception "errCode = 2"
+ }
+ test {
+ sql """ select /*+SET_VAR(experimental_enable_nereids_planner=false)*/
id, j, k,v from ${testTable} lateral view explode_json_object_outer(j) tmp as
k,v order by id; """
+ exception "errCode = 2"
+ }
// json_parse
qt_sql_json_parse """SELECT/*+SET_VAR(enable_fold_constant_by_be=false)*/
json_parse('{"":"v1"}')"""
qt_sql_json_parse """SELECT/*+SET_VAR(enable_fold_constant_by_be=false)*/
json_parse('{"":1, "":"v1"}')"""
diff --git
a/regression-test/suites/nereids_p0/jsonb_p0/test_jsonb_load_and_function.groovy
b/regression-test/suites/nereids_p0/jsonb_p0/test_jsonb_load_and_function.groovy
index d4baa081c4c..d44e81f8fa5 100644
---
a/regression-test/suites/nereids_p0/jsonb_p0/test_jsonb_load_and_function.groovy
+++
b/regression-test/suites/nereids_p0/jsonb_p0/test_jsonb_load_and_function.groovy
@@ -543,6 +543,10 @@ suite("test_jsonb_load_and_function", "p0") {
qt_select """SELECT id, j, JSON_EXTRACT(j, '\$.k2', null) FROM
${testTable} ORDER BY id"""
qt_select """SELECT id, j, JSON_EXTRACT(j, '\$.a1[0].k1', '\$.a1[0].k2',
'\$.a1[2]') FROM ${testTable} ORDER BY id"""
+ // explode_json_object function
+ order_qt_order_select_explode_json_object "select id, j, k,v from
${testTable} lateral view explode_json_object(j) tmp as k,v order by id, k;"
+ order_qt_order_select_explode_json_object_out "select id, j, k,v from
${testTable} lateral view explode_json_object_outer(j) tmp as k,v order by id,
k;"
+
// json_parse
qt_sql_json_parse """SELECT/*+SET_VAR(enable_fold_constant_by_be=false)*/
json_parse('{"":"v1"}')"""
qt_sql_json_parse """SELECT/*+SET_VAR(enable_fold_constant_by_be=false)*/
json_parse('{"":1, "":"v1"}')"""
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]