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

Commit 0f0abe3

Browse files
author
Nikita Glukhov
committed
Add _jsonpath_predicate()
1 parent 534b2a1 commit 0f0abe3

File tree

4 files changed

+116
-0
lines changed

4 files changed

+116
-0
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,6 +2372,52 @@ jsonb_jsonpath_exists3(PG_FUNCTION_ARGS)
23722372
return jsonb_jsonpath_exists(fcinfo);
23732373
}
23742374

2375+
static inline Datum
2376+
jsonb_jsonpath_predicate(FunctionCallInfo fcinfo, List *vars)
2377+
{
2378+
Jsonb *jb = PG_GETARG_JSONB_P(0);
2379+
JsonPath *jp = PG_GETARG_JSONPATH_P(1);
2380+
JsonbValue *jbv;
2381+
JsonValueList found = { 0 };
2382+
JsonPathExecResult res;
2383+
2384+
res = executeJsonPath(jp, vars, jb, &found);
2385+
2386+
throwJsonPathError(res);
2387+
2388+
if (JsonValueListLength(&found) != 1)
2389+
throwJsonPathError(jperMakeError(ERRCODE_SINGLETON_JSON_ITEM_REQUIRED));
2390+
2391+
jbv = JsonValueListHead(&found);
2392+
2393+
if (JsonbType(jbv) == jbvScalar)
2394+
JsonbExtractScalar(jbv->val.binary.data, jbv);
2395+
2396+
PG_FREE_IF_COPY(jb, 0);
2397+
PG_FREE_IF_COPY(jp, 1);
2398+
2399+
if (jbv->type == jbvNull)
2400+
PG_RETURN_NULL();
2401+
2402+
if (jbv->type != jbvBool)
2403+
PG_RETURN_NULL(); /* XXX */
2404+
2405+
PG_RETURN_BOOL(jbv->val.boolean);
2406+
}
2407+
2408+
Datum
2409+
jsonb_jsonpath_predicate2(PG_FUNCTION_ARGS)
2410+
{
2411+
return jsonb_jsonpath_predicate(fcinfo, NIL);
2412+
}
2413+
2414+
Datum
2415+
jsonb_jsonpath_predicate3(PG_FUNCTION_ARGS)
2416+
{
2417+
return jsonb_jsonpath_predicate(fcinfo,
2418+
makePassingVars(PG_GETARG_JSONB_P(2)));
2419+
}
2420+
23752421
static Datum
23762422
jsonb_jsonpath_query(FunctionCallInfo fcinfo)
23772423
{

src/include/catalog/pg_proc.dat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9124,6 +9124,13 @@
91249124
proname => '_jsonpath_query', prorows => '1000', proretset => 't',
91259125
prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb',
91269126
prosrc => 'jsonb_jsonpath_query3' },
9127+
{ oid => '6073', descr => 'jsonpath predicate test',
9128+
proname => '_jsonpath_predicate', prorettype => 'bool',
9129+
proargtypes => 'jsonb jsonpath', prosrc => 'jsonb_jsonpath_predicate2' },
9130+
{ oid => '6074', descr => 'jsonpath predicate test',
9131+
proname => '_jsonpath_predicate', prorettype => 'bool',
9132+
proargtypes => 'jsonb jsonpath jsonb',
9133+
prosrc => 'jsonb_jsonpath_predicate3' },
91279134

91289135
# txid
91299136
{ oid => '2939', descr => 'I/O',

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,58 @@ select _jsonpath_query(jsonb '2', '$ == "2"');
820820
null
821821
(1 row)
822822

823+
select _jsonpath_predicate(jsonb '2', '$ > 1');
824+
_jsonpath_predicate
825+
---------------------
826+
t
827+
(1 row)
828+
829+
select _jsonpath_predicate(jsonb '2', '$ <= 1');
830+
_jsonpath_predicate
831+
---------------------
832+
f
833+
(1 row)
834+
835+
select _jsonpath_predicate(jsonb '2', '$ == "2"');
836+
_jsonpath_predicate
837+
---------------------
838+
839+
(1 row)
840+
841+
select _jsonpath_predicate(jsonb '2', '1');
842+
_jsonpath_predicate
843+
---------------------
844+
845+
(1 row)
846+
847+
select _jsonpath_predicate(jsonb '{}', '$');
848+
_jsonpath_predicate
849+
---------------------
850+
851+
(1 row)
852+
853+
select _jsonpath_predicate(jsonb '[]', '$');
854+
_jsonpath_predicate
855+
---------------------
856+
857+
(1 row)
858+
859+
select _jsonpath_predicate(jsonb '[1,2,3]', '$[*]');
860+
ERROR: Singleton SQL/JSON item required
861+
select _jsonpath_predicate(jsonb '[]', '$[*]');
862+
ERROR: Singleton SQL/JSON item required
863+
select _jsonpath_predicate(jsonb '[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}');
864+
_jsonpath_predicate
865+
---------------------
866+
f
867+
(1 row)
868+
869+
select _jsonpath_predicate(jsonb '[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}');
870+
_jsonpath_predicate
871+
---------------------
872+
t
873+
(1 row)
874+
823875
select _jsonpath_query(jsonb '[null,1,true,"a",[],{}]', '$.type()');
824876
_jsonpath_query
825877
-----------------

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ select _jsonpath_query(jsonb '2', '$ > 1');
168168
select _jsonpath_query(jsonb '2', '$ <= 1');
169169
select _jsonpath_query(jsonb '2', '$ == "2"');
170170

171+
select _jsonpath_predicate(jsonb '2', '$ > 1');
172+
select _jsonpath_predicate(jsonb '2', '$ <= 1');
173+
select _jsonpath_predicate(jsonb '2', '$ == "2"');
174+
select _jsonpath_predicate(jsonb '2', '1');
175+
select _jsonpath_predicate(jsonb '{}', '$');
176+
select _jsonpath_predicate(jsonb '[]', '$');
177+
select _jsonpath_predicate(jsonb '[1,2,3]', '$[*]');
178+
select _jsonpath_predicate(jsonb '[]', '$[*]');
179+
select _jsonpath_predicate(jsonb '[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}');
180+
select _jsonpath_predicate(jsonb '[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}');
181+
171182
select _jsonpath_query(jsonb '[null,1,true,"a",[],{}]', '$.type()');
172183
select _jsonpath_query(jsonb '[null,1,true,"a",[],{}]', 'lax $.type()');
173184
select _jsonpath_query(jsonb '[null,1,true,"a",[],{}]', '$[*].type()');

0 commit comments

Comments
 (0)