Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5336bd8

Browse files
author
Nikita Glukhov
committed
Add jsonpath array constructors
1 parentbbb1f1e commit5336bd8

File tree

9 files changed

+136
-6
lines changed

9 files changed

+136
-6
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13694,6 +13694,13 @@ table2-mapping
1369413694
<entry><literal>pg $[*], 4, 5</literal></entry>
1369513695
<entry><literal>1, 2, 3, 4, 5</literal></entry>
1369613696
</row>
13697+
<row>
13698+
<entry>Array constructor</entry>
13699+
<entry>Construct a JSON array by enumeration of its elements enclosed in brackets</entry>
13700+
<entry><literal>[1, 2, 3]</literal></entry>
13701+
<entry><literal>pg [$[*], 4, 5]</literal></entry>
13702+
<entry><literal>[1, 2, 3, 4, 5]</literal></entry>
13703+
</row>
1369713704
</tbody>
1369813705
</tgroup>
1369913706
</table>

‎src/backend/utils/adt/jsonpath.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -368,13 +368,19 @@ flattenJsonPathParseItem(JsonPathEncodingContext *cxt, JsonPathParseItem *item,
368368
casejpiMinus:
369369
casejpiExists:
370370
casejpiDatetime:
371+
casejpiArray:
371372
{
372373
int32arg=reserveSpaceForItemPointer(buf);
373374

374-
chld= !item->value.arg ?pos :
375-
flattenJsonPathParseItem(cxt,item->value.arg,
376-
nestingLevel+argNestingLevel,
377-
insideArraySubscript);
375+
if (item->type==jpiArray)
376+
checkJsonPathExtensionsEnabled(cxt,item->type);
377+
378+
if (!item->value.arg)
379+
break;
380+
381+
chld=flattenJsonPathParseItem(cxt,item->value.arg,
382+
nestingLevel+argNestingLevel,
383+
insideArraySubscript);
378384
*(int32*) (buf->data+arg)=chld-pos;
379385
}
380386
break;
@@ -780,6 +786,15 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
780786
if (printBracketes||jspHasNext(v))
781787
appendStringInfoChar(buf,')');
782788
break;
789+
casejpiArray:
790+
appendStringInfoChar(buf,'[');
791+
if (v->content.arg)
792+
{
793+
jspGetArg(v,&elem);
794+
printJsonPathItem(buf,&elem, false, false);
795+
}
796+
appendStringInfoChar(buf,']');
797+
break;
783798
default:
784799
elog(ERROR,"unrecognized jsonpath item type: %d",v->type);
785800
}
@@ -979,6 +994,7 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
979994
casejpiMinus:
980995
casejpiFilter:
981996
casejpiDatetime:
997+
casejpiArray:
982998
read_int32(v->content.arg,base,pos);
983999
break;
9841000
casejpiIndexArray:
@@ -1009,7 +1025,8 @@ jspGetArg(JsonPathItem *v, JsonPathItem *a)
10091025
v->type==jpiExists||
10101026
v->type==jpiPlus||
10111027
v->type==jpiMinus||
1012-
v->type==jpiDatetime);
1028+
v->type==jpiDatetime||
1029+
v->type==jpiArray);
10131030

10141031
jspInitByBuffer(a,v->base,v->content.arg);
10151032
}
@@ -1060,7 +1077,8 @@ jspGetNext(JsonPathItem *v, JsonPathItem *a)
10601077
v->type==jpiDatetime||
10611078
v->type==jpiKeyValue||
10621079
v->type==jpiStartsWith||
1063-
v->type==jpiSequence);
1080+
v->type==jpiSequence||
1081+
v->type==jpiArray);
10641082

10651083
if (a)
10661084
jspInitByBuffer(a,v->base,v->nextPos);

‎src/backend/utils/adt/jsonpath_exec.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,25 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
11751175
break;
11761176
}
11771177

