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

Commit 41ce840

Browse files
author
Nikita Glukhov
committed
Add _jsonpath_predicate()
1 parent 50d0693 commit 41ce840

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,51 @@ jsonb_jsonpath_exists3(PG_FUNCTION_ARGS)
21872187
return jsonb_jsonpath_exists(fcinfo);
21882188
}
21892189

2190+
static inline Datum
2191+
jsonb_jsonpath_predicate(FunctionCallInfo fcinfo, List *vars)
2192+
{
2193+
Jsonb *jb = PG_GETARG_JSONB(0);
2194+
JsonPath *jp = PG_GETARG_JSONPATH(1);
2195+
JsonbValue *jbv;
2196+
JsonValueList found = { 0 };
2197+
JsonPathExecResult res;
2198+
2199+
res = executeJsonPath(jp, vars, jb, &found);
2200+
2201+
throwJsonPathError(res);
2202+
2203+
if (JsonValueListLength(&found) != 1)
2204+
throwJsonPathError(jperMakeError(ERRCODE_SINGLETON_JSON_ITEM_REQUIRED));
2205+
2206+
jbv = JsonValueListHead(&found);
2207+
2208+
if (JsonbType(jbv) == jbvScalar)
2209+
JsonbExtractScalar(jbv->val.binary.data, jbv);
2210+
2211+
PG_FREE_IF_COPY(jb, 0);
2212+
PG_FREE_IF_COPY(jp, 1);
2213+
2214+
if (jbv->type == jbvNull)
2215+
PG_RETURN_NULL();
2216+
2217+
if (jbv->type != jbvBool)
2218+
PG_RETURN_NULL(); /* XXX */
2219+
2220+
PG_RETURN_BOOL(jbv->val.boolean);
2221+
}
2222+
2223+
Datum
2224+
jsonb_jsonpath_predicate2(PG_FUNCTION_ARGS)
2225+
{
2226+
return jsonb_jsonpath_predicate(fcinfo, NIL);
2227+
}
2228+
2229+
Datum
2230+
jsonb_jsonpath_predicate3(PG_FUNCTION_ARGS)
2231+
{
2232+
return jsonb_jsonpath_predicate(fcinfo, makePassingVars(PG_GETARG_JSONB(2)));
2233+
}
2234+
21902235
static Datum
21912236
jsonb_jsonpath_query(FunctionCallInfo fcinfo, bool safe)
21922237
{

src/include/catalog/pg_proc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5492,6 +5492,10 @@ DATA(insert OID = 6058 ( _jsonpath_query_safe PGNSP PGUID 12 1 1000 0 0 f f f
54925492
DESCR("jsonpath query, empty on error");
54935493
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_ ));
54945494
DESCR("jsonpath query, empty on error");
5495+
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_ ));
5496+
DESCR("jsonpath predicate test");
5497+
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_ ));
5498+
DESCR("jsonpath predicate test");
54955499

54965500
/*
54975501
* 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
@@ -794,6 +794,58 @@ select _jsonpath_query(jsonb '2', '$ == "2"');
794794
null
795795
(1 row)
796796

797+
select _jsonpath_predicate(jsonb '2', '$ > 1');
798+
_jsonpath_predicate
799+
---------------------
800+
t
801+
(1 row)
802+
803+
select _jsonpath_predicate(jsonb '2', '$ <= 1');
804+
_jsonpath_predicate
805+
---------------------
806+
f
807+
(1 row)
808+
809+
select _jsonpath_predicate(jsonb '2', '$ == "2"');
810+
_jsonpath_predicate
811+
---------------------
812+
813+
(1 row)
814+
815+
select _jsonpath_predicate(jsonb '2', '1');
816+
_jsonpath_predicate
817+
---------------------
818+
819+
(1 row)
820+
821+
select _jsonpath_predicate(jsonb '{}', '$');
822+
_jsonpath_predicate
823+
---------------------
824+
825+
(1 row)
826+
827+
select _jsonpath_predicate(jsonb '[]', '$');
828+
_jsonpath_predicate
829+
---------------------
830+
831+
(1 row)
832+
833+
select _jsonpath_predicate(jsonb '[1,2,3]', '$[*]');
834+
ERROR: Singleton SQL/JSON item required
835+
select _jsonpath_predicate(jsonb '[]', '$[*]');
836+
ERROR: Singleton SQL/JSON item required
837+
select _jsonpath_predicate(jsonb '[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}');
838+
_jsonpath_predicate
839+
---------------------
840+
f
841+
(1 row)
842+
843+
select _jsonpath_predicate(jsonb '[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}');
844+
_jsonpath_predicate
845+
---------------------
846+
t
847+
(1 row)
848+
797849
select _jsonpath_query(jsonb '[null,1,true,"a",[],{}]', '$.type()');
798850
_jsonpath_query
799851
-----------------

src/test/regress/sql/jsonb_jsonpath.sql

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

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

0 commit comments

Comments
 (0)