Skip to content

Commit

Permalink
Add support for using negative array indices in json path (facebookin…
Browse files Browse the repository at this point in the history
…cubator#11451)

Summary:
This allows the use of negative array indices in json path to access
elements from the end.

Pull Request resolved: facebookincubator#11451

Test Plan: Added unit tests

Reviewed By: kgpai

Differential Revision: D65553507

Pulled By: bikramSingh91

fbshipit-source-id: e00d49cf7c3453137b00384024be7a89e5168357
  • Loading branch information
bikramSingh91 authored and facebook-github-bot committed Nov 7, 2024
1 parent 789ce65 commit d1bf9da
Show file tree
Hide file tree
Showing 2 changed files with 21 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
18 changes: 18 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,21 @@ 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 d1bf9da

Please sign in to comment.