Skip to content

Commit f1ebe1c

Browse files
committed
correct work for logical expression in ~~
1 parent a2ed982 commit f1ebe1c

File tree

3 files changed

+160
-8
lines changed

3 files changed

+160
-8
lines changed

expected/jsquery.out

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,90 @@ select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.g and b.d';
19041904
f
19051905
(1 row)
19061906

1907+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and b.d';
1908+
?column?
1909+
----------
1910+
[1, 3]
1911+
(1 row)
1912+
1913+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and b.c';
1914+
?column?
1915+
----------
1916+
1917+
(1 row)
1918+
1919+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and (b.d or b.c)';
1920+
?column?
1921+
----------
1922+
[1, 3]
1923+
(1 row)
1924+
1925+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and (b.c or b.d)';
1926+
?column?
1927+
----------
1928+
[1, 3]
1929+
(1 row)
1930+
1931+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and a.c and b.d';
1932+
?column?
1933+
-----------
1934+
[1, 2, 3]
1935+
(1 row)
1936+
1937+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.b or a.c) and b.d';
1938+
?column?
1939+
----------
1940+
[1, 3]
1941+
(1 row)
1942+
1943+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.e or a.c) and b.d';
1944+
?column?
1945+
----------
1946+
[2, 3]
1947+
(1 row)
1948+
1949+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.e or a.g) and b.d';
1950+
?column?
1951+
----------
1952+
1953+
(1 row)
1954+
1955+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b or (b.d or b.c)';
1956+
?column?
1957+
----------
1958+
[1]
1959+
(1 row)
1960+
1961+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d or (a.b or a.c)';
1962+
?column?
1963+
----------
1964+
[3]
1965+
(1 row)
1966+
1967+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d or (a.b and a.c)';
1968+
?column?
1969+
----------
1970+
[3]
1971+
(1 row)
1972+
1973+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.f or (a.b and a.c)';
1974+
?column?
1975+
----------
1976+
[1, 2]
1977+
(1 row)
1978+
1979+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d and (a.b and a.c)';
1980+
?column?
1981+
-----------
1982+
[3, 1, 2]
1983+
(1 row)
1984+
1985+
select '{"a": {"b": [6,5,4], "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d and (a.b and a.c)';
1986+
?column?
1987+
-------------------
1988+
[3, [6, 5, 4], 2]
1989+
(1 row)
1990+
19071991
--extract entries for index scan
19081992
SELECT gin_debug_query_path_value('NOT NOT NOT x(y(NOT (a=1) and NOT (b=2)) OR NOT NOT (c=3)) and z = 5');
19091993
gin_debug_query_path_value

jsquery_op.c

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,27 @@ appendResult(ResultAccum *ra, JsonbValue *jb)
5151
pushJsonbValue(&ra->jbArrayState, WJB_ELEM, jb);
5252
}
5353

54+
static void
55+
concatResult(ResultAccum *ra, JsonbParseState *a, JsonbParseState *b)
56+
{
57+
Jsonb *value;
58+
JsonbIterator *it;
59+
int32 r;
60+
JsonbValue v;
61+
62+
Assert(a);
63+
Assert(b);
64+
65+
ra->jbArrayState = a;
66+
67+
value = JsonbValueToJsonb(pushJsonbValue(&b, WJB_END_ARRAY, NULL));
68+
it = JsonbIteratorInit(&value->root);
69+
70+
while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
71+
if (r == WJB_ELEM)
72+
pushJsonbValue(&ra->jbArrayState, WJB_ELEM, &v);
73+
}
74+
5475
static int
5576
compareNumeric(Numeric a, Numeric b)
5677
{
@@ -435,14 +456,37 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg,
435456

436457
switch(jsq->type) {
437458
case jqiAnd:
438-
jsqGetLeftArg(jsq, &elem);
439-
res = recursiveExecute(&elem, jb, jsqLeftArg, ra);
440-
if (res == true)
441459
{
442-
jsqGetRightArg(jsq, &elem);
460+
JsonbParseState *saveJbArrayState = NULL;
461+
462+
jsqGetLeftArg(jsq, &elem);
463+
if (ra && ra->missAppend == false)
464+
{
465+
saveJbArrayState = ra->jbArrayState;
466+
ra->jbArrayState = NULL;
467+
}
468+
443469
res = recursiveExecute(&elem, jb, jsqLeftArg, ra);
470+
if (res == true)
471+
{
472+
jsqGetRightArg(jsq, &elem);
473+
res = recursiveExecute(&elem, jb, jsqLeftArg, ra);
474+
}
475+
476+
if (ra && ra->missAppend == false)
477+
{
478+
if (res == true)
479+
{
480+
if (saveJbArrayState != NULL)
481+
/* append args lists to current */
482+
concatResult(ra, saveJbArrayState, ra->jbArrayState);
483+
}
484+
else
485+
ra->jbArrayState = saveJbArrayState;
486+
}
487+
488+
break;
444489
}
445-
break;
446490
case jqiOr:
447491
jsqGetLeftArg(jsq, &elem);
448492
res = recursiveExecute(&elem, jb, jsqLeftArg, ra);
@@ -453,9 +497,18 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg,
453497
}
454498
break;
455499
case jqiNot:
456-
jsqGetArg(jsq, &elem);
457-
res = !recursiveExecute(&elem, jb, jsqLeftArg, ra);
458-
break;
500+
{
501+
bool saveMissAppend = (ra) ? ra->missAppend : true;
502+
503+
jsqGetArg(jsq, &elem);
504+
if (ra)
505+
ra->missAppend = true;
506+
res = !recursiveExecute(&elem, jb, jsqLeftArg, ra);
507+
if (ra)
508+
ra->missAppend = saveMissAppend;
509+
510+
break;
511+
}
459512
case jqiKey:
460513
if (JsonbType(jb) == jbvObject) {
461514
JsonbValue *v, key;

sql/jsquery.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,21 @@ select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.c and b.d';
378378
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.c and b.b';
379379
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.g and b.d';
380380

381+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and b.d';
382+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and b.c';
383+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and (b.d or b.c)';
384+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and (b.c or b.d)';
385+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and a.c and b.d';
386+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.b or a.c) and b.d';
387+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.e or a.c) and b.d';
388+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.e or a.g) and b.d';
389+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b or (b.d or b.c)';
390+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d or (a.b or a.c)';
391+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d or (a.b and a.c)';
392+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.f or (a.b and a.c)';
393+
select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d and (a.b and a.c)';
394+
select '{"a": {"b": [6,5,4], "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d and (a.b and a.c)';
395+
381396
--extract entries for index scan
382397

383398
SELECT gin_debug_query_path_value('NOT NOT NOT x(y(NOT (a=1) and NOT (b=2)) OR NOT NOT (c=3)) and z = 5');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy