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

Commit 8a0304f

Browse files
author
Nikita Glukhov
committed
Add jsonpath operator @# for returning conditionally wrapped in array sequences
1 parent 6480f67 commit 8a0304f

File tree

5 files changed

+70
-0
lines changed

5 files changed

+70
-0
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2480,6 +2480,44 @@ jsonb_jsonpath_query3(PG_FUNCTION_ARGS)
24802480
return jsonb_jsonpath_query(fcinfo);
24812481
}
24822482

2483+
static Datum
2484+
jsonb_jsonpath_query_wrapped(FunctionCallInfo fcinfo, List *vars)
2485+
{
2486+
Jsonb *jb = PG_GETARG_JSONB_P(0);
2487+
JsonPath *jp = PG_GETARG_JSONPATH_P(1);
2488+
JsonValueList found = { 0 };
2489+
JsonPathExecResult res;
2490+
int size;
2491+
2492+
res = executeJsonPath(jp, vars, jb, &found);
2493+
2494+
if (jperIsError(res))
2495+
throwJsonPathError(res);
2496+
2497+
size = JsonValueListLength(&found);
2498+
2499+
if (size == 0)
2500+
PG_RETURN_NULL();
2501+
2502+
if (size == 1)
2503+
PG_RETURN_JSONB_P(JsonbValueToJsonb(JsonValueListHead(&found)));
2504+
2505+
PG_RETURN_JSONB_P(JsonbValueToJsonb(wrapItemsInArray(&found)));
2506+
}
2507+
2508+
Datum
2509+
jsonb_jsonpath_query_wrapped2(PG_FUNCTION_ARGS)
2510+
{
2511+
return jsonb_jsonpath_query_wrapped(fcinfo, NIL);
2512+
}
2513+
2514+
Datum
2515+
jsonb_jsonpath_query_wrapped3(PG_FUNCTION_ARGS)
2516+
{
2517+
return jsonb_jsonpath_query_wrapped(fcinfo,
2518+
makePassingVars(PG_GETARG_JSONB_P(2)));
2519+
}
2520+
24832521
/* Construct a JSON array from the item list */
24842522
static inline JsonbValue *
24852523
wrapItemsInArray(const JsonValueList *items)

src/include/catalog/pg_operator.dat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3206,5 +3206,8 @@
32063206
oprname => '@~', oprleft => 'jsonb', oprright => 'jsonpath',
32073207
oprresult => 'bool', oprcode => 'jsonpath_predicate(jsonb,jsonpath)',
32083208
oprrest => 'contsel', oprjoin => 'contjoinsel' },
3209+
{ oid => '6122', descr => 'jsonpath items wrapped',
3210+
oprname => '@#', oprleft => 'jsonb', oprright => 'jsonpath',
3211+
oprresult => 'jsonb', oprcode => 'jsonpath_query_wrapped(jsonb,jsonpath)' },
32093212

32103213
]

src/include/catalog/pg_proc.dat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9117,13 +9117,20 @@
91179117
proname => 'jsonpath_query', prorows => '1000', proretset => 't',
91189118
prorettype => 'jsonb', proargtypes => 'jsonb jsonpath',
91199119
prosrc => 'jsonb_jsonpath_query2' },
9120+
{ oid => '6124', descr => 'implementation of @# operator',
9121+
proname => 'jsonpath_query_wrapped', prorettype => 'jsonb',
9122+
proargtypes => 'jsonb jsonpath', prosrc => 'jsonb_jsonpath_query_wrapped2' },
91209123
{ oid => '6056', descr => 'jsonpath exists test',
91219124
proname => 'jsonpath_exists', prorettype => 'bool',
91229125
proargtypes => 'jsonb jsonpath jsonb', prosrc => 'jsonb_jsonpath_exists3' },
91239126
{ oid => '6057', descr => 'jsonpath query',
91249127
proname => 'jsonpath_query', prorows => '1000', proretset => 't',
91259128
prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb',
91269129
prosrc => 'jsonb_jsonpath_query3' },
9130+
{ oid => '6125', descr => 'jsonpath query with conditional wrapper',
9131+
proname => 'jsonpath_query_wrapped', prorettype => 'jsonb',
9132+
proargtypes => 'jsonb jsonpath jsonb',
9133+
prosrc => 'jsonb_jsonpath_query_wrapped3' },
91279134
{ oid => '6073', descr => 'implementation of @~ operator',
91289135
proname => 'jsonpath_predicate', prorettype => 'bool',
91299136
proargtypes => 'jsonb jsonpath', prosrc => 'jsonb_jsonpath_predicate2' },

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,6 +1620,24 @@ SELECT jsonb '[{"a": 1}, {"a": 2}]' @* '$[*] ? (@.a > 10)';
16201620
----------
16211621
(0 rows)
16221622

1623+
SELECT jsonb '[{"a": 1}, {"a": 2}]' @# '$[*].a';
1624+
?column?
1625+
----------
1626+
[1, 2]
1627+
(1 row)
1628+
1629+
SELECT jsonb '[{"a": 1}, {"a": 2}]' @# '$[*].a ? (@ == 1)';
1630+
?column?
1631+
----------
1632+
1
1633+
(1 row)
1634+
1635+
SELECT jsonb '[{"a": 1}, {"a": 2}]' @# '$[*].a ? (@ > 10)';
1636+
?column?
1637+
----------
1638+
1639+
(1 row)
1640+
16231641
SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)';
16241642
?column?
16251643
----------

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ set time zone default;
361361
SELECT jsonb '[{"a": 1}, {"a": 2}]' @* '$[*]';
362362
SELECT jsonb '[{"a": 1}, {"a": 2}]' @* '$[*] ? (@.a > 10)';
363363

364+
SELECT jsonb '[{"a": 1}, {"a": 2}]' @# '$[*].a';
365+
SELECT jsonb '[{"a": 1}, {"a": 2}]' @# '$[*].a ? (@ == 1)';
366+
SELECT jsonb '[{"a": 1}, {"a": 2}]' @# '$[*].a ? (@ > 10)';
367+
364368
SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)';
365369
SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*] ? (@.a > 2)';
366370

0 commit comments

Comments
 (0)