diff --git a/be/src/vec/functions/function_jsonb.cpp b/be/src/vec/functions/function_jsonb.cpp index de2469a394ffa1..30761d13ab9cd2 100644 --- a/be/src/vec/functions/function_jsonb.cpp +++ b/be/src/vec/functions/function_jsonb.cpp @@ -793,7 +793,7 @@ struct JsonbExtractStringImpl { 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()) { diff --git a/be/test/vec/function/function_jsonb_test.cpp b/be/test/vec/function/function_jsonb_test.cpp index bb5cae7a0b6f36..0578ff685b889e 100644 --- a/be/test/vec/function/function_jsonb_test.cpp +++ b/be/test/vec/function/function_jsonb_test.cpp @@ -668,7 +668,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 @@ -752,7 +752,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]")}, @@ -1559,7 +1559,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 @@ -1643,7 +1643,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]")}, diff --git a/regression-test/data/json_p0/test_json_load_and_function.out b/regression-test/data/json_p0/test_json_load_and_function.out index aa8c6805696015..de25adfef2e758 100644 --- a/regression-test/data/json_p0/test_json_load_and_function.out +++ b/regression-test/data/json_p0/test_json_load_and_function.out @@ -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} diff --git a/regression-test/data/json_p0/test_json_load_unique_key_and_function.out b/regression-test/data/json_p0/test_json_load_unique_key_and_function.out index a0a12b2c2769f5..3a6a5ef057ab5a 100644 --- a/regression-test/data/json_p0/test_json_load_unique_key_and_function.out +++ b/regression-test/data/json_p0/test_json_load_unique_key_and_function.out @@ -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 diff --git a/regression-test/data/jsonb_p0/test_jsonb_load_and_function.out b/regression-test/data/jsonb_p0/test_jsonb_load_and_function.out index 83474e38b7fa2a..dbd756dab9d0bb 100644 --- a/regression-test/data/jsonb_p0/test_jsonb_load_and_function.out +++ b/regression-test/data/jsonb_p0/test_jsonb_load_and_function.out @@ -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 diff --git a/regression-test/data/jsonb_p0/test_jsonb_load_unique_key_and_function.out b/regression-test/data/jsonb_p0/test_jsonb_load_unique_key_and_function.out index c699a010fc885b..427b6426d6816f 100644 --- a/regression-test/data/jsonb_p0/test_jsonb_load_unique_key_and_function.out +++ b/regression-test/data/jsonb_p0/test_jsonb_load_unique_key_and_function.out @@ -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 diff --git a/regression-test/data/nereids_function_p0/scalar_function/J.out b/regression-test/data/nereids_function_p0/scalar_function/J.out index 41606ca51a741b..64a76e24826c10 100644 --- a/regression-test/data/nereids_function_p0/scalar_function/J.out +++ b/regression-test/data/nereids_function_p0/scalar_function/J.out @@ -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 diff --git a/regression-test/data/query_p0/sql_functions/json_functions/test_json_extract.out b/regression-test/data/query_p0/sql_functions/json_functions/test_json_extract.out new file mode 100644 index 00000000000000..1fe0d2a2b7e899 --- /dev/null +++ b/regression-test/data/query_p0/sql_functions/json_functions/test_json_extract.out @@ -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 + +-- !sql_string6 -- +\N + +-- !sql_string7 -- +\N + diff --git a/regression-test/suites/query_p0/sql_functions/json_functions/test_json_extract.groovy b/regression-test/suites/query_p0/sql_functions/json_functions/test_json_extract.groovy new file mode 100644 index 00000000000000..46a2009a6f8827 --- /dev/null +++ b/regression-test/suites/query_p0/sql_functions/json_functions/test_json_extract.groovy @@ -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: \$." + } +}