Skip to content

Commit a8365ff

Browse files
mrhhsgYour Name
authored and
Your Name
committed
[fix](function) JSON_EXTRACT_STRING should return NULL instead of the string 'null' when encountering a NULL value (#51516)
### What problem does this PR solve? Previously, when JSON_EXTRACT_STRING encountered a NULL input value or path, it returned the string "null" instead of a proper SQL NULL value. This behavior could lead to incorrect query results and confusion in downstream processing that expects NULL to be represented as an actual null value rather than a literal string. This commit adjusts the logic to ensure that JSON_EXTRACT_STRING returns NULL in such cases, aligning with SQL semantics and improving compatibility with systems that rely on strict null-handling behavior.
1 parent ae1d1cc commit a8365ff

File tree

9 files changed

+70
-17
lines changed

9 files changed

+70
-17
lines changed

be/src/vec/functions/function_jsonb.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ struct JsonbExtractStringImpl {
793793
std::string_view(str_value->getBlob(), str_value->length()), i, res_data,
794794
res_offsets);
795795
} else if (value->isNull()) {
796-
StringOP::push_value_string("null", i, res_data, res_offsets);
796+
StringOP::push_null_string(i, res_data, res_offsets, null_map);
797797
} else if (value->isTrue()) {
798798
StringOP::push_value_string("true", i, res_data, res_offsets);
799799
} else if (value->isFalse()) {

be/test/vec/function/function_jsonb_test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ TEST(FunctionJsonbTEST, JsonbExtractStringTest) {
667667
// json_extract root
668668
DataSet data_set = {
669669
{{Null(), STRING("$")}, Null()},
670-
{{STRING("null"), STRING("$")}, STRING("null")},
670+
{{STRING("null"), STRING("$")}, Null()},
671671
{{STRING("true"), STRING("$")}, STRING("true")},
672672
{{STRING("false"), STRING("$")}, STRING("false")},
673673
{{STRING("100"), STRING("$")}, STRING("100")}, //int8
@@ -751,7 +751,7 @@ TEST(FunctionJsonbTEST, JsonbExtractStringTest) {
751751
{{STRING(R"(["abc", "def"])"), STRING("$[1]")}, STRING("def")}, // string array
752752
{{STRING(R"(["abc", "def"])"), STRING("$[2]")}, Null()}, // string array
753753
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[0]")},
754-
STRING("null")}, // multi type array
754+
Null()}, // multi type array
755755
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[1]")},
756756
STRING("true")}, // multi type array
757757
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[2]")},
@@ -1521,7 +1521,7 @@ TEST(FunctionJsonbTEST, GetJSONSTRINGTest) {
15211521
// get json from root
15221522
DataSet data_set = {
15231523
{{Null(), STRING("$")}, Null()},
1524-
{{STRING("null"), STRING("$")}, STRING("null")},
1524+
{{STRING("null"), STRING("$")}, Null()},
15251525
{{STRING("true"), STRING("$")}, STRING("true")},
15261526
{{STRING("false"), STRING("$")}, STRING("false")},
15271527
{{STRING("100"), STRING("$")}, STRING("100")}, //int8
@@ -1605,7 +1605,7 @@ TEST(FunctionJsonbTEST, GetJSONSTRINGTest) {
16051605
{{STRING(R"(["abc", "def"])"), STRING("$[1]")}, STRING("def")}, // string array
16061606
{{STRING(R"(["abc", "def"])"), STRING("$[2]")}, Null()}, // string array
16071607
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[0]")},
1608-
STRING("null")}, // multi type array
1608+
Null()}, // multi type array
16091609
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[1]")},
16101610
STRING("true")}, // multi type array
16111611
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[2]")},

regression-test/data/json_p0/test_json_load_and_function.out

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@
783783

784784
-- !select --
785785
1 \N \N
786-
2 null null
786+
2 null \N
787787
3 true true
788788
4 false false
789789
5 100 100
@@ -884,7 +884,7 @@
884884
13 [] \N
885885
14 [123,456] 123
886886
15 ["abc","def"] abc
887-
16 [null,true,false,100,6.18,"abc"] null
887+
16 [null,true,false,100,6.18,"abc"] \N
888888
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
889889
18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]}
890890
26 \N \N
@@ -7023,7 +7023,7 @@ false
70237023
34 {"":1,"ab":"v1"," ":"v1"," ":2} \N
70247024

