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

Commit 65dd7b8

Browse files
author
Nikita Glukhov
committed
Add _jsonpath_predicate()
1 parent 616a472 commit 65dd7b8

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

src/backend/utils/adt/jsonpath_exec.c

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

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

src/include/catalog/pg_proc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5539,6 +5539,10 @@ DATA(insert OID = 6058 ( _jsonpath_query_safe PGNSP PGUID 12 1 1000 0 0 f f f
55395539
DESCR("jsonpath query, empty on error");
55405540
DATA(insert OID = 6059 ( _jsonpath_query_safe PGNSP PGUID 12 1 1000 0 0 f f f f t t i s 3 0 3802 "3802 6050 3802" _null_ _null_ _null_ _null_ _null_ jsonb_jsonpath_query_safe3 _null_ _null_ _null_ ));
55415541
DESCR("jsonpath query, empty on error");
5542+
DATA(insert OID = 6073 ( _jsonpath_predicate PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 16 "3802 6050" _null_ _null_ _null_ _null_ _null_ jsonb_jsonpath_predicate2 _null_ _null_ _null_ ));
5543+
DESCR("jsonpath predicate test");
5544+
DATA(insert OID = 6074 ( _jsonpath_predicate PGNSP PGUID 12 1 0 0 0 f f f f t f i s 3 0 16 "3802 6050 3802" _null_ _null_ _null_ _null_ _null_ jsonb_jsonpath_predicate3 _null_ _null_ _null_ ));
5545+
DESCR("jsonpath predicate test");
55425546

55435547
/*
55445548
* Symbolic values for provolatile column: these indicate whether the result

src/test/regress/expected/jsonb_jsonpath.out

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

813+
select _jsonpath_predicate(jsonb '2', '$ > 1');
814+
_jsonpath_predicate
815+
---------------------
816+
t
817+
(1 row)
818+
819+
select _jsonpath_predicate(jsonb '2', '$ <= 1');
820+
_jsonpath_predicate
821+
---------------------
822+
f
823+
(1 row)
824+
825+
select _jsonpath_predicate(jsonb '2', '$ == "2"');
826+
_jsonpath_predicate
827+
---------------------
828+
829+
(1 row)
830+
831+
select _jsonpath_predicate(jsonb '2', '1');
832+
_jsonpath_predicate
833+
---------------------
834+
835+
(1 row)
836+
837+
select _jsonpath_predicate(jsonb '{}', '$');
838+
_jsonpath_predicate
839+
---------------------
840+
841+
(1 row)
842+
843+
select _jsonpath_predicate(jsonb '[]', '$');
844+
_jsonpath_predicate
845+
---------------------
846+
847+
(1 row)
848+
849+
select _jsonpath_predicate(jsonb '[1,2,3]', '$[*]');
850+
ERROR: Singleton SQL/JSON item required
851+
select _jsonpath_predicate(jsonb '[]', '$[*]');
852+
ERROR: Singleton SQL/JSON item required
853+
select _jsonpath_predicate(jsonb '[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}');
854+
_jsonpath_predicate
855+
---------------------
856+
f
857+
(1 row)
858+
859+
select _jsonpath_predicate(jsonb '[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}');
860+
_jsonpath_predicate
861+
---------------------
862+
t
863+
(1 row)
864+
813865
select _jsonpath_query(jsonb '[null,1,true,"a",[],{}]', '$.type()');
814866
_jsonpath_query
815867
-----------------

src/test/regress/sql/jsonb_jsonpath.sql

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

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

0 commit comments

Comments
 (0)