1178+
casejpiArray:
1179+
{
1180+
JsonValueListlist= {0};
1181+
JsonbValue*arr;
1182+
1183+
if (jsp->content.arg)
1184+
{
1185+
jspGetArg(jsp,&elem);
1186+
res=executeItem(cxt,&elem,jb,&list);
1187+
1188+
if (jperIsError(res))
1189+
break;
1190+
}
1191+
1192+
arr=wrapItemsInArray(&list);
1193+
res=executeNextItem(cxt,jsp,NULL,arr,found, false);
1194+
break;
1195+
}
1196+
11781197
default:
11791198
elog(ERROR,"unrecognized jsonpath item type: %d",jsp->type);
11801199
}

‎src/backend/utils/adt/jsonpath_gram.y

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ path_primary:
217217
|'@'{$$ = makeItemType(jpiCurrent); }
218218
|LAST_P{$$ = makeItemType(jpiLast); }
219219
|'('expr_seq')'{$$ =$2; }
220+
|'['']'{$$ = makeItemUnary(jpiArray,NULL); }
221+
|'['expr_or_seq']'{$$ = makeItemUnary(jpiArray,$2); }
220222
;
221223

222224
accessor_expr:

‎src/include/utils/jsonpath.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ typedef enum JsonPathItemType
8888
jpiStartsWith,/* STARTS WITH predicate */
8989
jpiLikeRegex,/* LIKE_REGEX predicate */
9090
jpiSequence,/* sequence constructor: 'expr, ...' */
91+
jpiArray,/* array constructor: '[expr, ...]' */
9192
}JsonPathItemType;
9293

9394
/* XQuery regex mode flags for LIKE_REGEX predicate */

‎src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,6 +2199,12 @@ SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)');
21992199
------------------
22002200
(0 rows)
22012201

2202+
SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', 'pg [$[*].a]');
2203+
jsonb_path_query
2204+
------------------
2205+
[1, 2]
2206+
(1 row)
2207+
22022208
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a');
22032209
ERROR: JSON object does not contain key "a"
22042210
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a');
@@ -2231,6 +2237,12 @@ SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].
22312237
[]
22322238
(1 row)
22332239

2240+
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', 'pg [$[*].a]');
2241+
jsonb_path_query_array
2242+
------------------------
2243+
[[1, 2]]
2244+
(1 row)
2245+
22342246
SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a');
22352247
ERROR: JSON object does not contain key "a"
22362248
SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a', silent => true);
@@ -2578,3 +2590,48 @@ select jsonb_path_query('[1,2,3,4,5]', 'pg $[(0, $[*], 5) ? (@ == 3)]');
25782590

25792591
select jsonb_path_query('[1,2,3,4,5]', 'pg $[(0, $[*], 3) ? (@ == 3)]');
25802592
ERROR: jsonpath array subscript is not a single numeric value
2593+
-- extension: array constructors
2594+
select jsonb_path_query('[1, 2, 3]', 'pg []');
2595+
jsonb_path_query
2596+
------------------
2597+
[]
2598+
(1 row)
2599+
2600+
select jsonb_path_query('[1, 2, 3]', 'pg [1, 2, $[*], 4, 5]');
2601+
jsonb_path_query
2602+
-----------------------
2603+
[1, 2, 1, 2, 3, 4, 5]
2604+
(1 row)
2605+
2606+
select jsonb_path_query('[1, 2, 3]', 'pg [1, 2, $[*], 4, 5][*]');
2607+
jsonb_path_query
2608+
------------------
2609+
1
2610+
2
2611+
1
2612+
2
2613+
3
2614+
4
2615+
5
2616+
(7 rows)
2617+
2618+
select jsonb_path_query('[1, 2, 3]', 'pg [(1, (2, $[*])), (4, 5)]');
2619+
jsonb_path_query
2620+
-----------------------
2621+
[1, 2, 1, 2, 3, 4, 5]
2622+
(1 row)
2623+
2624+
select jsonb_path_query('[1, 2, 3]', 'pg [[1, 2], [$[*], 4], 5, [(1,2)?(@ > 5)]]');
2625+
jsonb_path_query
2626+
-------------------------------
2627+
[[1, 2], [1, 2, 3, 4], 5, []]
2628+
(1 row)
2629+
2630+
select jsonb_path_query('[1, 2, 3]', 'pg strict [1, 2, $[*].a, 4, 5]');
2631+
ERROR: jsonpath member accessor can only be applied to an object
2632+
select jsonb_path_query('[[1, 2], [3, 4, 5], [], [6, 7]]', 'pg [$[*][*] ? (@ > 3)]');
2633+
jsonb_path_query
2634+
------------------
2635+
[4, 5, 6, 7]
2636+
(1 row)
2637+

