Skip to content

Commit 5bf859c

Browse files
author
Alexander Korotkov
committed
Handle paths without operators in indexes.
1 parent 0c5bb5c commit 5bf859c

File tree

3 files changed

+116
-6
lines changed

3 files changed

+116
-6
lines changed

Diff for: expected/jsquery.out

+68
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,13 @@ SELECT gin_debug_query_path_value('NOT #:(NOT x=1) AND NOT %:(NOT y=1) AND NOT *
21652165

21662166
(1 row)
21672167

2168+
SELECT gin_debug_query_path_value('$ = true');
2169+
gin_debug_query_path_value
2170+
----------------------------
2171+
$ = true , entry 0 +
2172+
2173+
(1 row)
2174+
21682175
SELECT gin_debug_query_value_path('NOT NOT NOT x(y(NOT (a=1) and NOT (b=2)) OR NOT NOT (c=3)) and z = 5');
21692176
gin_debug_query_value_path
21702177
----------------------------
@@ -2375,6 +2382,13 @@ SELECT gin_debug_query_value_path('tags.#.term. ? ( # = "NYC").x > 0');
23752382

23762383
(1 row)
23772384

2385+
SELECT gin_debug_query_path_value('$ = true');
2386+
gin_debug_query_path_value
2387+
----------------------------
2388+
$ = true , entry 0 +
2389+
2390+
(1 row)
2391+
23782392
---table and index
23792393
select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 > 0;
23802394
count
@@ -2624,6 +2638,24 @@ select count(*) from test_jsquery where v @@ '$ = false';
26242638
2
26252639
(1 row)
26262640

2641+
select count(*) from test_jsquery where v @@ 't';
2642+
count
2643+
-------
2644+
10
2645+
(1 row)
2646+
2647+
select count(*) from test_jsquery where v @@ '$';
2648+
count
2649+
-------
2650+
1034
2651+
(1 row)
2652+
2653+
select count(*) from test_jsquery where v @@ 'similar_product_ids.#';
2654+
count
2655+
-------
2656+
1001
2657+
(1 row)
2658+
26272659
select v from test_jsquery where v @@ 'array <@ [2,3]' order by v;
26282660
v
26292661
-------------------
@@ -2872,6 +2904,24 @@ select count(*) from test_jsquery where v @@ '$ = false';
28722904
2
28732905
(1 row)
28742906

2907+
select count(*) from test_jsquery where v @@ 't';
2908+
count
2909+
-------
2910+
10
2911+
(1 row)
2912+
2913+
select count(*) from test_jsquery where v @@ '$';
2914+
count
2915+
-------
2916+
1034
2917+
(1 row)
2918+
2919+
select count(*) from test_jsquery where v @@ 'similar_product_ids.#';
2920+
count
2921+
-------
2922+
1001
2923+
(1 row)
2924+
28752925
explain (costs off) select v from test_jsquery where v @@ 'array <@ [2,3]' order by v;
28762926
QUERY PLAN
28772927
---------------------------------------------------------------
@@ -3165,6 +3215,24 @@ select count(*) from test_jsquery where v @@ '$ = false';
31653215
2
31663216
(1 row)
31673217

3218+
select count(*) from test_jsquery where v @@ 't';
3219+
count
3220+
-------
3221+
10
3222+
(1 row)
3223+
3224+
select count(*) from test_jsquery where v @@ '$';
3225+
count
3226+
-------
3227+
1034
3228+
(1 row)
3229+
3230+
select count(*) from test_jsquery where v @@ 'similar_product_ids.#';
3231+
count
3232+
-------
3233+
950
3234+
(1 row)
3235+
31683236
explain (costs off) select v from test_jsquery where v @@ 'array <@ [2,3]' order by v;
31693237
QUERY PLAN
31703238
---------------------------------------------------------------

Diff for: jsquery_extract.c

+37-6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "jsquery.h"
2323

2424
static ExtractedNode *recursiveExtract(JsQueryItem *jsq, bool not, bool indirect, PathItem *path);
25+
static ExtractedNode *makeAnyNode(bool not, bool indirect, PathItem *path);
2526
static int coundChildren(ExtractedNode *node, ExtractedNodeType type, bool first, bool *found);
2627
static void fillChildren(ExtractedNode *node, ExtractedNodeType type, bool first, ExtractedNode **items, int *i);
2728
static void flatternTree(ExtractedNode *node);
@@ -95,7 +96,8 @@ recursiveExtract(JsQueryItem *jsq, bool not, bool indirect, PathItem *path)
9596
pathItem->type = iKey;
9697
pathItem->s = jsqGetString(jsq, &pathItem->len);
9798
pathItem->parent = path;
98-
jsqGetNext(jsq, &elem);
99+
if (!jsqGetNext(jsq, &elem))
100+
return makeAnyNode(not, indirect, pathItem);
99101
return recursiveExtract(&elem, not, indirect, pathItem);
100102
case jqiAny:
101103
case jqiAll:
@@ -104,14 +106,16 @@ recursiveExtract(JsQueryItem *jsq, bool not, bool indirect, PathItem *path)
104106
pathItem = (PathItem *)palloc(sizeof(PathItem));
105107
pathItem->type = iAny;
106108
pathItem->parent = path;
107-
jsqGetNext(jsq, &elem);
109+
if (!jsqGetNext(jsq, &elem))
110+
return makeAnyNode(not, indirect, pathItem);
108111
return recursiveExtract(&elem, not, true, pathItem);
109112
case jqiIndexArray:
110113
pathItem = (PathItem *)palloc(sizeof(PathItem));
111114
pathItem->type = iIndexArray;
112115
pathItem->arrayIndex = jsq->arrayIndex;
113116
pathItem->parent = path;
114-
jsqGetNext(jsq, &elem);
117+
if (!jsqGetNext(jsq, &elem))
118+
return makeAnyNode(not, indirect, pathItem);
115119
return recursiveExtract(&elem, not, true, pathItem);
116120
case jqiAnyArray:
117121
case jqiAllArray:
@@ -120,7 +124,8 @@ recursiveExtract(JsQueryItem *jsq, bool not, bool indirect, PathItem *path)
120124
pathItem = (PathItem *)palloc(sizeof(PathItem));
121125
pathItem->type = iAnyArray;
122126
pathItem->parent = path;
123-
jsqGetNext(jsq, &elem);
127+
if (!jsqGetNext(jsq, &elem))
128+
return makeAnyNode(not, indirect, pathItem);
124129
return recursiveExtract(&elem, not, true, pathItem);
125130
case jqiAnyKey:
126131
case jqiAllKey:
@@ -129,12 +134,14 @@ recursiveExtract(JsQueryItem *jsq, bool not, bool indirect, PathItem *path)
129134
pathItem = (PathItem *)palloc(sizeof(PathItem));
130135
pathItem->type = iAnyKey;
131136
pathItem->parent = path;
132-
jsqGetNext(jsq, &elem);
137+
if (!jsqGetNext(jsq, &elem))
138+
return makeAnyNode(not, indirect, pathItem);
133139
return recursiveExtract(&elem, not, true, pathItem);
134140
case jqiFilter:
135141
/* ignore filter for now */
136142
case jqiCurrent:
137-
jsqGetNext(jsq, &elem);
143+
if (!jsqGetNext(jsq, &elem))
144+
return makeAnyNode(not, indirect, path);
138145
return recursiveExtract(&elem, not, indirect, path);
139146
case jqiEqual:
140147
if (not)
@@ -264,6 +271,25 @@ recursiveExtract(JsQueryItem *jsq, bool not, bool indirect, PathItem *path)
264271
return NULL;
265272
}
266273

274+
/*
275+
* Make node for checking existence of path.
276+
*/
277+
static ExtractedNode *
278+
makeAnyNode(bool not, bool indirect, PathItem *path)
279+
{
280+
ExtractedNode *result;
281+
282+
if (not)
283+
return NULL;
284+
285+
result = (ExtractedNode *) palloc(sizeof(ExtractedNode));
286+
result->type = eAny;
287+
result->hint = false;
288+
result->path = path;
289+
result->indirect = indirect;
290+
return result;
291+
}
292+
267293
/*
268294
* Count number of children connected with nodes of same type.
269295
*/
@@ -857,6 +883,11 @@ execRecursiveTristate(ExtractedNode *node, GinTernaryValue *check)
857883
static void
858884
debugPath(StringInfo buf, PathItem *path)
859885
{
886+
if (!path)
887+
{
888+
appendStringInfoChar(buf, '$');
889+
return;
890+
}
860891
if (path->parent)
861892
{
862893
debugPath(buf, path->parent);

Diff for: sql/jsquery.sql

+11
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ SELECT gin_debug_query_path_value('x is object');
417417
SELECT gin_debug_query_path_value('#:(x=1) AND %:(y=1) AND *:(z=1)');
418418
SELECT gin_debug_query_path_value('#:(NOT x=1) AND %:(NOT y=1) AND *:(NOT z=1)');
419419
SELECT gin_debug_query_path_value('NOT #:(NOT x=1) AND NOT %:(NOT y=1) AND NOT *:(NOT z=1)');
420+
SELECT gin_debug_query_path_value('$ = true');
420421

421422
SELECT gin_debug_query_value_path('NOT NOT NOT x(y(NOT (a=1) and NOT (b=2)) OR NOT NOT (c=3)) and z = 5');
422423
SELECT gin_debug_query_value_path('NOT #(x=1) and NOT *(y=1) and NOT %(z=1) ');
@@ -444,6 +445,7 @@ SELECT gin_debug_query_value_path('NOT #:(NOT x=1) AND NOT %:(NOT y=1) AND NOT *
444445
SELECT gin_debug_query_value_path('(@# > 0 and #: = 16)');
445446
SELECT gin_debug_query_value_path('*.@# ($ = 4 or $ = 2)');
446447
SELECT gin_debug_query_value_path('tags.#.term. ? ( # = "NYC").x > 0');
448+
SELECT gin_debug_query_path_value('$ = true');
447449

448450
---table and index
449451

@@ -492,6 +494,9 @@ select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is string';
492494
select count(*) from test_jsquery where v @@ 'NOT similar_product_ids.#: (NOT $ = "0440180295")';
493495
select count(*) from test_jsquery where v @@ '$ > 2';
494496
select count(*) from test_jsquery where v @@ '$ = false';
497+
select count(*) from test_jsquery where v @@ 't';
498+
select count(*) from test_jsquery where v @@ '$';
499+
select count(*) from test_jsquery where v @@ 'similar_product_ids.#';
495500

496501
select v from test_jsquery where v @@ 'array <@ [2,3]' order by v;
497502
select v from test_jsquery where v @@ 'array && [2,3]' order by v;
@@ -538,6 +543,9 @@ select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is string';
538543
select count(*) from test_jsquery where v @@ 'NOT similar_product_ids.#: (NOT $ = "0440180295")';
539544
select count(*) from test_jsquery where v @@ '$ > 2';
540545
select count(*) from test_jsquery where v @@ '$ = false';
546+
select count(*) from test_jsquery where v @@ 't';
547+
select count(*) from test_jsquery where v @@ '$';
548+
select count(*) from test_jsquery where v @@ 'similar_product_ids.#';
541549

542550
explain (costs off) select v from test_jsquery where v @@ 'array <@ [2,3]' order by v;
543551
explain (costs off) select v from test_jsquery where v @@ 'array && [2,3]' order by v;
@@ -591,6 +599,9 @@ select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is string';
591599
select count(*) from test_jsquery where v @@ 'NOT similar_product_ids.#: (NOT $ = "0440180295")';
592600
select count(*) from test_jsquery where v @@ '$ > 2';
593601
select count(*) from test_jsquery where v @@ '$ = false';
602+
select count(*) from test_jsquery where v @@ 't';
603+
select count(*) from test_jsquery where v @@ '$';
604+
select count(*) from test_jsquery where v @@ 'similar_product_ids.#';
594605

595606
explain (costs off) select v from test_jsquery where v @@ 'array <@ [2,3]' order by v;
596607
explain (costs off) select v from test_jsquery where v @@ 'array && [2,3]' order by v;

0 commit comments

Comments
 (0)