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

Commit 9488737

Browse files
author
Nikita Glukhov
committed
Add _jsonpath_predicate()
1 parent 0815037 commit 9488737

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
@@ -2396,6 +2396,52 @@ jsonb_jsonpath_exists3(PG_FUNCTION_ARGS)
23962396
return jsonb_jsonpath_exists(fcinfo);
23972397
}
23982398

2399+
static inline Datum
2400+
jsonb_jsonpath_predicate(FunctionCallInfo fcinfo, List *vars)
2401+
{
2402+
Jsonb *jb = PG_GETARG_JSONB_P(0);
2403+
JsonPath *jp = PG_GETARG_JSONPATH_P(1);
2404+
JsonbValue *jbv;
2405+
JsonValueList found = { 0 };
2406+
JsonPathExecResult res;
2407+
2408+
res = executeJsonPath(jp, vars, jb, &found);
2409+
2410+
throwJsonPathError(res);
2411+
2412+
if (JsonValueListLength(&found) != 1)
2413+
throwJsonPathError(jperMakeError(ERRCODE_SINGLETON_JSON_ITEM_REQUIRED));
2414+
2415+
jbv = JsonValueListHead(&found);
2416+
2417+
if (JsonbType(jbv) == jbvScalar)
2418+
JsonbExtractScalar(jbv->val.binary.data, jbv);
2419+
2420+
PG_FREE_IF_COPY(jb, 0);
2421+
PG_FREE_IF_COPY(jp, 1);
2422+
2423+
if (jbv->type == jbvNull)
2424+
PG_RETURN_NULL();
2425+
2426+
if (jbv->type != jbvBool)
2427+
PG_RETURN_NULL(); /* XXX */
2428+
2429+
PG_RETURN_BOOL(jbv->val.boolean);
2430+
}
2431+
2432+
Datum
2433+
jsonb_jsonpath_predicate2(PG_FUNCTION_ARGS)
2434+
{
2435+
return jsonb_jsonpath_predicate(fcinfo, NIL);
2436+
}
2437+
2438+
Datum
2439+
jsonb_jsonpath_predicate3(PG_FUNCTION_ARGS)
2440+
{
2441+
return jsonb_jsonpath_predicate(fcinfo,
2442+
makePassingVars(PG_GETARG_JSONB_P(2)));
2443+
}
2444+
23992445
static Datum
24002446
jsonb_jsonpath_query(FunctionCallInfo fcinfo, bool safe)
24012447
{

src/include/catalog/pg_proc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5543,6 +5543,10 @@ DATA(insert OID = 6058 ( _jsonpath_query_safe PGNSP PGUID 12 1 1000 0 0 f f f
55435543
DESCR("jsonpath query, empty on error");
55445544
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_ ));
55455545
DESCR("jsonpath query, empty on error");
5546+
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_ ));
5547+
DESCR("jsonpath predicate test");
5548+
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_ ));
5549+
DESCR("jsonpath predicate test");
55465550

55475551
/*
55485552
* 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)