Skip to content

Commit 4572b59

Browse files
authored
[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`
1 parent 2ec0eed commit 4572b59

5 files changed

Lines changed: 104 additions & 7 deletions

File tree

be/src/vec/data_types/serde/data_type_object_serde.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ Status DataTypeObjectSerDe::write_column_to_mysql(const IColumn& column,
8787
return _write_column_to_mysql(column, row_buffer, row_idx, col_const, options);
8888
}
8989

90+
Status DataTypeObjectSerDe::serialize_column_to_json(const IColumn& column, int64_t start_idx,
91+
int64_t end_idx, BufferWritable& bw,
92+
FormatOptions& options) const {
93+
SERIALIZE_COLUMN_TO_JSON();
94+
}
95+
9096
void DataTypeObjectSerDe::write_one_cell_to_jsonb(const IColumn& column, JsonbWriter& result,
9197
Arena* mem_pool, int32_t col_id,
9298
int64_t row_num) const {

be/src/vec/data_types/serde/data_type_object_serde.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ class DataTypeObjectSerDe : public DataTypeSerDe {
4242
FormatOptions& options) const override;
4343

4444
Status serialize_column_to_json(const IColumn& column, int64_t start_idx, int64_t end_idx,
45-
BufferWritable& bw, FormatOptions& options) const override {
46-
return Status::NotSupported("serialize_column_to_json with type [{}]", column.get_name());
47-
}
45+
BufferWritable& bw, FormatOptions& options) const override;
46+
4847
Status deserialize_one_cell_from_json(IColumn& column, Slice& slice,
4948
const FormatOptions& options) const override {
5049
return Status::NotSupported("deserialize_one_cell_from_text with type " +

be/src/vec/functions/function_cast.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,7 +1793,8 @@ class FunctionCast final : public IFunctionBase {
17931793
variant.is_scalar_variant() ||
17941794
(!variant.is_null_root() &&
17951795
!WhichDataType(remove_nullable(variant.get_root_type())).is_nothing() &&
1796-
!WhichDataType(data_type_to).is_string());
1796+
!WhichDataType(data_type_to).is_string() &&
1797+
!WhichDataType(data_type_to).is_json());
17971798
if (is_root_valuable) {
17981799
ColumnPtr nested = variant.get_root();
17991800
auto nested_from_type = variant.get_root_type();
@@ -1825,13 +1826,19 @@ class FunctionCast final : public IFunctionBase {
18251826
// TODO not found root cause, a tmp fix
18261827
col_to->assume_mutable()->insert_many_defaults(input_rows_count);
18271828
col_to = make_nullable(col_to, true);
1829+
} else if (WhichDataType(data_type_to).is_string()) {
1830+
// serialize to string
1831+
return ConvertImplGenericToString::execute2(context, block, arguments, result,
1832+
input_rows_count);
1833+
} else if (WhichDataType(data_type_to).is_json()) {
1834+
// serialize to json by parsing
1835+
return ConvertImplGenericToJsonb::execute(context, block, arguments, result,
1836+
input_rows_count);
18281837
} else if (!data_type_to->is_nullable() &&
18291838
!WhichDataType(data_type_to).is_string()) {
1839+
// other types
18301840
col_to->assume_mutable()->insert_many_defaults(input_rows_count);
18311841
col_to = make_nullable(col_to, true);
1832-
} else if (WhichDataType(data_type_to).is_string()) {
1833-
return ConvertImplGenericToString::execute2(context, block, arguments, result,
1834-
input_rows_count);
18351842
} else {
18361843
assert_cast<ColumnNullable&>(*col_to->assume_mutable())
18371844
.insert_many_defaults(input_rows_count);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-- This file is automatically generated. You should know what you did if you want to edit this
2+
-- !sql1 --
3+
{"a":1}
4+
5+
-- !sql2 --
6+
int
7+
8+
-- !sql3 --
9+
{"aaa":1}
10+
11+
-- !sql4 --
12+
[1]
13+
14+
-- !sql5 --
15+
123
16+
17+
-- !sql6 --
18+
{"aaa":1}
19+
20+
-- !sql7 --
21+
[1]
22+
23+
-- !sql8 --
24+
123
25+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
import org.codehaus.groovy.runtime.IOGroovyMethods
19+
20+
suite("test_variant_cast", "p0") {
21+
qt_sql1 """select cast(cast('{"a" : 1}' as variant) as jsonb);"""
22+
qt_sql2 """select json_type(cast(cast('{"a" : 1}' as variant) as jsonb), "\$.a");"""
23+
sql "DROP TABLE IF EXISTS var_cast"
24+
sql """
25+
CREATE TABLE `var_cast` (
26+
`k` int NULL,
27+
`var` variant NULL
28+
) ENGINE=OLAP
29+
UNIQUE KEY(`k`)
30+
DISTRIBUTED BY HASH(k) BUCKETS 1
31+
PROPERTIES (
32+
"replication_allocation" = "tag.location.default: 1"
33+
);
34+
"""
35+
sql """insert into var_cast values (1, '{"aaa" : 1}')"""
36+
qt_sql3 "select cast(var as json) from var_cast"
37+
sql """insert into var_cast values (1, '[1]')"""
38+
qt_sql4 "select cast(var as json) from var_cast"
39+
sql """insert into var_cast values (1, '123')"""
40+
qt_sql5 "select cast(var as json) from var_cast"
41+
42+
sql "DROP TABLE IF EXISTS var_not_null_cast"
43+
sql """
44+
CREATE TABLE `var_not_null_cast` (
45+
`k` int NULL,
46+
`var` variant NOT NULL
47+
) ENGINE=OLAP
48+
UNIQUE KEY(`k`)
49+
DISTRIBUTED BY HASH(k) BUCKETS 1
50+
PROPERTIES (
51+
"replication_allocation" = "tag.location.default: 1"
52+
);
53+
"""
54+
sql """insert into var_not_null_cast values (1, '{"aaa" : 1}')"""
55+
qt_sql6 "select cast(var as json) from var_not_null_cast"
56+
sql """insert into var_not_null_cast values (1, '[1]')"""
57+
qt_sql7 "select cast(var as json) from var_not_null_cast"
58+
sql """insert into var_not_null_cast values (1, '123')"""
59+
qt_sql8 "select cast(var as json) from var_not_null_cast"
60+
}

0 commit comments

Comments
 (0)