Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 92d88ac

Browse files
author
Nikita Glukhov
committed
Change syntax of jsonpath .** accessor
1 parent c755a7f commit 92d88ac

File tree

7 files changed

+93
-67
lines changed

7 files changed

+93
-67
lines changed

src/backend/utils/adt/jsonpath.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -504,16 +504,21 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracket
504504
appendStringInfoChar(buf, '.');
505505

506506
if (v->content.anybounds.first == 0 &&
507-
v->content.anybounds.last == PG_UINT32_MAX)
507+
v->content.anybounds.last == PG_UINT32_MAX)
508508
appendBinaryStringInfo(buf, "**", 2);
509-
else if (v->content.anybounds.first == 0)
510-
appendStringInfo(buf, "**{,%u}", v->content.anybounds.last);
511-
else if (v->content.anybounds.last == PG_UINT32_MAX)
512-
appendStringInfo(buf, "**{%u,}", v->content.anybounds.first);
513509
else if (v->content.anybounds.first == v->content.anybounds.last)
514-
appendStringInfo(buf, "**{%u}", v->content.anybounds.first);
510+
{
511+
if (v->content.anybounds.first == PG_UINT32_MAX)
512+
appendStringInfo(buf, "**{last}");
513+
else
514+
appendStringInfo(buf, "**{%u}", v->content.anybounds.first);
515+
}
516+
else if (v->content.anybounds.first == PG_UINT32_MAX)
517+
appendStringInfo(buf, "**{last to %u}", v->content.anybounds.last);
518+
else if (v->content.anybounds.last == PG_UINT32_MAX)
519+
appendStringInfo(buf, "**{%u to last}", v->content.anybounds.first);
515520
else
516-
appendStringInfo(buf, "**{%u,%u}", v->content.anybounds.first,
521+
appendStringInfo(buf, "**{%u to %u}", v->content.anybounds.first,
517522
v->content.anybounds.last);
518523
break;
519524
case jpiType:

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,9 @@ recursiveAny(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
10471047
if (r == WJB_VALUE || r == WJB_ELEM)
10481048
{
10491049

1050-
if (level >= first)
1050+
if (level >= first ||
1051+
(first == PG_UINT32_MAX && last == PG_UINT32_MAX &&
1052+
v.type != jbvBinary)) /* leaves only requested */
10511053
{
10521054
/* check expression */
10531055
res = recursiveExecuteNext(cxt, NULL, jsp, &v, found, true);

src/backend/utils/adt/jsonpath_gram.y

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ makeAny(int first, int last)
199199
{
200200
JsonPathParseItem *v = makeItemType(jpiAny);
201201

202-
v->value.anybounds.first = (first > 0) ? first : 0;
202+
v->value.anybounds.first = (first >= 0) ? first : PG_UINT32_MAX;
203203
v->value.anybounds.last = (last >= 0) ? last : PG_UINT32_MAX;
204204

205205
return v;
@@ -269,6 +269,7 @@ makeItemLikeRegex(JsonPathParseItem *expr, string *pattern, string *flags)
269269
JsonPathParseResult *result;
270270
JsonPathItemType optype;
271271
bool boolean;
272+
int integer;
272273
}
273274

274275
%token <str> TO_P NULL_P TRUE_P FALSE_P IS_P UNKNOWN_P EXISTS_P
@@ -296,6 +297,7 @@ makeItemLikeRegex(JsonPathParseItem *expr, string *pattern, string *flags)
296297

297298
%type <str> key_name
298299

300+
%type <integer> any_level
299301

300302
%left OR_P
301303
%left AND_P
@@ -413,14 +415,15 @@ array_accessor:
413415
| '[' index_list ']' { $$ = makeIndexArray($2); }
414416
;
415417

418+
any_level:
419+
INT_P { $$ = pg_atoi($1.val, 4, 0); }
420+
| LAST_P { $$ = -1; }
421+
;
422+
416423
any_path:
417-
ANY_P { $$ = makeAny(-1, -1); }
418-
| ANY_P '{' INT_P '}' { $$ = makeAny(pg_atoi($3.val, 4, 0),
419-
pg_atoi($3.val, 4, 0)); }
420-
| ANY_P '{' ',' INT_P '}' { $$ = makeAny(-1, pg_atoi($4.val, 4, 0)); }
421-
| ANY_P '{' INT_P ',' '}' { $$ = makeAny(pg_atoi($3.val, 4, 0), -1); }
422-
| ANY_P '{' INT_P ',' INT_P '}' { $$ = makeAny(pg_atoi($3.val, 4, 0),
423-
pg_atoi($5.val, 4, 0)); }
424+
ANY_P { $$ = makeAny(0, -1); }
425+
| ANY_P '{' any_level '}' { $$ = makeAny($3, $3); }
426+
| ANY_P '{' any_level TO_P any_level '}' { $$ = makeAny($3, $5); }
424427
;
425428

426429
accessor_op:

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -388,13 +388,27 @@ select jsonb '{"a": {"b": 1}}' @* 'lax $.**';
388388
1
389389
(3 rows)
390390

391+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0}';
392+
?column?
393+
-----------------
394+
{"a": {"b": 1}}
395+
(1 row)
396+
397+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0 to last}';
398+
?column?
399+
-----------------
400+
{"a": {"b": 1}}
401+
{"b": 1}
402+
1
403+
(3 rows)
404+
391405
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1}';
392406
?column?
393407
----------
394408
{"b": 1}
395409
(1 row)
396410

397-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1,}';
411+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1 to last}';
398412
?column?
399413
----------
400414
{"b": 1}
@@ -407,13 +421,13 @@ select jsonb '{"a": {"b": 1}}' @* 'lax $.**{2}';
407421
1
408422
(1 row)
409423

410-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{2,}';
424+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{2 to last}';
411425
?column?
412426
----------
413427
1
414428
(1 row)
415429

416-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{3,}';
430+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{3 to last}';
417431
?column?
418432
----------
419433
(0 rows)
@@ -435,19 +449,19 @@ select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1}.b ? (@ > 0)';
435449
1
436450
(1 row)
437451

438-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0,}.b ? (@ > 0)';
452+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0 to last}.b ? (@ > 0)';
439453
?column?
440454
----------
441455
1
442456
(1 row)
443457

444-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1,}.b ? (@ > 0)';
458+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1 to last}.b ? (@ > 0)';
445459
?column?
446460
----------
447461
1
448462
(1 row)
449463

450-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1,2}.b ? (@ > 0)';
464+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1 to 2}.b ? (@ > 0)';
451465
?column?
452466
----------
453467
1
@@ -469,25 +483,25 @@ select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1}.b ? (@ > 0)';
469483
----------
470484
(0 rows)
471485

472-
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{0,}.b ? (@ > 0)';
486+
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{0 to last}.b ? (@ > 0)';
473487
?column?
474488
----------
475489
1
476490
(1 row)
477491

478-
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1,}.b ? (@ > 0)';
492+
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1 to last}.b ? (@ > 0)';
479493
?column?
480494
----------
481495
1
482496
(1 row)
483497

484-
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1,2}.b ? (@ > 0)';
498+
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1 to 2}.b ? (@ > 0)';
485499
?column?
486500
----------
487501
1
488502
(1 row)
489503

490-
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{2,3}.b ? (@ > 0)';
504+
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{2 to 3}.b ? (@ > 0)';
491505
?column?
492506
----------
493507
1
@@ -511,19 +525,19 @@ select jsonb '{"a": {"b": 1}}' @? '$.**{1}.b ? ( @ > 0)';
511525
t
512526
(1 row)
513527

