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

Commit 58c3265

Browse files
author
Nikita Glukhov
committed
Add jsonpath IS UNKNOWN predicate
1 parent 4837e2a commit 58c3265

File tree

8 files changed

+46
-3
lines changed

8 files changed

+46
-3
lines changed

src/backend/utils/adt/jsonpath.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,12 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracket
288288
printJsonPathItem(buf, &elem, false, false);
289289
appendStringInfoChar(buf, ')');
290290
break;
291+
case jpiIsUnknown:
292+
appendStringInfoChar(buf, '(');
293+
jspGetArg(v, &elem);
294+
printJsonPathItem(buf, &elem, false, false);
295+
appendBinaryStringInfo(buf, ") is unknown", 12);
296+
break;
291297
case jpiCurrent:
292298
Assert(!inKey);
293299
appendStringInfoChar(buf, '@');

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,18 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
488488
break;
489489
}
490490
break;
491+
case jpiIsUnknown:
492+
jspGetArg(jsp, &elem);
493+
switch ((res = recursiveExecute(&elem, vars, jb, NULL)))
494+
{
495+
case jperError:
496+
res = jperOk;
497+
break;
498+
default:
499+
res = jperNotFound;
500+
break;
501+
}
502+
break;
491503
case jpiKey:
492504
if (JsonbType(jb) == jbvObject)
493505
{

src/backend/utils/adt/jsonpath_gram.y

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ makeAny(int first, int last)
207207
int optype;
208208
}
209209

210-
%token <str> TO_P NULL_P TRUE_P FALSE_P
210+
%token <str> TO_P NULL_P TRUE_P FALSE_P IS_P UNKNOWN_P
211211
%token <str> STRING_P NUMERIC_P INT_P VARIABLE_P
212212
%token <str> OR_P AND_P NOT_P
213213
%token <str> LESS_P LESSEQUAL_P EQUAL_P NOTEQUAL_P GREATEREQUAL_P GREATER_P
@@ -241,6 +241,8 @@ result:
241241
scalar_value:
242242
STRING_P { $$ = makeItemString(&$1); }
243243
| TO_P { $$ = makeItemString(&$1); }
244+
| IS_P { $$ = makeItemString(&$1); }
245+
| UNKNOWN_P { $$ = makeItemString(&$1); }
244246
| NULL_P { $$ = makeItemString(NULL); }
245247
| TRUE_P { $$ = makeItemBool(true); }
246248
| FALSE_P { $$ = makeItemBool(false); }
@@ -283,7 +285,7 @@ predicate:
283285
// | expr STARTS WITH '$' STRING_P { $$ = ...; }
284286
// | expr STARTS WITH '$' STRING_P { $$ = ...; }
285287
// | '.' any_key right_expr { $$ = makeItemList(list_make2($2, $3)); }
286-
// | '(' predicate ')' IS UNKNOWN { $$ = makeItemUnary(jpiIsUnknown, $2); }
288+
| '(' predicate ')' IS_P UNKNOWN_P { $$ = makeItemUnary(jpiIsUnknown, $2); }
287289
| predicate AND_P predicate { $$ = makeItemBinary(jpiAnd, $1, $3); }
288290
| predicate OR_P predicate { $$ = makeItemBinary(jpiOr, $1, $3); }
289291
| NOT_P delimited_predicate { $$ = makeItemUnary(jpiNot, $2); }

src/backend/utils/adt/jsonpath_scan.l

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,12 @@ typedef struct keyword
270270
*/
271271

272272
static keyword keywords[] = {
273+
{ 2, true, IS_P, "is"},
273274
{ 2, false, TO_P, "to"},
274275
{ 4, true, NULL_P, "null"},
275276
{ 4, true, TRUE_P, "true"},
276-
{ 5, true, FALSE_P, "false"}
277+
{ 5, true, FALSE_P, "false"},
278+
{ 7, true, UNKNOWN_P, "unknown"},
277279
};
278280

279281
static int

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ select _jsonpath_exists(jsonb '{"a": [1,2,3], "b": [3,4,null]}', '$ ? (@.a[*] >=
106106
t
107107
(1 row)
108108

109+
select _jsonpath_exists(jsonb '1', '$ ? ((@ == "1") is unknown)');
110+
_jsonpath_exists
111+
------------------
112+
t
113+
(1 row)
114+
115+
select _jsonpath_exists(jsonb '1', '$ ? ((@ == 1) is unknown)');
116+
_jsonpath_exists
117+
------------------
118+
f
119+
(1 row)
120+
109121
select * from _jsonpath_query(jsonb '{"a": 12, "b": {"a": 13}}', '$.a');
110122
_jsonpath_query
111123
-----------------

src/test/regress/expected/jsonpath.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ select '$.g ? (.x >= @[*]?(@.a > "abc"))'::jsonpath;
225225
$."g"?(@."x" >= @[*]?(@."a" > "abc"))
226226
(1 row)
227227

228+
select '$.g ? ((x >= 123 || a == 4) is unknown)'::jsonpath;
229+
jsonpath
230+
---------------------------------------------
231+
$."g"?(("x" >= 123 || "a" == 4) is unknown)
232+
(1 row)
233+
228234
select '$.g ? (zip == $zip)'::jsonpath;
229235
jsonpath
230236
-------------------------

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ select _jsonpath_exists(jsonb '{"a": [1,2,3], "b": [3,4,5]}', '$ ? (@.a[*] > @.
1717
select _jsonpath_exists(jsonb '{"a": [1,2,3], "b": [3,4,5]}', '$ ? (@.a[*] >= @.b[*])');
1818
select _jsonpath_exists(jsonb '{"a": [1,2,3], "b": [3,4,"5"]}', '$ ? (@.a[*] >= @.b[*])');
1919
select _jsonpath_exists(jsonb '{"a": [1,2,3], "b": [3,4,null]}', '$ ? (@.a[*] >= @.b[*])');
20+
select _jsonpath_exists(jsonb '1', '$ ? ((@ == "1") is unknown)');
21+
select _jsonpath_exists(jsonb '1', '$ ? ((@ == 1) is unknown)');
2022

2123
select * from _jsonpath_query(jsonb '{"a": 12, "b": {"a": 13}}', '$.a');
2224
select * from _jsonpath_query(jsonb '{"a": 12, "b": {"a": 13}}', '$.b');

src/test/regress/sql/jsonpath.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ select '$.g ? (@.a == 1 || a == 4 && b == 7)'::jsonpath;
3939
select '$.g ? (@.a == 1 || !(a == 4) && b == 7)'::jsonpath;
4040
select '$.g ? (@.a == 1 || !(x >= 123 || a == 4) && b == 7)'::jsonpath;
4141
select '$.g ? (.x >= @[*]?(@.a > "abc"))'::jsonpath;
42+
select '$.g ? ((x >= 123 || a == 4) is unknown)'::jsonpath;
4243

4344
select '$.g ? (zip == $zip)'::jsonpath;
4445
select '$.a.[1,2, 3 to 16]'::jsonpath;

0 commit comments

Comments
 (0)