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

Commit 22f3b13

Browse files
author
Nikita Glukhov
committed
Fix jsonpath ternary logic
1 parent 8050541 commit 22f3b13

File tree

3 files changed

+92
-13
lines changed

3 files changed

+92
-13
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -459,19 +459,27 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
459459
case jpiAnd:
460460
jspGetLeftArg(jsp, &elem);
461461
res = recursiveExecute(&elem, vars, jb, NULL);
462-
if (res == jperOk)
462+
if (res != jperNotFound)
463463
{
464+
JsonPathExecResult res2;
465+
464466
jspGetRightArg(jsp, &elem);
465-
res = recursiveExecute(&elem, vars, jb, NULL);
467+
res2 = recursiveExecute(&elem, vars, jb, NULL);
468+
469+
res = res2 == jperOk ? res : res2;
466470
}
467471
break;
468472
case jpiOr:
469473
jspGetLeftArg(jsp, &elem);
470474
res = recursiveExecute(&elem, vars, jb, NULL);
471-
if (res == jperNotFound)
475+
if (res != jperOk)
472476
{
477+
JsonPathExecResult res2;
478+
473479
jspGetRightArg(jsp, &elem);
474-
res = recursiveExecute(&elem, vars, jb, NULL);
480+
res2 = recursiveExecute(&elem, vars, jb, NULL);
481+
482+
res = res2 == jperNotFound ? res : res2;
475483
}
476484
break;
477485
case jpiNot:
@@ -490,15 +498,8 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
490498
break;
491499
case jpiIsUnknown:
492500
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-
}
501+
res = recursiveExecute(&elem, vars, jb, NULL);
502+
res = res == jperError ? jperOk : jperNotFound;
502503
break;
503504
case jpiKey:
504505
if (JsonbType(jb) == jbvObject)

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,3 +465,54 @@ select _jsonpath_query(jsonb '{"g": {"x": 2}}', '$.g ? (exists (@.x ? (@ >= 2) )
465465
{"x": 2}
466466
(1 row)
467467

468+
--test ternary logic
469+
select
470+
x, y,
471+
_jsonpath_query(
472+
jsonb '[true, false, null]',
473+
'$[*] ? (@ == true && ($x == true && $y == true) ||
474+
@ == false && !($x == true && $y == true) ||
475+
@ == null && ($x == true && $y == true) is unknown)',
476+
jsonb_build_object('x', x, 'y', y)
477+
) as "x && y"
478+
from
479+
(values (jsonb 'true'), ('false'), ('"null"')) x(x),
480+
(values (jsonb 'true'), ('false'), ('"null"')) y(y);
481+
x | y | x && y
482+
--------+--------+--------
483+
true | true | true
484+
true | false | false
485+
true | "null" | null
486+
false | true | false
487+
false | false | false
488+
false | "null" | false
489+
"null" | true | null
490+
"null" | false | false
491+
"null" | "null" | null
492+
(9 rows)
493+
494+
select
495+
x, y,
496+
_jsonpath_query(
497+
jsonb '[true, false, null]',
498+
'$[*] ? (@ == true && ($x == true || $y == true) ||
499+
@ == false && !($x == true || $y == true) ||
500+
@ == null && ($x == true || $y == true) is unknown)',
501+
jsonb_build_object('x', x, 'y', y)
502+
) as "x || y"
503+
from
504+
(values (jsonb 'true'), ('false'), ('"null"')) x(x),
505+
(values (jsonb 'true'), ('false'), ('"null"')) y(y);
506+
x | y | x || y
507+
--------+--------+--------
508+
true | true | true
509+
true | false | true
510+
true | "null" | true
511+
false | true | true
512+
false | false | false
513+
false | "null" | null
514+
"null" | true | true
515+
"null" | false | null
516+
"null" | "null" | null
517+
(9 rows)
518+

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,30 @@ select * from _jsonpath_exists(jsonb '{"a": {"c": {"b": 1}}}', '$.**{2,3}.b ? (@
8282
select _jsonpath_query(jsonb '{"g": {"x": 2}}', '$.g ? (exists (@.x))');
8383
select _jsonpath_query(jsonb '{"g": {"x": 2}}', '$.g ? (exists (@.y))');
8484
select _jsonpath_query(jsonb '{"g": {"x": 2}}', '$.g ? (exists (@.x ? (@ >= 2) ))');
85+
86+
--test ternary logic
87+
select
88+
x, y,
89+
_jsonpath_query(
90+
jsonb '[true, false, null]',
91+
'$[*] ? (@ == true && ($x == true && $y == true) ||
92+
@ == false && !($x == true && $y == true) ||
93+
@ == null && ($x == true && $y == true) is unknown)',
94+
jsonb_build_object('x', x, 'y', y)
95+
) as "x && y"
96+
from
97+
(values (jsonb 'true'), ('false'), ('"null"')) x(x),
98+
(values (jsonb 'true'), ('false'), ('"null"')) y(y);
99+
100+
select
101+
x, y,
102+
_jsonpath_query(
103+
jsonb '[true, false, null]',
104+
'$[*] ? (@ == true && ($x == true || $y == true) ||
105+
@ == false && !($x == true || $y == true) ||
106+
@ == null && ($x == true || $y == true) is unknown)',
107+
jsonb_build_object('x', x, 'y', y)
108+
) as "x || y"
109+
from
110+
(values (jsonb 'true'), ('false'), ('"null"')) x(x),
111+
(values (jsonb 'true'), ('false'), ('"null"')) y(y);

0 commit comments

Comments
 (0)