514-
select jsonb '{"a": {"b": 1}}' @? '$.**{0,}.b ? ( @ > 0)';
528+
select jsonb '{"a": {"b": 1}}' @? '$.**{0 to last}.b ? ( @ > 0)';
515529
?column?
516530
----------
517531
t
518532
(1 row)
519533

520-
select jsonb '{"a": {"b": 1}}' @? '$.**{1,}.b ? ( @ > 0)';
534+
select jsonb '{"a": {"b": 1}}' @? '$.**{1 to last}.b ? ( @ > 0)';
521535
?column?
522536
----------
523537
t
524538
(1 row)
525539

526-
select jsonb '{"a": {"b": 1}}' @? '$.**{1,2}.b ? ( @ > 0)';
540+
select jsonb '{"a": {"b": 1}}' @? '$.**{1 to 2}.b ? ( @ > 0)';
527541
?column?
528542
----------
529543
t
@@ -547,25 +561,25 @@ select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1}.b ? ( @ > 0)';
547561
f
548562
(1 row)
549563

550-
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0,}.b ? ( @ > 0)';
564+
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0 to last}.b ? ( @ > 0)';
551565
?column?
552566
----------
553567
t
554568
(1 row)
555569

556-
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1,}.b ? ( @ > 0)';
570+
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to last}.b ? ( @ > 0)';
557571
?column?
558572
----------
559573
t
560574
(1 row)
561575

562-
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1,2}.b ? ( @ > 0)';
576+
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to 2}.b ? ( @ > 0)';
563577
?column?
564578
----------
565579
t
566580
(1 row)
567581

568-
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2,3}.b ? ( @ > 0)';
582+
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2 to 3}.b ? ( @ > 0)';
569583
?column?
570584
----------
571585
t

src/test/regress/expected/jsonpath.out

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,28 +99,28 @@ select '$.a.**{2}.b'::jsonpath;
9999
$."a".**{2}."b"
100100
(1 row)
101101

102-
select '$.a.**{2,2}.b'::jsonpath;
102+
select '$.a.**{2 to 2}.b'::jsonpath;
103103
jsonpath
104104
-----------------
105105
$."a".**{2}."b"
106106
(1 row)
107107

108-
select '$.a.**{2,5}.b'::jsonpath;
109-
jsonpath
110-
-------------------
111-
$."a".**{2,5}."b"
108+
select '$.a.**{2 to 5}.b'::jsonpath;
109+
jsonpath
110+
----------------------
111+
$."a".**{2 to 5}."b"
112112
(1 row)
113113

114-
select '$.a.**{,5}.b'::jsonpath;
115-
jsonpath
116-
------------------
117-
$."a".**{,5}."b"
114+
select '$.a.**{0 to 5}.b'::jsonpath;
115+
jsonpath
116+
----------------------
117+
$."a".**{0 to 5}."b"
118118
(1 row)
119119

120-
select '$.a.**{5,}.b'::jsonpath;
121-
jsonpath
122-
------------------
123-
$."a".**{5,}."b"
120+
select '$.a.**{5 to last}.b'::jsonpath;
121+
jsonpath
122+
-------------------------
123+
$."a".**{5 to last}."b"
124124
(1 row)
125125

126126
select '$+1'::jsonpath;

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,38 +67,40 @@ select * from jsonpath_query(jsonb '[1, "2", null]', '$[*] ? (@ != null)');
6767
select * from jsonpath_query(jsonb '[1, "2", null]', '$[*] ? (@ == null)');
6868