70257025
-- !select --
7026-
2 null null
7026+
2 null \N
70277027
3 true true
70287028
4 false false
70297029
5 100 100
@@ -7118,7 +7118,7 @@ false
71187118
13 [] \N
71197119
14 [123,456] 123
71207120
15 ["abc","def"] abc
7121-
16 [null,true,false,100,6.18,"abc"] null
7121+
16 [null,true,false,100,6.18,"abc"] \N
71227122
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
71237123
18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]}
71247124
27 {"k1":"v1","k2":200} {"k1":"v1","k2":200}

regression-test/data/json_p0/test_json_load_unique_key_and_function.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@
619619

620620
-- !select --
621621
1 \N \N
622-
2 null null
622+
2 null \N
623623
3 true true
624624
4 false false
625625
5 100 100
@@ -702,7 +702,7 @@
702702
13 [] \N
703703
14 [123,456] 123
704704
15 ["abc","def"] abc
705-
16 [null,true,false,100,6.18,"abc"] null
705+
16 [null,true,false,100,6.18,"abc"] \N
706706
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
707707
18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]}
708708
26 \N \N

regression-test/data/jsonb_p0/test_jsonb_load_and_function.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@
925925

926926
-- !jsonb_extract_string_select --
927927
1 \N \N
928-
2 null null
928+
2 null \N
929929
3 true true
930930
4 false false
931931
5 100 100
@@ -1026,7 +1026,7 @@
10261026
13 [] \N
10271027
14 [123,456] 123
10281028
15 ["abc","def"] abc
1029-
16 [null,true,false,100,6.18,"abc"] null
1029+
16 [null,true,false,100,6.18,"abc"] \N
10301030
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
10311031
18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]}
10321032
26 \N \N

regression-test/data/jsonb_p0/test_jsonb_load_unique_key_and_function.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@
734734

735735
-- !jsonb_extract_string_select --
736736
1 \N \N
737-
2 null null
737+
2 null \N
738738
3 true true
739739
4 false false
740740
5 100 100
@@ -817,7 +817,7 @@
817817
13 [] \N
818818
14 [123,456] 123
819819
15 ["abc","def"] abc
820-
16 [null,true,false,100,6.18,"abc"] null
820+
16 [null,true,false,100,6.18,"abc"] \N
821821
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
822822
18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]}
823823
26 \N \N

regression-test/data/nereids_function_p0/scalar_function/J.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@
827827

828828
-- !jsonb_extract_string_select --
829829
1 \N \N
830-
2 null null
830+
2 null \N
831831
3 true true
832832
4 false false
833833
5 100 100
@@ -919,7 +919,7 @@
919919
13 [] \N
920920
14 [123,456] 123
921921
15 ["abc","def"] abc
922-
16 [null,true,false,100,6.18,"abc"] null
922+
16 [null,true,false,100,6.18,"abc"] \N
923923
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
924924
18 {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]} {"k1":"v31","k2":300,"a1":[{"k1":"v41","k2":400},1,"a",3.14]}
925925
26 \N \N
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-- This file is automatically generated. You should know what you did if you want to edit this
2+
-- !sql_string1 --
3+
v31
4+
5+
-- !sql_string2 --
6+
\N
7+
8+
-- !sql_string3 --
9+
\N
10+
11+
-- !sql_string4 --
12+
1234.56
13+
14+
-- !sql_string5 --
15+
2025-06-05 14:47:01
16+
17+
-- !sql_string6 --
18+
\N
19+
20+
-- !sql_string7 --
21+
\N
22+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
suite("test_json_extract") {
19+
qt_sql_string1 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2":300}', '\$.k1'); """
20+
qt_sql_string2 """ SELECT JSON_EXTRACT_STRING(null, '\$.k1'); """
21+
qt_sql_string3 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2":300}', NULL); """
22+
qt_sql_string4 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2":{"sub_key": 1234.56}}', '\$.k2.sub_key'); """
23+
qt_sql_string5 """ SELECT JSON_EXTRACT_STRING(json_array("abc", 123, STR_TO_DATE('2025-06-05 14:47:01', '%Y-%m-%d %H:%i:%s')), '\$.[2]'); """
24+
qt_sql_string6 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2": null}', '\$.k2'); """
25+
qt_sql_string7 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2":300}', '\$.k3'); """
26+
27+
test {
28+
sql """ SELECT JSON_EXTRACT_STRING('{"id": 123, "name": "doris"}', '\$.'); """
29+
exception "Invalid Json Path for value: \$."
30+
}
31+
}

0 commit comments

Comments
 (0)