This is an automated email from the ASF dual-hosted git repository.
eldenmoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 4572b5997a1 [Fix](Variant) fix variant cast to jsonb into wrong NULL
values (#50180)
4572b5997a1 is described below
commit 4572b5997a1f6797a1d03b51bd8fcd2998cbd4dc
Author: lihangyu <[email protected]>
AuthorDate: Mon Apr 21 15:34:16 2025 +0800
[Fix](Variant) fix variant cast to jsonb into wrong NULL values (#50180)
1. implement cast to jsonb in `ConvertImplGenericFromVariant`
2. implement `DataTypeObjectSerDe::serialize_column_to_json`
---
.../data_types/serde/data_type_object_serde.cpp | 6 +++
.../vec/data_types/serde/data_type_object_serde.h | 5 +-
be/src/vec/functions/function_cast.h | 15 ++++--
regression-test/data/variant_p0/cast.out | Bin 0 -> 247 bytes
regression-test/suites/variant_p0/cast.groovy | 60 +++++++++++++++++++++
5 files changed, 79 insertions(+), 7 deletions(-)
diff --git a/be/src/vec/data_types/serde/data_type_object_serde.cpp
b/be/src/vec/data_types/serde/data_type_object_serde.cpp
index fc536d9ef0d..c450ee60e27 100644
--- a/be/src/vec/data_types/serde/data_type_object_serde.cpp
+++ b/be/src/vec/data_types/serde/data_type_object_serde.cpp
@@ -87,6 +87,12 @@ Status DataTypeObjectSerDe::write_column_to_mysql(const
IColumn& column,
return _write_column_to_mysql(column, row_buffer, row_idx, col_const,
options);
}
+Status DataTypeObjectSerDe::serialize_column_to_json(const IColumn& column,
int64_t start_idx,
+ int64_t end_idx,
BufferWritable& bw,
+ FormatOptions& options)
const {
+ SERIALIZE_COLUMN_TO_JSON();
+}
+
void DataTypeObjectSerDe::write_one_cell_to_jsonb(const IColumn& column,
JsonbWriter& result,
Arena* mem_pool, int32_t
col_id,
int64_t row_num) const {
diff --git a/be/src/vec/data_types/serde/data_type_object_serde.h
b/be/src/vec/data_types/serde/data_type_object_serde.h
index 4ba144760fb..61545ddcc3c 100644
--- a/be/src/vec/data_types/serde/data_type_object_serde.h
+++ b/be/src/vec/data_types/serde/data_type_object_serde.h
@@ -42,9 +42,8 @@ public:
FormatOptions& options) const override;
Status serialize_column_to_json(const IColumn& column, int64_t start_idx,
int64_t end_idx,
- BufferWritable& bw, FormatOptions&
options) const override {
- return Status::NotSupported("serialize_column_to_json with type [{}]",
column.get_name());
- }
+ BufferWritable& bw, FormatOptions&
options) const override;
+
Status deserialize_one_cell_from_json(IColumn& column, Slice& slice,
const FormatOptions& options) const
override {
return Status::NotSupported("deserialize_one_cell_from_text with type
" +
diff --git a/be/src/vec/functions/function_cast.h
b/be/src/vec/functions/function_cast.h
index 041c3224862..f064b5c9494 100644
--- a/be/src/vec/functions/function_cast.h
+++ b/be/src/vec/functions/function_cast.h
@@ -1793,7 +1793,8 @@ private:
variant.is_scalar_variant() ||
(!variant.is_null_root() &&
!WhichDataType(remove_nullable(variant.get_root_type())).is_nothing() &&
- !WhichDataType(data_type_to).is_string());
+ !WhichDataType(data_type_to).is_string() &&
+ !WhichDataType(data_type_to).is_json());
if (is_root_valuable) {
ColumnPtr nested = variant.get_root();
auto nested_from_type = variant.get_root_type();
@@ -1825,13 +1826,19 @@ private:
// TODO not found root cause, a tmp fix
col_to->assume_mutable()->insert_many_defaults(input_rows_count);
col_to = make_nullable(col_to, true);
+ } else if (WhichDataType(data_type_to).is_string()) {
+ // serialize to string
+ return ConvertImplGenericToString::execute2(context,
block, arguments, result,
+
input_rows_count);
+ } else if (WhichDataType(data_type_to).is_json()) {
+ // serialize to json by parsing
+ return ConvertImplGenericToJsonb::execute(context, block,
arguments, result,
+
input_rows_count);
} else if (!data_type_to->is_nullable() &&
!WhichDataType(data_type_to).is_string()) {
+ // other types
col_to->assume_mutable()->insert_many_defaults(input_rows_count);
col_to = make_nullable(col_to, true);
- } else if (WhichDataType(data_type_to).is_string()) {
- return ConvertImplGenericToString::execute2(context,
block, arguments, result,
-
input_rows_count);
} else {
assert_cast<ColumnNullable&>(*col_to->assume_mutable())
.insert_many_defaults(input_rows_count);
diff --git a/regression-test/data/variant_p0/cast.out
b/regression-test/data/variant_p0/cast.out
new file mode 100644
index 00000000000..7ceb039ea71
Binary files /dev/null and b/regression-test/data/variant_p0/cast.out differ
diff --git a/regression-test/suites/variant_p0/cast.groovy
b/regression-test/suites/variant_p0/cast.groovy
new file mode 100644
index 00000000000..76c4c134d61
--- /dev/null
+++ b/regression-test/suites/variant_p0/cast.groovy
@@ -0,0 +1,60 @@
+// 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.
+
+import org.codehaus.groovy.runtime.IOGroovyMethods
+
+suite("test_variant_cast", "p0") {
+ qt_sql1 """select cast(cast('{"a" : 1}' as variant) as jsonb);"""
+ qt_sql2 """select json_type(cast(cast('{"a" : 1}' as variant) as jsonb),
"\$.a");"""
+ sql "DROP TABLE IF EXISTS var_cast"
+ sql """
+ CREATE TABLE `var_cast` (
+ `k` int NULL,
+ `var` variant NULL
+ ) ENGINE=OLAP
+ UNIQUE KEY(`k`)
+ DISTRIBUTED BY HASH(k) BUCKETS 1
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+ );
+ """
+ sql """insert into var_cast values (1, '{"aaa" : 1}')"""
+ qt_sql3 "select cast(var as json) from var_cast"
+ sql """insert into var_cast values (1, '[1]')"""
+ qt_sql4 "select cast(var as json) from var_cast"
+ sql """insert into var_cast values (1, '123')"""
+ qt_sql5 "select cast(var as json) from var_cast"
+
+ sql "DROP TABLE IF EXISTS var_not_null_cast"
+ sql """
+ CREATE TABLE `var_not_null_cast` (
+ `k` int NULL,
+ `var` variant NOT NULL
+ ) ENGINE=OLAP
+ UNIQUE KEY(`k`)
+ DISTRIBUTED BY HASH(k) BUCKETS 1
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+ );
+ """
+ sql """insert into var_not_null_cast values (1, '{"aaa" : 1}')"""
+ qt_sql6 "select cast(var as json) from var_not_null_cast"
+ sql """insert into var_not_null_cast values (1, '[1]')"""
+ qt_sql7 "select cast(var as json) from var_not_null_cast"
+ sql """insert into var_not_null_cast values (1, '123')"""
+ qt_sql8 "select cast(var as json) from var_not_null_cast"
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]