6969
select jsonb '{"a": {"b": 1}}' @* 'lax $.**';
70+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0}';
71+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0 to last}';
7072
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1}';
71-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1,}';
73+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1 to last}';
7274
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{2}';
73-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{2,}';
74-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{3,}';
75+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{2 to last}';
76+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{3 to last}';
7577
select jsonb '{"a": {"b": 1}}' @* 'lax $.**.b ? (@ > 0)';
7678
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0}.b ? (@ > 0)';
7779
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1}.b ? (@ > 0)';
78-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0,}.b ? (@ > 0)';
79-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1,}.b ? (@ > 0)';
80-
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1,2}.b ? (@ > 0)';
80+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{0 to last}.b ? (@ > 0)';
81+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1 to last}.b ? (@ > 0)';
82+
select jsonb '{"a": {"b": 1}}' @* 'lax $.**{1 to 2}.b ? (@ > 0)';
8183
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**.b ? (@ > 0)';
8284
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{0}.b ? (@ > 0)';
8385
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1}.b ? (@ > 0)';
84-
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{0,}.b ? (@ > 0)';
85-
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1,}.b ? (@ > 0)';
86-
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1,2}.b ? (@ > 0)';
87-
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{2,3}.b ? (@ > 0)';
86+
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{0 to last}.b ? (@ > 0)';
87+
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1 to last}.b ? (@ > 0)';
88+
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{1 to 2}.b ? (@ > 0)';
89+
select jsonb '{"a": {"c": {"b": 1}}}' @* 'lax $.**{2 to 3}.b ? (@ > 0)';
8890

8991
select jsonb '{"a": {"b": 1}}' @? '$.**.b ? ( @ > 0)';
9092
select jsonb '{"a": {"b": 1}}' @? '$.**{0}.b ? ( @ > 0)';
9193
select jsonb '{"a": {"b": 1}}' @? '$.**{1}.b ? ( @ > 0)';
92-
select jsonb '{"a": {"b": 1}}' @? '$.**{0,}.b ? ( @ > 0)';
93-
select jsonb '{"a": {"b": 1}}' @? '$.**{1,}.b ? ( @ > 0)';
94-
select jsonb '{"a": {"b": 1}}' @? '$.**{1,2}.b ? ( @ > 0)';
94+
select jsonb '{"a": {"b": 1}}' @? '$.**{0 to last}.b ? ( @ > 0)';
95+
select jsonb '{"a": {"b": 1}}' @? '$.**{1 to last}.b ? ( @ > 0)';
96+
select jsonb '{"a": {"b": 1}}' @? '$.**{1 to 2}.b ? ( @ > 0)';
9597
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**.b ? ( @ > 0)';
9698
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0}.b ? ( @ > 0)';
9799
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1}.b ? ( @ > 0)';
98-
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0,}.b ? ( @ > 0)';
99-
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1,}.b ? ( @ > 0)';
100-
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1,2}.b ? ( @ > 0)';
101-
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2,3}.b ? ( @ > 0)';
100+
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0 to last}.b ? ( @ > 0)';
101+
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to last}.b ? ( @ > 0)';
102+
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to 2}.b ? ( @ > 0)';
103+
select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2 to 3}.b ? ( @ > 0)';
102104

103105
select jsonb '{"g": {"x": 2}}' @* '$.g ? (exists (@.x))';
104106
select jsonb '{"g": {"x": 2}}' @* '$.g ? (exists (@.y))';

src/test/regress/sql/jsonpath.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ select '$[*].a'::jsonpath;
1717
select '$[*][0].a.b'::jsonpath;
1818
select '$.a.**.b'::jsonpath;
1919
select '$.a.**{2}.b'::jsonpath;
20-
select '$.a.**{2,2}.b'::jsonpath;
21-
select '$.a.**{2,5}.b'::jsonpath;
22-
select '$.a.**{,5}.b'::jsonpath;
23-
select '$.a.**{5,}.b'::jsonpath;
20+
select '$.a.**{2 to 2}.b'::jsonpath;
21+
select '$.a.**{2 to 5}.b'::jsonpath;
22+
select '$.a.**{0 to 5}.b'::jsonpath;
23+
select '$.a.**{5 to last}.b'::jsonpath;
2424
select '$+1'::jsonpath;
2525
select '$-1'::jsonpath;
2626
select '$--+1'::jsonpath;

0 commit comments

Comments
 (0)