Skip to content

Commit 4750f8d

Browse files
authored
fix: jsonPath parser for int values (#5737)
* fix: jsonPath parser for int values
1 parent a67c2ab commit 4750f8d

File tree

4 files changed

+43
-16
lines changed

4 files changed

+43
-16
lines changed

src/core/json/jsonpath_grammar.y

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,19 @@
2525

2626
#include "src/core/json/lexer_impl.h"
2727
#include "src/core/json/driver.h"
28+
#include <absl/strings/numbers.h>
29+
#include "base/logging.h"
2830

2931
#define yylex driver->lexer()->Lex
3032

3133
using namespace std;
34+
35+
static int unsafe_stoi(std::string_view s) {
36+
int value;
37+
bool success = absl::SimpleAtoi(s, &value);
38+
DCHECK(success);
39+
return value;
40+
}
3241
}
3342

3443
%parse-param { Driver *driver }
@@ -56,7 +65,7 @@ using namespace std;
5665
// Needed 0 at the end to satisfy bison 3.5.1
5766
%token YYEOF 0
5867
%token <std::string> UNQ_STR "unquoted string"
59-
%token <int> INT "integer"
68+
%token <std::string> INT "integer"
6069

6170
%nterm <std::string> identifier
6271
%nterm <PathSegment> bracket_index
@@ -84,23 +93,28 @@ relative_path: identifier { driver->AddIdentifier($1); } opt_relative_location
8493
| bracket_expr
8594

8695
identifier: UNQ_STR
96+
| INT
8797

8898
bracket_expr: LBRACKET bracket_index RBRACKET { driver->AddSegment($2); } opt_relative_location
8999

90100
bracket_index: single_quoted_string { $$ = PathSegment(SegmentType::IDENTIFIER, $1); }
91101
| double_quoted_string { $$ = PathSegment(SegmentType::IDENTIFIER, $1); }
92102
| WILDCARD { $$ = PathSegment{SegmentType::INDEX, IndexExpr::All()}; }
93-
| INT { $$ = PathSegment(SegmentType::INDEX, IndexExpr($1, $1)); }
94-
| INT COLON INT { $$ = PathSegment(SegmentType::INDEX, IndexExpr::HalfOpen($1, $3)); }
95-
| INT COLON { $$ = PathSegment(SegmentType::INDEX, IndexExpr($1, INT_MAX)); }
96-
| COLON INT { $$ = PathSegment(SegmentType::INDEX, IndexExpr::HalfOpen(0, $2)); }
103+
| INT { int tmp_idx = unsafe_stoi($1);
104+
$$ = PathSegment(SegmentType::INDEX, IndexExpr(tmp_idx, tmp_idx)); }
105+
| INT COLON INT { $$ = PathSegment(SegmentType::INDEX, IndexExpr::HalfOpen(
106+
unsafe_stoi($1), unsafe_stoi($3))); }
107+
| INT COLON { $$ = PathSegment(SegmentType::INDEX, IndexExpr(unsafe_stoi($1), INT_MAX)); }
108+
| COLON INT { $$ = PathSegment(SegmentType::INDEX, IndexExpr::HalfOpen(0, unsafe_stoi($2))); }
97109

98110
single_quoted_string: SINGLE_QUOTE quoted_content SINGLE_QUOTE { $$ = $2; }
99111

100112
double_quoted_string: DOUBLE_QUOTE quoted_content DOUBLE_QUOTE { $$ = $2; }
101113

102114
quoted_content: UNQ_STR { $$ = $1; }
115+
| INT { $$ = $1; }
103116
| quoted_content DOT UNQ_STR { $$ = $1 + "." + $3; }
117+
| quoted_content DOT INT { $$ = $1 + "." + $3; }
104118

105119
function_expr: UNQ_STR { driver->AddFunction($1); } LPARENT ROOT relative_location RPARENT
106120
%%

src/core/json/jsonpath_lexer.lex

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44
}
55

66

7-
%{
8-
#include <absl/strings/numbers.h>
9-
#include "base/logging.h"
10-
%}
11-
127
%o bison-cc-namespace="dfly.json" bison-cc-parser="Parser"
138
%o namespace="dfly.json"
149

@@ -53,11 +48,7 @@
5348
")" return Parser::make_RPARENT(loc());
5449
"'" return Parser::make_SINGLE_QUOTE(loc());
5550
"\"" return Parser::make_DOUBLE_QUOTE(loc());
56-
-?[0-9]{1,9} {
57-
int val;
58-
CHECK(absl::SimpleAtoi(str(), &val));
59-
return Parser::make_INT(val, loc());
60-
}
51+
-?[0-9]{1,9} return Parser::make_INT(str(), loc());
6152

6253
[\w_\-]+ return Parser::make_UNQ_STR(str(), loc());
6354
<<EOF>> return Parser::make_YYEOF(loc());

src/core/json/jsonpath_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ TEST_F(ScannerTest, Basic) {
144144
NEXT_TOK(DOT);
145145
NEXT_EQ(UNQ_STR, string, "book");
146146
NEXT_TOK(LBRACKET);
147-
NEXT_EQ(INT, int, 0);
147+
NEXT_EQ(INT, string, "0");
148148
NEXT_TOK(RBRACKET);
149149
NEXT_TOK(DOT);
150150
NEXT_TOK(WILDCARD);

src/server/json_family_test.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3239,4 +3239,26 @@ TEST_F(JsonFamilyTest, JsonSetDeleteExpiryOfExistingKey) {
32393239
EXPECT_THAT(resp.GetInt(), 100);
32403240
}
32413241

3242+
TEST_F(JsonFamilyTest, JsonIntPathTest) {
3243+
auto resp = Run(
3244+
R"(JSON.SET test:images $ {"images":[{"id":1,"sizes":{"1":"small.jpg","10":"medium.jpg","14":"large.jpg","8":"thumb.jpg"}}]})");
3245+
ASSERT_THAT(resp, "OK");
3246+
resp = Run(R"(JSON.GET test:images $.images[0].sizes.10)");
3247+
EXPECT_THAT(resp, "[\"medium.jpg\"]");
3248+
resp = Run(R"(JSON.GET test:images $.images[0].sizes["10"])");
3249+
EXPECT_THAT(resp, "[\"medium.jpg\"]");
3250+
resp = Run(R"(JSON.GET test:images $.images[0].sizes['10'])");
3251+
EXPECT_THAT(resp, "[\"medium.jpg\"]");
3252+
resp = Run(R"(JSON.GET test:images $.images[0]["sizes"]["10"])");
3253+
EXPECT_THAT(resp, "[\"medium.jpg\"]");
3254+
resp = Run(R"(JSON.GET test:images $.images[0].sizes.8)");
3255+
EXPECT_THAT(resp, "[\"thumb.jpg\"]");
3256+
resp = Run(R"(JSON.GET test:images $.images[0].sizes.14)");
3257+
EXPECT_THAT(resp, "[\"large.jpg\"]");
3258+
resp = Run(R"(JSON.GET test:images $.images[0].sizes["8"])");
3259+
EXPECT_THAT(resp, "[\"thumb.jpg\"]");
3260+
resp = Run(R"(JSON.GET test:images $.images[0].sizes["14"])");
3261+
EXPECT_THAT(resp, "[\"large.jpg\"]");
3262+
}
3263+
32423264
} // namespace dfly

0 commit comments

Comments
 (0)