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

Commit 0864532

Browse files
author
Nikita Glukhov
committed
Change syntax of jsonpath .** accessor
1 parent 8cba26d commit 0864532

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
@@ -508,16 +508,21 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracket
508508
appendStringInfoChar(buf, '.');
509509

510510
if (v->content.anybounds.first == 0 &&
511-
v->content.anybounds.last == PG_UINT32_MAX)
511+
v->content.anybounds.last == PG_UINT32_MAX)
512512
appendBinaryStringInfo(buf, "**", 2);
513-
else if (v->content.anybounds.first == 0)
514-
appendStringInfo(buf, "**{,%u}", v->content.anybounds.last);
515-
else if (v->content.anybounds.last == PG_UINT32_MAX)
516-
appendStringInfo(buf, "**{%u,}", v->content.anybounds.first);
517513
else if (v->content.anybounds.first == v->content.anybounds.last)
518-
appendStringInfo(buf, "**{%u}", v->content.anybounds.first);
514+
{
515+
if (v->content.anybounds.first == PG_UINT32_MAX)
516+
appendStringInfo(buf, "**{last}");
517+
else
518+
appendStringInfo(buf, "**{%u}", v->content.anybounds.first);
519+
}
520+
else if (v->content.anybounds.first == PG_UINT32_MAX)
521+
appendStringInfo(buf, "**{last to %u}", v->content.anybounds.last);
522+
else if (v->content.anybounds.last == PG_UINT32_MAX)
523+
appendStringInfo(buf, "**{%u to last}", v->content.anybounds.first);
519524
else
520-
appendStringInfo(buf, "**{%u,%u}", v->content.anybounds.first,
525+
appendStringInfo(buf, "**{%u to %u}", v->content.anybounds.first,
521526
v->content.anybounds.last);
522527
break;
523528
case jpiType:

src/backend/utils/adt/jsonpath_exec.c

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

1019-
if (level >= first)
1019+
if (level >= first ||
1020+
(first == PG_UINT32_MAX && last == PG_UINT32_MAX &&
1021+
v.type != jbvBinary)) /* leaves only requested */
10201022
{
10211023
/* check expression */
10221024
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
@@ -202,7 +202,7 @@ makeAny(int first, int last)
202202
{
203203
JsonPathParseItem *v = makeItemType(jpiAny);
204204

205-
v->value.anybounds.first = (first > 0) ? first : 0;
205+
v->value.anybounds.first = (first >= 0) ? first : PG_UINT32_MAX;
206206
v->value.anybounds.last = (last >= 0) ? last : PG_UINT32_MAX;
207207

208208
return v;
@@ -272,6 +272,7 @@ makeItemLikeRegex(JsonPathParseItem *expr, string *pattern, string *flags)
272272
JsonPathParseResult *result;
273273
JsonPathItemType optype;
274274
bool boolean;
275+
int integer;
275276
}
276277

277278
%token <str> TO_P NULL_P TRUE_P FALSE_P IS_P UNKNOWN_P EXISTS_P
@@ -299,6 +300,7 @@ makeItemLikeRegex(JsonPathParseItem *expr, string *pattern, string *flags)
299300

300301
%type <str> key_name
301302

303+
%type <integer> any_level
302304

303305
%left OR_P
304306
%left AND_P
@@ -416,14 +418,15 @@ array_accessor:
416418
| '[' index_list ']' { $$ = makeIndexArray($2); }
417419
;
418420

421+
any_level:
422+
INT_P { $$ = pg_atoi($1.val, 4, 0); }
423+
| LAST_P { $$ = -1; }
424+
;
425+
419426
any_path:
420-
ANY_P { $$ = makeAny(-1, -1); }
421-
| ANY_P '{' INT_P '}' { $$ = makeAny(pg_atoi($3.val, 4, 0),
422-
pg_atoi($3.val, 4, 0)); }
423-
| ANY_P '{' ',' INT_P '}' { $$ = makeAny(-1, pg_atoi($4.val, 4, 0)); }
424-
| ANY_P '{' INT_P ',' '}' { $$ = makeAny(pg_atoi($3.val, 4, 0), -1); }
425-
| ANY_P '{' INT_P ',' INT_P '}' { $$ = makeAny(pg_atoi($3.val, 4, 0),
426-
pg_atoi($5.val, 4, 0)); }
427+
ANY_P { $$ = makeAny(0, -1); }
428+
| ANY_P '{' any_level '}' { $$ = makeAny($3, $3); }
429+
| ANY_P '{' any_level TO_P any_level '}' { $$ = makeAny($3, $5); }
427430
;
428431

429432
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)