‎src/test/regress/expected/jsonpath.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,18 @@ select 'pg $[(1, (2, $.a)), 3, (4, 5)]'::jsonpath;
604604
pg $[(1, (2, $."a")),3,(4, 5)]
605605
(1 row)
606606

607+
select 'pg []'::jsonpath;
608+
jsonpath
609+
----------
610+
pg []
611+
(1 row)
612+
613+
select 'pg [[1, 2], ([(3, 4, 5), 6], []), $.a[*]]'::jsonpath;
614+
jsonpath
615+
---------------------------------------------
616+
pg [[1, 2], ([(3, 4, 5), 6], []), $."a"[*]]
617+
(1 row)
618+
607619
select '$ ? (@.a < 1)'::jsonpath;
608620
jsonpath
609621
---------------

‎src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,13 +525,15 @@ set time zone default;
525525

526526
SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]','$[*]');
527527
SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]','$[*] ? (@.a > 10)');
528+
SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]','pg [$[*].a]');
528529

529530
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]','strict $[*].a');
530531
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]','$[*].a');
531532
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]','$[*].a ? (@ == 1)');
532533
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]','$[*].a ? (@ > 10)');
533534
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]','$[*].a ? (@ > $min && @ < $max)', vars=>'{"min": 1, "max": 4}');
534535
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]','$[*].a ? (@ > $min && @ < $max)', vars=>'{"min": 3, "max": 4}');
536+
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]','pg [$[*].a]');
535537

536538
SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]','strict $[*].a');
537539
SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]','strict $[*].a', silent=> true);
@@ -587,3 +589,12 @@ select jsonb_path_query('[1,2,3,4,5]', 'pg -(10, 20, $[1 to 3], 30)');
587589
select jsonb_path_query('[1,2,3,4,5]','pg lax (10, 20.5, $[1 to 3], "30").double()');
588590
select jsonb_path_query('[1,2,3,4,5]','pg $[(0, $[*], 5) ? (@ == 3)]');
589591
select jsonb_path_query('[1,2,3,4,5]','pg $[(0, $[*], 3) ? (@ == 3)]');
592+
593+
-- extension: array constructors
594+
select jsonb_path_query('[1, 2, 3]','pg []');
595+
select jsonb_path_query('[1, 2, 3]','pg [1, 2, $[*], 4, 5]');
596+
select jsonb_path_query('[1, 2, 3]','pg [1, 2, $[*], 4, 5][*]');
597+
select jsonb_path_query('[1, 2, 3]','pg [(1, (2, $[*])), (4, 5)]');
598+
select jsonb_path_query('[1, 2, 3]','pg [[1, 2], [$[*], 4], 5, [(1,2)?(@ > 5)]]');
599+
select jsonb_path_query('[1, 2, 3]','pg strict [1, 2, $[*].a, 4, 5]');
600+
select jsonb_path_query('[[1, 2], [3, 4, 5], [], [6, 7]]','pg [$[*][*] ? (@ > 3)]');

‎src/test/regress/sql/jsonpath.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ select 'pg (1, 2, $.a) == 5'::jsonpath;
113113
select'pg $[(1,2, $.a) to (3,4)]'::jsonpath;
114114
select'pg $[(1, (2, $.a)),3, (4,5)]'::jsonpath;
115115
116+
select'pg []'::jsonpath;
117+
select'pg [[1,2], ([(3,4,5),6], []), $.a[*]]'::jsonpath;
118+
116119
select'$ ? (@.a<1)'::jsonpath;
117120
select'$ ? (@.a<-1)'::jsonpath;
118121
select'$ ? (@.a<+1)'::jsonpath;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp