Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions cpp/src/json/json_path.cu
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ class json_state : private parser {
* The user can specify whether or not the name string must be present via
* the `can_be_empty` flag.
*
* When a name is present, it must be followed by a colon `:`
* When a name is present, it must be followed by a colon `:`. A present but zero-length
* name (the `""` key of `{"":1}`) is not an absent name.
*
* @param[out] name The resulting name.
* @param can_be_empty Parameter indicating whether it is valid for the name
Expand All @@ -366,17 +367,16 @@ class json_state : private parser {
{
char const quote = options.get_allow_single_quotes() ? 0 : '\"';

if (parse_string(name, can_be_empty, quote) == parse_result::ERROR) {
return parse_result::ERROR;
if (auto const result = parse_string(name, can_be_empty, quote);
result != parse_result::SUCCESS) {
return result;
}

// if we got a real string, the next char must be a :
if (name.size_bytes() > 0) {
if (!parse_whitespace()) { return parse_result::ERROR; }
if (*pos == ':') {
pos++;
return parse_result::SUCCESS;
}
// a name is present, so the next char must be a :
if (!parse_whitespace()) { return parse_result::ERROR; }
if (*pos == ':') {
pos++;
return parse_result::SUCCESS;
}
return parse_result::EMPTY;
}
Expand Down
17 changes: 16 additions & 1 deletion cpp/tests/json/json_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021-2026, NVIDIA CORPORATION.
* SPDX-FileCopyrightText: Copyright (c) 2021-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

Expand Down Expand Up @@ -1044,6 +1044,21 @@ TEST_F(JsonPathTests, QueriesContainingQuotes)
do_test(R"($.'A)", R"({"B'": 3})");
}

TEST_F(JsonPathTests, ObjectWithEmptyKey)
{
auto const input = cudf::test::strings_column_wrapper{R"({"":0,"a":1})",
R"({"a":1,"":0})",
R"({"" : 0, "a" : 1})",
R"({"":{"a":9},"a":1})",
R"({"":[1,2],"a":1})",
R"({"":"s","a":1})"};

auto const result =
cudf::get_json_object(cudf::strings_column_view(input), std::string_view{"$.a"});
auto const expected = cudf::test::strings_column_wrapper{"1", "1", "1", "1", "1", "1"};
CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(*result, expected);
}

// Test that get_json_object creates valid string columns for empty/whitespace JSONPath queries
TEST_F(JsonPathTests, EmptyPathCreatesValidColumn)
{
Expand Down
Loading