branch-2.1: [fix](function) JSON_EXTRACT_STRING should return NULL instead of the string 'null' when encountering a NULL value #51516 (#51566)

Cherry-picked from #51516

---------

Co-authored-by: Jerry Hu <hushenggang@selectdb.com>
This commit is contained in:
github-actions[bot]
2025-06-13 11:07:31 +08:00
committed by GitHub
parent ec0af70215
commit 18d2f93120
13 changed files with 78 additions and 25 deletions

View File

@ -793,7 +793,7 @@ private:
std::string_view(str_value->getBlob(), str_value->length()), i, res_data,
res_offsets);
} else if (value->isNull()) {
StringOP::push_value_string("null", i, res_data, res_offsets);
StringOP::push_null_string(i, res_data, res_offsets, null_map);
} else if (value->isTrue()) {
StringOP::push_value_string("true", i, res_data, res_offsets);
} else if (value->isFalse()) {

View File

@ -667,7 +667,7 @@ TEST(FunctionJsonbTEST, JsonbExtractStringTest) {
// json_extract root
DataSet data_set = {
{{Null(), STRING("$")}, Null()},
{{STRING("null"), STRING("$")}, STRING("null")},
{{STRING("null"), STRING("$")}, Null()},
{{STRING("true"), STRING("$")}, STRING("true")},
{{STRING("false"), STRING("$")}, STRING("false")},
{{STRING("100"), STRING("$")}, STRING("100")}, //int8
@ -751,7 +751,7 @@ TEST(FunctionJsonbTEST, JsonbExtractStringTest) {
{{STRING(R"(["abc", "def"])"), STRING("$[1]")}, STRING("def")}, // string array
{{STRING(R"(["abc", "def"])"), STRING("$[2]")}, Null()}, // string array
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[0]")},
STRING("null")}, // multi type array
Null()}, // multi type array
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[1]")},
STRING("true")}, // multi type array
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[2]")},
@ -1298,7 +1298,7 @@ TEST(FunctionJsonbTEST, GetJSONSTRINGTest) {
// get json from root
DataSet data_set = {
{{Null(), STRING("$")}, Null()},
{{STRING("null"), STRING("$")}, STRING("null")},
{{STRING("null"), STRING("$")}, Null()},
{{STRING("true"), STRING("$")}, STRING("true")},
{{STRING("false"), STRING("$")}, STRING("false")},
{{STRING("100"), STRING("$")}, STRING("100")}, //int8
@ -1382,7 +1382,7 @@ TEST(FunctionJsonbTEST, GetJSONSTRINGTest) {
{{STRING(R"(["abc", "def"])"), STRING("$[1]")}, STRING("def")}, // string array
{{STRING(R"(["abc", "def"])"), STRING("$[2]")}, Null()}, // string array
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[0]")},
STRING("null")}, // multi type array
Null()}, // multi type array
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[1]")},
STRING("true")}, // multi type array
{{STRING(R"([null, true, false, 100, 6.18, "abc"])"), STRING("$[2]")},

View File

@ -783,7 +783,7 @@
-- !select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -884,7 +884,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N
@ -7023,7 +7023,7 @@ false
34 {"":1,"ab":"v1","":"v1","":2} \N
-- !select --
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -7118,7 +7118,7 @@ false
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
27 {"k1":"v1","k2":200} {"k1":"v1","k2":200}

View File

@ -619,7 +619,7 @@
-- !select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -702,7 +702,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N

View File

@ -925,7 +925,7 @@
-- !jsonb_extract_string_select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -1026,7 +1026,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N

View File

@ -734,7 +734,7 @@
-- !jsonb_extract_string_select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -817,7 +817,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N

View File

@ -827,7 +827,7 @@
-- !jsonb_extract_string_select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -919,7 +919,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N

View File

@ -780,7 +780,7 @@
-- !select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -881,7 +881,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N

View File

@ -619,7 +619,7 @@
-- !select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -702,7 +702,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N

View File

@ -925,7 +925,7 @@
-- !jsonb_extract_string_select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -1026,7 +1026,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N

View File

@ -734,7 +734,7 @@
-- !jsonb_extract_string_select --
1 \N \N
2 null null
2 null \N
3 true true
4 false false
5 100 100
@ -817,7 +817,7 @@
13 [] \N
14 [123,456] 123
15 ["abc","def"] abc
16 [null,true,false,100,6.18,"abc"] null
16 [null,true,false,100,6.18,"abc"] \N
17 [{"k1":"v41","k2":400},1,"a",3.14] {"k1":"v41","k2":400}
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]}
26 \N \N

View File

@ -0,0 +1,22 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !sql_string1 --
v31
-- !sql_string2 --
\N
-- !sql_string3 --
\N
-- !sql_string4 --
1234.56
-- !sql_string5 --
2025-06-05 14:47:01.000000
-- !sql_string6 --
\N
-- !sql_string7 --
\N

View File

@ -0,0 +1,31 @@
// 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.
suite("test_json_extract") {
qt_sql_string1 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2":300}', '\$.k1'); """
qt_sql_string2 """ SELECT JSON_EXTRACT_STRING(null, '\$.k1'); """
qt_sql_string3 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2":300}', NULL); """
qt_sql_string4 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2":{"sub_key": 1234.56}}', '\$.k2.sub_key'); """
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]'); """
qt_sql_string6 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2": null}', '\$.k2'); """
qt_sql_string7 """ SELECT JSON_EXTRACT_STRING('{"k1":"v31","k2":300}', '\$.k3'); """
test {
sql """ SELECT JSON_EXTRACT_STRING('{"id": 123, "name": "doris"}', '\$.'); """
exception "Invalid Json Path for value: \$."
}
}