Skip to content

Commit

Permalink
Add support for using negative array indices in json path
Browse files Browse the repository at this point in the history
This allows the use of negative array indices in json path to access elements from the end.

Test Plan:
Added unit tests
  • Loading branch information
bikramSingh91 committed Nov 6, 2024
1 parent c95f1e0 commit e8491fd
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
5 changes: 3 additions & 2 deletions velox/functions/prestosql/json/JsonExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,16 @@ void extractArray(
const folly::dynamic* jsonArray,
const std::string& key,
JsonVector& ret) {
auto arrayLen = jsonArray->size();
int64_t arrayLen = jsonArray->size();
if (key == "*") {
for (size_t i = 0; i < arrayLen; ++i) {
ret.push_back(jsonArray->get_ptr(i));
}
} else {
auto rv = folly::tryTo<int32_t>(key);
auto rv = folly::tryTo<int64_t>(key);
if (rv.hasValue()) {
auto idx = rv.value();
idx = idx >= 0 ? idx : arrayLen + idx;
if (idx >= 0 && idx < arrayLen) {
ret.push_back(jsonArray->get_ptr(idx));
}
Expand Down
16 changes: 16 additions & 0 deletions velox/functions/prestosql/json/tests/JsonExtractorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ TEST(JsonExtractorTest, arrayJsonValueTest) {
EXPECT_JSON_VALUE_EQ("[1, 2, 3]"s, "$[0]"s, "1"s);
EXPECT_JSON_VALUE_EQ("[1, 2]"s, "$[1]"s, "2"s);
EXPECT_JSON_VALUE_EQ("[1, null]"s, "$[1]"s, "null"s);
// Negative Index
EXPECT_JSON_VALUE_EQ("[1, 2, 3]"s, "$[-1]"s, "3"s);
EXPECT_JSON_VALUE_NULL("[1, 2, 3]"s, "$[-4]"s);
// Out of bounds
EXPECT_JSON_VALUE_NULL("[1]"s, "$[1]"s);
// Check skipping complex structures
Expand Down Expand Up @@ -412,6 +415,19 @@ TEST(JsonExtractorTest, fullJsonValueTest) {
"{\"15day\" : 0, \"30day\" : 1, \"90day\" : 2 }"s, "$[\"30day\"]"s, "1"s);
EXPECT_JSON_VALUE_EQ("{\"a\\\\b\": 4}"s, "$[\"a\\\\b\"]"s, "4"s);
EXPECT_JSON_VALUE_NULL("{\"fuu\" : null}"s, "$.a.b"s);

// Negative array index
EXPECT_JSON_VALUE_EQ(
"[{\"id\": 1, \"text\": \"First\"}, {\"id\": 2, \"text\": \"Second\"},"
"{\"id\": 3, \"text\": \"Last\"}]"s, "[-1][\"text\"]"s, "\"Last\""s);
EXPECT_JSON_VALUE_EQ(
"{\"id\": 1, \"entries\": [\"First\", \"Second\", \"Last\"]}"s,
"$.entries[-2]"s,
"\"Second\""s);
EXPECT_JSON_VALUE_EQ(
"{\"id\": 1, \"entries\": [\"First\", \"Second\", \"Last\"]}"s,
"$.entries.-3"s,
"\"First\""s);
}

TEST(JsonExtractorTest, invalidJsonPathTest) {
Expand Down

0 comments on commit e8491fd

Please sign in to comment.