Skip to content

Commit aef0499

Browse files
authored
fix(query): fix variant get string function auto cast null to SQL NULL (#17466)
1 parent f6bcf03 commit aef0499

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

src/query/functions/src/scalars/variant.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,12 @@ pub fn register(registry: &mut FunctionRegistry) {
394394
}
395395
match get_by_name(val, name, false) {
396396
Some(v) => {
397-
let json_str = cast_to_string(&v);
398-
output.push(&json_str);
397+
if is_null(&v) {
398+
output.push_null();
399+
} else {
400+
let json_str = cast_to_string(&v);
401+
output.push(&json_str);
402+
}
399403
}
400404
None => output.push_null(),
401405
}
@@ -419,8 +423,12 @@ pub fn register(registry: &mut FunctionRegistry) {
419423
} else {
420424
match get_by_index(val, idx as usize) {
421425
Some(v) => {
422-
let json_str = cast_to_string(&v);
423-
output.push(&json_str);
426+
if is_null(&v) {
427+
output.push_null();
428+
} else {
429+
let json_str = cast_to_string(&v);
430+
output.push(&json_str);
431+
}
424432
}
425433
None => {
426434
output.push_null();
@@ -632,7 +640,7 @@ pub fn register(registry: &mut FunctionRegistry) {
632640
let mut out_offsets = Vec::new();
633641
match get_by_path(&buf, json_path, &mut out_buf, &mut out_offsets) {
634642
Ok(()) => {
635-
if out_offsets.is_empty() {
643+
if out_offsets.is_empty() || is_null(&out_buf) {
636644
output.push_null();
637645
} else {
638646
let json_str = cast_to_string(&out_buf);

src/query/functions/tests/it/scalars/testdata/variant.txt

+18
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,15 @@ output domain : {"{\"b\":2}"..="{\"b\":2}"}
900900
output : '{"b":2}'
901901

902902

903+
ast : json_extract_path_text('{"a":null}', 'a')
904+
raw expr : json_extract_path_text('{"a":null}', 'a')
905+
checked expr : json_extract_path_text<String, String>("{\"a\":null}", "a")
906+
optimized expr : NULL
907+
output type : String NULL
908+
output domain : {NULL}
909+
output : NULL
910+
911+
903912
ast : json_extract_path_text(s, k)
904913
raw expr : json_extract_path_text(s::String, k::String)
905914
checked expr : json_extract_path_text<String, String>(s, k)
@@ -3283,6 +3292,15 @@ output domain : {NULL}
32833292
output : NULL
32843293

32853294

3295+
ast : parse_json('{"k":null}')->>'k'
3296+
raw expr : get_string(parse_json('{"k":null}'), 'k')
3297+
checked expr : get_string<Variant, String>(parse_json<String>("{\"k\":null}"), "k")
3298+
optimized expr : NULL
3299+
output type : String NULL
3300+
output domain : {NULL}
3301+
output : NULL
3302+
3303+
32863304
ast : CAST(('a', 'b') AS VARIANT)->>'2'
32873305
raw expr : get_string(CAST(tuple('a', 'b') AS Variant), '2')
32883306
checked expr : get_string<Variant, String>(to_variant<T0=Tuple(String, String)><T0>(tuple<String, String>("a", "b")), "2")

src/query/functions/tests/it/scalars/variant.rs

+2
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ fn test_get_string_arrow_op(file: &mut impl Write) {
326326
run_ast(file, "parse_json('[1,2,3,4]')->>(2+3)", &[]);
327327
run_ast(file, "parse_json('{\"k\":\"v\"}')->>'k'", &[]);
328328
run_ast(file, "parse_json('{\"k\":\"v\"}')->>'x'", &[]);
329+
run_ast(file, "parse_json('{\"k\":null}')->>'k'", &[]);
329330
run_ast(file, "CAST(('a', 'b') AS VARIANT)->>'2'", &[]);
330331

331332
run_ast(file, "parse_json(s)->>i", &[
@@ -471,6 +472,7 @@ fn test_json_extract_path_text(file: &mut impl Write) {
471472
);
472473
run_ast(file, "json_extract_path_text('{\"a\":{\"b\":2}}', 'a')", &[
473474
]);
475+
run_ast(file, "json_extract_path_text('{\"a\":null}', 'a')", &[]);
474476

475477
run_ast(file, "json_extract_path_text(s, k)", &[
476478
(

tests/sqllogictests/suites/query/functions/02_0051_function_semi_structureds_get.test

+10-1
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,18 @@ NULL
9292
query T
9393
select parse_json('{"aa": null, "aA": 2, "Aa": 3}')->>'aa'
9494
----
95-
null
95+
NULL
9696

9797
query T
9898
select parse_json(null)->>'aa'
9999
----
100100
NULL
101101

102+
query T
103+
select parse_json('{"key1":null}')->>'key1'
104+
----
105+
NULL
106+
102107
query T
103108
select parse_json('[2.71, 3.14]')[0]
104109
----
@@ -201,6 +206,10 @@ select json_extract_path_text('{"customer":{"id": 1, "name":"databend", "extras"
201206
----
202207
{"customer":{"extras":["ext","test"],"id":1,"name":"databend"}}
203208

209+
query T
210+
select json_extract_path_text('{"attr":null}', 'attr')
211+
----
212+
NULL
204213

205214
query T
206215
select NULL#>'{0}'

0 commit comments

Comments
 (0)