From 615894b361ae14e4f6e4b3074d88cc653eb5bdde Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Mon, 24 Aug 2026 13:59:53 +0300 Subject: [PATCH 1/8] Refactoring: remove never used field. --- jsquery_op.c | 1 - 1 file changed, 1 deletion(-) diff --git a/jsquery_op.c b/jsquery_op.c index 29cfe3d..cdeb0b1 100644 --- a/jsquery_op.c +++ b/jsquery_op.c @@ -31,7 +31,6 @@ #include "jsquery.h" typedef struct ResultAccum { - StringInfo buf; bool missAppend; JsonbParseState *jbArrayState; } ResultAccum; From 54a169011dcc5dc1ee5a27b5cc1117c54b3c03e5 Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Mon, 24 Aug 2026 14:02:34 +0300 Subject: [PATCH 2/8] Refactoring before adapting to new Jsonb API. 1. Add initializing and finalizing functions for ResultAccum. 2. Rename functions working with ResultAccum. 3. Hide all ResultAccum guts in 4 functions: - raInitialize - raFinalize - raAppendElement - raAppendArray 4. Let "jbArrayState" be always initialized (not NULL). --- jsquery_op.c | 113 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/jsquery_op.c b/jsquery_op.c index cdeb0b1..f3b76fd 100644 --- a/jsquery_op.c +++ b/jsquery_op.c @@ -30,7 +30,9 @@ #include "jsquery.h" -typedef struct ResultAccum { +/* ResultAccum is used to accumulate values in a Jsonb array. */ +typedef struct ResultAccum +{ bool missAppend; JsonbParseState *jbArrayState; } ResultAccum; @@ -39,35 +41,63 @@ typedef struct ResultAccum { static bool recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, ResultAccum *ra); +/* + * Initialize ResultAccum with the opening WJB_BEGIN_ARRAY token. + */ static void -appendResult(ResultAccum *ra, JsonbValue *jb) +raInitialize(ResultAccum *ra) +{ + Assert(ra); + + memset(ra, 0, sizeof(*ra)); + pushJsonbValue(&ra->jbArrayState, WJB_BEGIN_ARRAY, NULL); +} + +/* + * Finalize ResultAccum with the closing WJB_END_ARRAY token, and return the + * resulting Jsonb. + */ +static Jsonb * +raFinalize(ResultAccum *ra) +{ + Assert(ra); + Assert(ra->jbArrayState); + + return JsonbValueToJsonb(pushJsonbValue(&ra->jbArrayState, WJB_END_ARRAY, NULL)); +} + +/* + * Append one element. + * Note: append only if "ra" is vaild and appendable; otherwise, do nothing. + */ +static void +raAppendElement(ResultAccum *ra, JsonbValue *jb) { if (ra == NULL || ra->missAppend == true) return; - if (ra->jbArrayState == NULL) - pushJsonbValue(&ra->jbArrayState, WJB_BEGIN_ARRAY, NULL); + Assert(ra->jbArrayState); pushJsonbValue(&ra->jbArrayState, WJB_ELEM, jb); } +/* + * Iterate over the Jsonb array and append its elements to "ra". + * Note: "ra" must be valid and appendable. + */ static void -concatResult(ResultAccum *ra, JsonbParseState *a, JsonbParseState *b) +raAppendArray(ResultAccum *ra, Jsonb *array) { - Jsonb *value; JsonbIterator *it; int32 r; JsonbValue v; - Assert(a); - Assert(b); - - ra->jbArrayState = a; + Assert(ra && ra->missAppend == false); + Assert(ra->jbArrayState); - value = JsonbValueToJsonb(pushJsonbValue(&b, WJB_END_ARRAY, NULL)); - it = JsonbIteratorInit(&value->root); + it = JsonbIteratorInit(&array->root); - while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) + while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) if (r == WJB_ELEM) pushJsonbValue(&ra->jbArrayState, WJB_ELEM, &v); } @@ -459,32 +489,35 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, switch(jsq->type) { case jqiAnd: { - JsonbParseState *saveJbArrayState = NULL; + /* + * Accumulate the array in "raTmp" if needed. Don't mess with + * "ra" in case the result turns out to be false. + */ + ResultAccum raTmpData; + ResultAccum *raTmp = NULL; - jsqGetLeftArg(jsq, &elem); if (ra && ra->missAppend == false) { - saveJbArrayState = ra->jbArrayState; - ra->jbArrayState = NULL; + /* need to accumulate */ + raTmp = &raTmpData; + raInitialize(raTmp); } - res = recursiveExecute(&elem, jb, jsqLeftArg, ra); + jsqGetLeftArg(jsq, &elem); + res = recursiveExecute(&elem, jb, jsqLeftArg, raTmp); if (res == true) { jsqGetRightArg(jsq, &elem); - res = recursiveExecute(&elem, jb, jsqLeftArg, ra); + res = recursiveExecute(&elem, jb, jsqLeftArg, raTmp); } + /* Append the array accumulated in "raTmp" to "ra" if needed. */ if (ra && ra->missAppend == false) { + Jsonb *array = raFinalize(raTmp); + if (res == true) - { - if (saveJbArrayState != NULL) - /* append args lists to current */ - concatResult(ra, saveJbArrayState, ra->jbArrayState); - } - else - ra->jbArrayState = saveJbArrayState; + raAppendArray(ra, array); } break; @@ -524,7 +557,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, { if (jsqGetNext(jsq, &elem) == false) { - appendResult(ra, v); + raAppendElement(ra, v); res = true; } else @@ -536,7 +569,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, case jqiCurrent: if (jsqGetNext(jsq, &elem) == false) { - appendResult(ra, jb); + raAppendElement(ra, jb); res = true; } else if (JsonbType(jb) == jbvScalar) @@ -566,7 +599,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, if (jsqGetNext(jsq, &elem) == false) { res = true; - appendResult(ra, jb); + raAppendElement(ra, jb); } else if (recursiveExecute(&elem, jb, NULL, ra)) res = true; @@ -577,7 +610,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, if (jsqGetNext(jsq, &elem) == false) { res = true; - appendResult(ra, jb); + raAppendElement(ra, jb); } if ((res = recursiveExecute(&elem, jb, NULL, ra)) == true) { @@ -604,7 +637,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, while(ra && (r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) if (r == WJB_ELEM) - appendResult(ra, &v); + raAppendElement(ra, &v); break; } @@ -650,7 +683,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, if (jsqGetNext(jsq, &elem) == false) { res = true; - appendResult(ra, v); + raAppendElement(ra, v); } else res = recursiveExecute(&elem, v, NULL, ra); @@ -676,7 +709,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, while(ra && (r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) if (r == WJB_VALUE) - appendResult(ra, &v); + raAppendElement(ra, &v); break; } @@ -762,7 +795,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, if (res) { if (jsqGetNext(jsq, &elem) == false) { - appendResult(ra, jb); + raAppendElement(ra, jb); res = true; } else @@ -841,21 +874,17 @@ json_jsquery_filter(PG_FUNCTION_ARGS) jbv.val.binary.len = VARSIZE_ANY_EXHDR(jb); jsqInit(&jsq, jq); - memset(&ra, 0, sizeof(ra)); + raInitialize(&ra); recursiveExecute(&jsq, &jbv, NULL, &ra); - if (ra.jbArrayState) - { - res = JsonbValueToJsonb( - pushJsonbValue(&ra.jbArrayState, WJB_END_ARRAY, NULL) - ); - } + res = raFinalize(&ra); PG_FREE_IF_COPY(jb, 0); PG_FREE_IF_COPY(jq, 1); - if (res) + /* If array is empty, we must return NULL. */ + if (res && JsonContainerSize(&res->root) > 0) PG_RETURN_JSONB_P(res); PG_RETURN_NULL(); From d5eb418e20f435daa9345558212234f845464c00 Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Mon, 24 Aug 2026 14:04:39 +0300 Subject: [PATCH 3/8] PG19 support: Adapt to new Jsonb API. Caused by: - 0986e951 Revise APIs for pushJsonbValue() and associated routines. --- jsquery_op.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/jsquery_op.c b/jsquery_op.c index f3b76fd..b8405f7 100644 --- a/jsquery_op.c +++ b/jsquery_op.c @@ -34,7 +34,11 @@ typedef struct ResultAccum { bool missAppend; - JsonbParseState *jbArrayState; +#if PG_VERSION_NUM >= 190000 + JsonbInState jbArrayState; /* initialize by zeroing this structure */ +#else + JsonbParseState *jbArrayState; /* initialize with NULL */ +#endif } ResultAccum; @@ -49,6 +53,7 @@ raInitialize(ResultAccum *ra) { Assert(ra); + /* This initialization works for both PG19+ and earlier */ memset(ra, 0, sizeof(*ra)); pushJsonbValue(&ra->jbArrayState, WJB_BEGIN_ARRAY, NULL); } @@ -61,9 +66,14 @@ static Jsonb * raFinalize(ResultAccum *ra) { Assert(ra); - Assert(ra->jbArrayState); +#if PG_VERSION_NUM >= 190000 + pushJsonbValue(&ra->jbArrayState, WJB_END_ARRAY, NULL); + return JsonbValueToJsonb(ra->jbArrayState.result); +#else + Assert(ra->jbArrayState); /* it's a pointer only before PG19 */ return JsonbValueToJsonb(pushJsonbValue(&ra->jbArrayState, WJB_END_ARRAY, NULL)); +#endif } /* @@ -76,7 +86,9 @@ raAppendElement(ResultAccum *ra, JsonbValue *jb) if (ra == NULL || ra->missAppend == true) return; - Assert(ra->jbArrayState); +#if PG_VERSION_NUM < 190000 + Assert(ra->jbArrayState); /* it's a pointer only before PG19 */ +#endif pushJsonbValue(&ra->jbArrayState, WJB_ELEM, jb); } @@ -93,7 +105,9 @@ raAppendArray(ResultAccum *ra, Jsonb *array) JsonbValue v; Assert(ra && ra->missAppend == false); - Assert(ra->jbArrayState); +#if PG_VERSION_NUM < 190000 + Assert(ra->jbArrayState); /* it's a pointer only before PG19 */ +#endif it = JsonbIteratorInit(&array->root); From 82cd96101889591eb1dbddf0501c13f6d7e5ac5d Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Mon, 24 Aug 2026 14:06:51 +0300 Subject: [PATCH 4/8] PG19 support: Add pg_fallthrough to keep compiler silent. Caused by: - 8354b9d6 Use fallthrough attribute instead of comment - 0284e075 Enable -Wimplicit-fallthrough option for clang Also to keep compiler silent add "break;" in one particular place. We could add another pg_fallthrough in here. Result is the same, but "break;" is shorter and easier to read given differences between PG versions. --- jsonb_gin_ops.c | 3 +++ jsquery_extract.c | 5 ++++- jsquery_io.c | 14 ++++++++++++-- jsquery_support.c | 35 +++++++++++++++++++++++++++++++---- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/jsonb_gin_ops.c b/jsonb_gin_ops.c index 3dd2f4d..7addd3b 100644 --- a/jsonb_gin_ops.c +++ b/jsonb_gin_ops.c @@ -1153,6 +1153,9 @@ gin_extract_jsonb_path_value_internal(Jsonb *jb, int32 *nentries) case WJB_END_ARRAY: if (!stack->parent) break; /* raw scalar array */ +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif /* fall through */ case WJB_END_OBJECT: /* Pop the stack */ diff --git a/jsquery_extract.c b/jsquery_extract.c index 4517706..2cd8f0e 100644 --- a/jsquery_extract.c +++ b/jsquery_extract.c @@ -179,8 +179,11 @@ recursiveExtract(JsQueryItem *jsq, bool not, bool indirect, PathItem *path) *result->exactValue = e; return result; } - /* fall through */ /* jqiEqual with jqiArray follows */ +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif + /* fall through */ case jqiIn: case jqiOverlap: case jqiContains: diff --git a/jsquery_io.c b/jsquery_io.c index 8a4b9ac..83de020 100644 --- a/jsquery_io.c +++ b/jsquery_io.c @@ -45,6 +45,9 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item, bool onlyCurrent case jqiKey: if (onlyCurrentInPath) elog(ERROR,"Array length should be last in path"); +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif /* fall through */ case jqiString: appendBinaryStringInfo(buf, (char*)&item->string.len, sizeof(item->string.len)); @@ -119,7 +122,10 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item, bool onlyCurrent case jqiIndexArray: appendBinaryStringInfo(buf, (char*)&item->arrayIndex, sizeof(item->arrayIndex)); - /* FALLTHROUGH */ /* keep svace quiet */ +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif + /* FALLTHROUGH */ case jqiAny: case jqiAnyArray: case jqiAnyKey: @@ -128,6 +134,7 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item, bool onlyCurrent case jqiAllKey: if (onlyCurrentInPath) elog(ERROR,"Array length should be last in path"); + break; case jqiCurrent: case jqiNull: break; @@ -236,8 +243,11 @@ printJsQueryItem(StringInfo buf, JsQueryItem *v, bool inKey, bool printBracketes case jqiKey: if (inKey) appendStringInfoChar(buf, '.'); - /* fall through */ /* follow next */ +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif + /* fall through */ case jqiString: escape_json(buf, jsqGetString(v, NULL)); break; diff --git a/jsquery_support.c b/jsquery_support.c index 747776b..616d247 100644 --- a/jsquery_support.c +++ b/jsquery_support.c @@ -34,12 +34,21 @@ alignStringInfoInt(StringInfo buf) { case 3: appendStringInfoCharMacro(buf, 0); +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif /* fall through */ case 2: appendStringInfoCharMacro(buf, 0); +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif /* fall through */ case 1: appendStringInfoCharMacro(buf, 0); +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif /* fall through */ default: break; @@ -64,9 +73,24 @@ jsqInitByBuffer(JsQueryItem *v, char *base, int32 pos) switch(INTALIGN(pos) - pos) { - case 3: pos++; /* fall through */ - case 2: pos++; /* fall through */ - case 1: pos++; /* fall through */ + case 3: + pos++; +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif + /* fall through */ + case 2: + pos++; +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif + /* fall through */ + case 1: + pos++; +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif + /* fall through */ default: break; } @@ -90,8 +114,11 @@ jsqInitByBuffer(JsQueryItem *v, char *base, int32 pos) case jqiKey: case jqiString: read_int32(v->value.datalen, base, pos); - /* fall through */ /* follow next */ +#if PG_VERSION_NUM >= 190000 + pg_fallthrough; +#endif + /* fall through */ case jqiNumeric: case jqiBool: case jqiIs: From 07a27402b5853dad8d77cb5aa1858cd415a7e5c8 Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Mon, 24 Aug 2026 14:08:56 +0300 Subject: [PATCH 5/8] PG19 support: Use "foo(void)" for definitions of functions with no parameters. See PostgreSQL commit: - 9b05e2ec Use "foo(void)" for definitions of functions with no parameters. Remove extra space while we are here. --- jsquery_scan.l | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jsquery_scan.l b/jsquery_scan.l index f145650..1452e13 100644 --- a/jsquery_scan.l +++ b/jsquery_scan.l @@ -248,9 +248,9 @@ static keyword keywords[] = { }; static int -checkSpecialVal() +checkSpecialVal(void) { - int res = STRING_P; + int res = STRING_P; int diff; keyword *StopLow = keywords, *StopHigh = keywords + lengthof(keywords), @@ -288,7 +288,7 @@ checkSpecialVal() } static JsQueryHint -checkHint() +checkHint(void) { if (scanstring.len <= 2 || strncmp(scanstring.val, "--", 2) != 0) return jsqIndexDefault; From af39f4f0d0cb6d46a3f52be3925e46f78275e9d2 Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Mon, 24 Aug 2026 14:11:11 +0300 Subject: [PATCH 6/8] PG19 support: Adapt test for PG19. Caused by: - 45762084 Force standard_conforming_strings to always be ON. --- expected/jsquery.out | 5 +++++ expected/jsquery_1.out | 5 +++++ sql/jsquery.sql | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/expected/jsquery.out b/expected/jsquery.out index 8c8d3b1..8f2edd8 100644 --- a/expected/jsquery.out +++ b/expected/jsquery.out @@ -1,6 +1,11 @@ CREATE EXTENSION jsquery; +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int < 19 AS server_version_lt_19 +\gset +\if :server_version_lt_19 set escape_string_warning=off; set standard_conforming_strings=on; +\endif CREATE TABLE test_jsquery (v jsonb); \copy test_jsquery from 'data/test_jsquery.data' select ''::jsquery; diff --git a/expected/jsquery_1.out b/expected/jsquery_1.out index ea1f6dc..8011209 100644 --- a/expected/jsquery_1.out +++ b/expected/jsquery_1.out @@ -1,6 +1,11 @@ CREATE EXTENSION jsquery; +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int < 19 AS server_version_lt_19 +\gset +\if :server_version_lt_19 set escape_string_warning=off; set standard_conforming_strings=on; +\endif CREATE TABLE test_jsquery (v jsonb); \copy test_jsquery from 'data/test_jsquery.data' select ''::jsquery; diff --git a/sql/jsquery.sql b/sql/jsquery.sql index d183741..a124eff 100644 --- a/sql/jsquery.sql +++ b/sql/jsquery.sql @@ -1,7 +1,13 @@ CREATE EXTENSION jsquery; +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int < 19 AS server_version_lt_19 +\gset + +\if :server_version_lt_19 set escape_string_warning=off; set standard_conforming_strings=on; +\endif CREATE TABLE test_jsquery (v jsonb); From e8b523c014a0d9b646690b7af79aaf0530490580 Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Fri, 11 Sep 2026 14:09:27 +0300 Subject: [PATCH 7/8] PG19 support: disable detailed parser errors to avoid fallthrough warnings Enabling detailed parser error messages causes some older versions of Bison (e.g., 2.3) to generate code that does not compile with the -Wimplicit-fallthrough option. Other parsers in PostgreSQL (e.g., src/backend/parser/gram.y and contrib/cube/cubeparse.y) do not use Bison's verbose error messages. This Bison option does not appear to make error messages much clearer for users in our case, so disable it in jsquery as well. Update the expected test output. The alternative output jsquery_1.out is no longer needed after this change. --- expected/jsquery.out | 6 +- expected/jsquery_1.out | 3389 ---------------------------------------- jsquery_gram.y | 1 - 3 files changed, 3 insertions(+), 3393 deletions(-) delete mode 100644 expected/jsquery_1.out diff --git a/expected/jsquery.out b/expected/jsquery.out index 8f2edd8..8fd18f4 100644 --- a/expected/jsquery.out +++ b/expected/jsquery.out @@ -77,7 +77,7 @@ select '* < 13 AND #.zxc"x" = "true"'::jsquery; ERROR: bad jsquery representation LINE 1: select '* < 13 AND #.zxc"x" = "true"'::jsquery; ^ -DETAIL: syntax error, unexpected STRING_P, expecting $end at or near """ +DETAIL: syntax error at or near """ select 'a < 1'::jsquery; jsquery --------- @@ -1193,7 +1193,7 @@ select 'a\r = x"\\abcd"'::jsquery AS err; ERROR: bad jsquery representation LINE 1: select 'a\r = x"\\abcd"'::jsquery AS err; ^ -DETAIL: syntax error, unexpected STRING_P, expecting $end at or near """ +DETAIL: syntax error at or near """ --IS select 'as IS boolean OR as is ARRAY OR as is ObJect OR as is Numeric OR as is string'::jsquery; jsquery @@ -1302,7 +1302,7 @@ select 'a = /*-- noindex */ 5'::jsquery; ERROR: bad jsquery representation LINE 1: select 'a = /*-- noindex */ 5'::jsquery; ^ -DETAIL: syntax error, unexpected HINT_P at or near "*/" +DETAIL: syntax error at or near "*/" select 'a = /* noindex */ 5'::jsquery; jsquery --------- diff --git a/expected/jsquery_1.out b/expected/jsquery_1.out deleted file mode 100644 index 8011209..0000000 --- a/expected/jsquery_1.out +++ /dev/null @@ -1,3389 +0,0 @@ -CREATE EXTENSION jsquery; -SHOW server_version \gset -SELECT substring(:'server_version', '\d+')::int < 19 AS server_version_lt_19 -\gset -\if :server_version_lt_19 -set escape_string_warning=off; -set standard_conforming_strings=on; -\endif -CREATE TABLE test_jsquery (v jsonb); -\copy test_jsquery from 'data/test_jsquery.data' -select ''::jsquery; -ERROR: bad jsquery representation -LINE 1: select ''::jsquery; - ^ -DETAIL: No symbols read at the end of input -select 'asd.zzz = 13'::jsquery; - jsquery ------------------- - "asd"."zzz" = 13 -(1 row) - -select 'asd.zzz < 13'::jsquery; - jsquery ------------------- - "asd"."zzz" < 13 -(1 row) - -select 'asd(zzz < 13)'::jsquery; - jsquery ------------------- - "asd"."zzz" < 13 -(1 row) - -select 'asd(zzz < 13 AND x = true)'::jsquery; - jsquery ----------------------------------- - "asd"("zzz" < 13 AND "x" = true) -(1 row) - -select 'asd(zzz < 13 AND x = "true")'::jsquery; - jsquery ------------------------------------- - "asd"("zzz" < 13 AND "x" = "true") -(1 row) - -select 'asd(zzz < 13 AND x.zxc = "true")'::jsquery; - jsquery ------------------------------------------- - "asd"("zzz" < 13 AND "x"."zxc" = "true") -(1 row) - -select 'asd(zzz < 13 OR #.zxc = "true" /* test */)'::jsquery; - jsquery ---------------------------------------- - "asd"("zzz" < 13 OR #."zxc" = "true") -(1 row) - -select 'asd(* < 13 AND /* ttt */ #.zxc = "true")'::jsquery; - jsquery ------------------------------------- - "asd"(* < 13 AND #."zxc" = "true") -(1 row) - -select '(* < 13 AND #.zxc = "true")'::jsquery; - jsquery -------------------------------- - (* < 13 AND #."zxc" = "true") -(1 row) - -select '* < 13 AND #.zxc/* t2 */ = "true"'::jsquery; - jsquery -------------------------------- - (* < 13 AND #."zxc" = "true") -(1 row) - -select '* < 13 AND #.zxc"x" = "true"'::jsquery; -ERROR: bad jsquery representation -LINE 1: select '* < 13 AND #.zxc"x" = "true"'::jsquery; - ^ -DETAIL: syntax error, unexpected STRING_P, expecting end of file at or near """ -select 'a < 1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < -1'::jsquery; - jsquery ----------- - "a" < -1 -(1 row) - -select 'a < +1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < .1'::jsquery; - jsquery ------------ - "a" < 0.1 -(1 row) - -select 'a < -.1'::jsquery; - jsquery ------------- - "a" < -0.1 -(1 row) - -select 'a < +.1'::jsquery; - jsquery ------------ - "a" < 0.1 -(1 row) - -select 'a < 0.1'::jsquery; - jsquery ------------ - "a" < 0.1 -(1 row) - -select 'a < -0.1'::jsquery; - jsquery ------------- - "a" < -0.1 -(1 row) - -select 'a < +0.1'::jsquery; - jsquery ------------ - "a" < 0.1 -(1 row) - -select 'a < 10.1'::jsquery; - jsquery ------------- - "a" < 10.1 -(1 row) - -select 'a < -10.1'::jsquery; - jsquery -------------- - "a" < -10.1 -(1 row) - -select 'a < +10.1'::jsquery; - jsquery ------------- - "a" < 10.1 -(1 row) - -select 'a < 1e1'::jsquery; - jsquery ----------- - "a" < 10 -(1 row) - -select 'a < -1e1'::jsquery; - jsquery ------------ - "a" < -10 -(1 row) - -select 'a < +1e1'::jsquery; - jsquery ----------- - "a" < 10 -(1 row) - -select 'a < .1e1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < -.1e1'::jsquery; - jsquery ----------- - "a" < -1 -(1 row) - -select 'a < +.1e1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < 0.1e1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < -0.1e1'::jsquery; - jsquery ----------- - "a" < -1 -(1 row) - -select 'a < +0.1e1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < 10.1e1'::jsquery; - jsquery ------------ - "a" < 101 -(1 row) - -select 'a < -10.1e1'::jsquery; - jsquery ------------- - "a" < -101 -(1 row) - -select 'a < +10.1e1'::jsquery; - jsquery ------------ - "a" < 101 -(1 row) - -select 'a < 1e-1'::jsquery; - jsquery ------------ - "a" < 0.1 -(1 row) - -select 'a < -1e-1'::jsquery; - jsquery ------------- - "a" < -0.1 -(1 row) - -select 'a < +1e-1'::jsquery; - jsquery ------------ - "a" < 0.1 -(1 row) - -select 'a < .1e-1'::jsquery; - jsquery ------------- - "a" < 0.01 -(1 row) - -select 'a < -.1e-1'::jsquery; - jsquery -------------- - "a" < -0.01 -(1 row) - -select 'a < +.1e-1'::jsquery; - jsquery ------------- - "a" < 0.01 -(1 row) - -select 'a < 0.1e-1'::jsquery; - jsquery ------------- - "a" < 0.01 -(1 row) - -select 'a < -0.1e-1'::jsquery; - jsquery -------------- - "a" < -0.01 -(1 row) - -select 'a < +0.1e-1'::jsquery; - jsquery ------------- - "a" < 0.01 -(1 row) - -select 'a < 10.1e-1'::jsquery; - jsquery ------------- - "a" < 1.01 -(1 row) - -select 'a < -10.1e-1'::jsquery; - jsquery -------------- - "a" < -1.01 -(1 row) - -select 'a < +10.1e-1'::jsquery; - jsquery ------------- - "a" < 1.01 -(1 row) - -select 'a < 1e+1'::jsquery; - jsquery ----------- - "a" < 10 -(1 row) - -select 'a < -1e+1'::jsquery; - jsquery ------------ - "a" < -10 -(1 row) - -select 'a < +1e+1'::jsquery; - jsquery ----------- - "a" < 10 -(1 row) - -select 'a < .1e+1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < -.1e+1'::jsquery; - jsquery ----------- - "a" < -1 -(1 row) - -select 'a < +.1e+1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < 0.1e+1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < -0.1e+1'::jsquery; - jsquery ----------- - "a" < -1 -(1 row) - -select 'a < +0.1e+1'::jsquery; - jsquery ---------- - "a" < 1 -(1 row) - -select 'a < 10.1e+1'::jsquery; - jsquery ------------ - "a" < 101 -(1 row) - -select 'a < -10.1e+1'::jsquery; - jsquery ------------- - "a" < -101 -(1 row) - -select 'a < +10.1e+1'::jsquery; - jsquery ------------ - "a" < 101 -(1 row) - -select 'a in (0,1,2)'::jsquery; - jsquery ------------------- - "a" IN (0, 1, 2) -(1 row) - -select 'a IN (0,null, "null", xxx, "zzz", 2)'::jsquery; - jsquery -------------------------------------------- - "a" IN (0, null, "null", "xxx", "zzz", 2) -(1 row) - -select 'not < 1'::jsquery; - jsquery ------------ - "not" < 1 -(1 row) - -select 'not not < 1'::jsquery; - jsquery ------------------ - (NOT "not" < 1) -(1 row) - -select 'not( not < 1)'::jsquery; - jsquery ------------------ - (NOT "not" < 1) -(1 row) - -select 'not.x < 1'::jsquery; - jsquery ---------------- - "not"."x" < 1 -(1 row) - -select 'x.not < 1'::jsquery; - jsquery ---------------- - "x"."not" < 1 -(1 row) - -select 'a.%(not x > 0 and not (y < 0 or z = 0))'::jsquery; - jsquery ------------------------------------------------------ - "a".%((NOT "x" > 0) AND (NOT ("y" < 0 OR "z" = 0))) -(1 row) - -select 'is < 1'::jsquery; - jsquery ----------- - "is" < 1 -(1 row) - -select 'in < 1'::jsquery; - jsquery ----------- - "in" < 1 -(1 row) - -select 'not is < 1'::jsquery; - jsquery ----------------- - (NOT "is" < 1) -(1 row) - -select 'not in < 1'::jsquery; - jsquery ----------------- - (NOT "in" < 1) -(1 row) - -select 'in in (1,2)'::jsquery; - jsquery ----------------- - "in" IN (1, 2) -(1 row) - -select 'is in (1,2)'::jsquery; - jsquery ----------------- - "is" IN (1, 2) -(1 row) - -select 'not in (1,2)'::jsquery; - jsquery ------------------ - "not" IN (1, 2) -(1 row) - -select 'in is numeric'::jsquery; - jsquery ------------------ - "in" IS NUMERIC -(1 row) - -select 'is is numeric'::jsquery; - jsquery ------------------ - "is" IS NUMERIC -(1 row) - -select 'not is numeric'::jsquery; - jsquery ------------------- - "not" IS NUMERIC -(1 row) - -select 'not.in < 1'::jsquery; - jsquery ----------------- - "not"."in" < 1 -(1 row) - -select 'not.is < 1'::jsquery; - jsquery ----------------- - "not"."is" < 1 -(1 row) - -select 'not.not < 1'::jsquery; - jsquery ------------------ - "not"."not" < 1 -(1 row) - -select 'in.in < 1'::jsquery; - jsquery ---------------- - "in"."in" < 1 -(1 row) - -select 'in.is < 1'::jsquery; - jsquery ---------------- - "in"."is" < 1 -(1 row) - -select 'in.not < 1'::jsquery; - jsquery ----------------- - "in"."not" < 1 -(1 row) - -select 'is.in < 1'::jsquery; - jsquery ---------------- - "is"."in" < 1 -(1 row) - -select 'is.is < 1'::jsquery; - jsquery ---------------- - "is"."is" < 1 -(1 row) - -select 'is.not < 1'::jsquery; - jsquery ----------------- - "is"."not" < 1 -(1 row) - -select 'a.b.#4 > 4'::jsquery; - jsquery ----------------- - "a"."b".#4 > 4 -(1 row) - -select 'a.b.#10203.* > 4'::jsquery; - jsquery ----------------------- - "a"."b".#10203.* > 4 -(1 row) - -select '{"a": {"b": null}}'::jsonb @@ 'a.b = 1'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": null}}'::jsonb @@ 'a.b = null'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": null}}'::jsonb @@ 'a.b = false'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": false}}'::jsonb @@ 'a.b = false'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": false}}'::jsonb @@ 'a.b = true'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": true}}'::jsonb @@ 'a.b = true'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b = 1'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b < 1'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b <= 1'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b >= 1'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b > 1'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b = 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b < 2'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b <= 2'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b >= 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b > 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b = 0'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b < 0'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b <= 0'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b >= 0'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.b > 0'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ '*.b > 0'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ '*.b > 0'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.* > 0'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1}}'::jsonb @@ 'a.* > 0'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ '*.b && [ 1 ]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ '*.b @> [ 1 ]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ '*.b <@ [ 1 ]'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ '*.b @> [ 1,2,3,4 ]'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ '*.b <@ [ 1,2,3,4 ]'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}]'::jsonb @@ '*.a = 4'::jsquery; - ?column? ----------- - f -(1 row) - -select '[{"a": 2}, {"a": 3}]'::jsonb @@ '*.a = 3'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '#.a = 4'::jsquery; - ?column? ----------- - f -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '*.a = 4'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '#(a = 1 OR a=3)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '#(a = 3 OR a=1)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '#(a = 3 and a=1)'::jsquery; - ?column? ----------- - f -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '#(a = 3 and a=2)'::jsquery as "false"; - false -------- - f -(1 row) - -select '[{"a": 2, "b":3}, {"a": 3, "b": 1}]'::jsonb @@ '#(b = 1 and a=3)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '#.a.a = 4'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '*.a.a = 4'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '*.#.a.a = 4'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a": 2}, {"a": 3}, {"a": {"a":4}}]'::jsonb @@ '#.*.a.a = 4'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": 1}'::jsonb @@ 'a in (0,1,2)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": 1}'::jsonb @@ 'a in (0,2)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.#=2'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ '*.b && [ 5 ]'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a=*'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b=*'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.c=*'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b = [1,2,3]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.# = [1,2,3]'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b && [1,2,3]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.# && [1,2,3]'::jsquery; - ?column? ----------- - f -(1 row) - -select 'asd.# = 3'::jsquery & 'zzz = true' | 'xxx.# = zero'::jsquery; - ?column? ------------------------------------------------------- - (("asd".# = 3 AND "zzz" = true) OR "xxx".# = "zero") -(1 row) - -select !'asd.# = 3'::jsquery & 'zzz = true' | !'xxx.# = zero'::jsquery; - ?column? ------------------------------------------------------------------- - (((NOT "asd".# = 3) AND "zzz" = true) OR (NOT "xxx".# = "zero")) -(1 row) - -select !'asd.#3.f = 3'::jsquery & 'zzz = true' | !'xxx.# = zero'::jsquery; - ?column? ------------------------------------------------------------------------ - (((NOT "asd".#3."f" = 3) AND "zzz" = true) OR (NOT "xxx".# = "zero")) -(1 row) - -select '{"x":[0,1,1,2]}'::jsonb @@ 'x @> [1,0]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"x":[0,1,1,2]}'::jsonb @@ 'x @> [1,0,1]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"x":[0,1,1,2]}'::jsonb @@ 'x @> [1,0,3]'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ '*.b && [ 2 ]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ '*.b($ && [ 2 ])'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.$.b && [ 2 ]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.$.b ($ && [ 2 ])'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1,2,3]'::jsonb @@ '# && [2]'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1,2,3]'::jsonb @@ '#($ && [2])'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1,2,3]'::jsonb @@ '$ && [2]'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1,2,3]'::jsonb @@ '$ ($ && [2])'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1,2,3]'::jsonb @@ '$ = 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1,2,3]'::jsonb @@ '# = 2'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1,2,3]'::jsonb @@ '#.$ = 2'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1,2,3]'::jsonb @@ '#($ = 2)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[3,4]'::jsonb @@ '#($ > 2 and $ < 5)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[3,4]'::jsonb @@ '# > 2 and # < 5'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1,6]'::jsonb @@ '#($ > 2 and $ < 5)'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1,6]'::jsonb @@ '# > 2 and # < 5'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%.b=3'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ 'a.%=3'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%.%="hey"'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%="hey"'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%=[5,6]'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.#1 = 2'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.#2 = 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.#3 = 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@ 'a.b.#1.x = 2'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@ 'a.b.#2.x = 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@ 'a.b.#3.x = 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '"XXX"'::jsonb @@ '$="XXX"'::jsquery; - ?column? ----------- - t -(1 row) - -select '"XXX"'::jsonb @@ '#.$="XXX"'::jsquery; - ?column? ----------- - f -(1 row) - ---Unicode -select 'a\t = "dollar \u0024 character"'::jsquery; - jsquery ------------------------------- - "a\t" = "dollar $ character" -(1 row) - -select '{ "a": "dollar \u0024 character" }'::jsonb @@ '* = "dollar \u0024 character"'::jsquery; - ?column? ----------- - t -(1 row) - -select '{ "a": "dollar \u0024 character" }'::jsonb @@ '* = "dollar $ character"'::jsquery; - ?column? ----------- - t -(1 row) - -select '{ "a": "dollar $ character" }'::jsonb @@ '* = "dollar \u0024 character"'::jsquery; - ?column? ----------- - t -(1 row) - -select 'a\r = "\n\""'::jsquery; - jsquery ----------------- - "a\r" = "\n\"" -(1 row) - -select 'a\r = "\u0000"'::jsquery; -ERROR: unsupported Unicode escape sequence -LINE 1: select 'a\r = "\u0000"'::jsquery; - ^ -DETAIL: \u0000 cannot be converted to text. -select 'a\r = \u0000'::jsquery; -ERROR: unsupported Unicode escape sequence -LINE 1: select 'a\r = \u0000'::jsquery; - ^ -DETAIL: \u0000 cannot be converted to text. -select 'a\r = "\abcd"'::jsquery AS err; -ERROR: bad jsquery representation -LINE 1: select 'a\r = "\abcd"'::jsquery AS err; - ^ -DETAIL: Escape sequence is invalid at or near "\a" -select 'a\r = "\\abcd"'::jsquery; - jsquery ------------------- - "a\r" = "\\abcd" -(1 row) - -select 'a\r = "x\u0000"'::jsquery; -ERROR: unsupported Unicode escape sequence -LINE 1: select 'a\r = "x\u0000"'::jsquery; - ^ -DETAIL: \u0000 cannot be converted to text. -select 'a\r = x\u0000'::jsquery; -ERROR: unsupported Unicode escape sequence -LINE 1: select 'a\r = x\u0000'::jsquery; - ^ -DETAIL: \u0000 cannot be converted to text. -select 'a\r = "x\abcd"'::jsquery AS err; -ERROR: bad jsquery representation -LINE 1: select 'a\r = "x\abcd"'::jsquery AS err; - ^ -DETAIL: Escape sequence is invalid at or near "\a" -select 'a\r = "x\\abcd"'::jsquery; - jsquery -------------------- - "a\r" = "x\\abcd" -(1 row) - -select 'a\r = "x\u0000x"'::jsquery; -ERROR: unsupported Unicode escape sequence -LINE 1: select 'a\r = "x\u0000x"'::jsquery; - ^ -DETAIL: \u0000 cannot be converted to text. -select 'a\r = x\u0000x'::jsquery; -ERROR: unsupported Unicode escape sequence -LINE 1: select 'a\r = x\u0000x'::jsquery; - ^ -DETAIL: \u0000 cannot be converted to text. -select 'a\r = "x\abcdx"'::jsquery AS err; -ERROR: bad jsquery representation -LINE 1: select 'a\r = "x\abcdx"'::jsquery AS err; - ^ -DETAIL: Escape sequence is invalid at or near "\a" -select 'a\r = "x\\abcdx"'::jsquery; - jsquery --------------------- - "a\r" = "x\\abcdx" -(1 row) - -select 'a\r = "\u0000x"'::jsquery; -ERROR: unsupported Unicode escape sequence -LINE 1: select 'a\r = "\u0000x"'::jsquery; - ^ -DETAIL: \u0000 cannot be converted to text. -select 'a\r = \u0000x'::jsquery; -ERROR: unsupported Unicode escape sequence -LINE 1: select 'a\r = \u0000x'::jsquery; - ^ -DETAIL: \u0000 cannot be converted to text. -select 'a\r = "\abcdx"'::jsquery AS err; -ERROR: bad jsquery representation -LINE 1: select 'a\r = "\abcdx"'::jsquery AS err; - ^ -DETAIL: Escape sequence is invalid at or near "\a" -select 'a\r = "\\abcdx"'::jsquery; - jsquery -------------------- - "a\r" = "\\abcdx" -(1 row) - -select 'a\r = x"\\abcd"'::jsquery AS err; -ERROR: bad jsquery representation -LINE 1: select 'a\r = x"\\abcd"'::jsquery AS err; - ^ -DETAIL: syntax error, unexpected STRING_P, expecting end of file at or near """ ---IS -select 'as IS boolean OR as is ARRAY OR as is ObJect OR as is Numeric OR as is string'::jsquery; - jsquery -------------------------------------------------------------------------------------------------- - (((("as" IS BOOLEAN OR "as" IS ARRAY) OR "as" IS OBJECT) OR "as" IS NUMERIC) OR "as" IS STRING) -(1 row) - -select '{"as": "xxx"}' @@ 'as IS string'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"as": "xxx"}' @@ 'as IS boolean OR as is ARRAY OR as is ObJect OR as is Numeric'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"as": 5}' @@ 'as is Numeric'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"as": true}' @@ 'as is boolean'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"as": false}' @@ 'as is boolean'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"as": "false"}' @@ 'as is boolean'::jsquery; - ?column? ----------- - f -(1 row) - -select '["xxx"]' @@ '$ IS array'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"as": false}' @@ '$ IS object'::jsquery; - ?column? ----------- - t -(1 row) - -select '"xxx"' @@ '$ IS string'::jsquery; - ?column? ----------- - t -(1 row) - -select '"xxx"' @@ '$ IS numeric'::jsquery; - ?column? ----------- - f -(1 row) - ---hint -select 'a /*-- noindex */ = 5'::jsquery; - jsquery --------------------------- - "a" /*-- noindex */ = 5 -(1 row) - -select 'a /*-- index */ = 5'::jsquery; - jsquery ------------------------- - "a" /*-- index */ = 5 -(1 row) - -select 'asd.# = 3'::jsquery & 'zzz /*-- noindex */ = true' | 'xxx.# /*-- index */ = zero'; - ?column? --------------------------------------------------------------------------------------- - (("asd".# = 3 AND "zzz" /*-- noindex */ = true) OR "xxx".# /*-- index */ = "zero") -(1 row) - -select 'a /*-- xxx */ = 5'::jsquery; - jsquery ---------- - "a" = 5 -(1 row) - -select 'a /* index */ = 5'::jsquery; - jsquery ---------- - "a" = 5 -(1 row) - -select 'a /* noindex */ = 5'::jsquery; - jsquery ---------- - "a" = 5 -(1 row) - -select 'a = /*-- noindex */ 5'::jsquery; -ERROR: bad jsquery representation -LINE 1: select 'a = /*-- noindex */ 5'::jsquery; - ^ -DETAIL: syntax error, unexpected HINT_P at or near "*/" -select 'a = /* noindex */ 5'::jsquery; - jsquery ---------- - "a" = 5 -(1 row) - ---LENGTH -select 'a.@# = 4'::jsquery; - jsquery ------------- - "a".@# = 4 -(1 row) - -select 'a.@#.$ = 4'::jsquery as noerror; - noerror --------------- - "a".@#.$ = 4 -(1 row) - -select 'a.@#.a = 4'::jsquery as error; -ERROR: Array length should be last in path -LINE 1: select 'a.@#.a = 4'::jsquery as error; - ^ -select 'a.@#.* = 4'::jsquery as error; -ERROR: Array length should be last in path -LINE 1: select 'a.@#.* = 4'::jsquery as error; - ^ -select 'a.@#.% = 4'::jsquery as error; -ERROR: Array length should be last in path -LINE 1: select 'a.@#.% = 4'::jsquery as error; - ^ -select 'a.@#.# = 4'::jsquery as error; -ERROR: Array length should be last in path -LINE 1: select 'a.@#.# = 4'::jsquery as error; - ^ -select 'a.@#.*: = 4'::jsquery as error; -ERROR: Array length should be last in path -LINE 1: select 'a.@#.*: = 4'::jsquery as error; - ^ -select 'a.@#.%: = 4'::jsquery as error; -ERROR: Array length should be last in path -LINE 1: select 'a.@#.%: = 4'::jsquery as error; - ^ -select 'a.@#.#: = 4'::jsquery as error; -ERROR: Array length should be last in path -LINE 1: select 'a.@#.#: = 4'::jsquery as error; - ^ -select 'a.@# (a = 5 or b = 6)'::jsquery as error; -ERROR: Array length should be last in path -LINE 1: select 'a.@# (a = 5 or b = 6)'::jsquery as error; - ^ -select '[]' @@ '@# = 0'::jsquery; - ?column? ----------- - t -(1 row) - -select '[]' @@ '@# < 2'::jsquery; - ?column? ----------- - t -(1 row) - -select '[]' @@ '@# > 1'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1]' @@ '@# = 0'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1]' @@ '@# < 2'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1]' @@ '@# > 1'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1,2]' @@ '@# = 0'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1,2]' @@ '@# < 2'::jsquery; - ?column? ----------- - f -(1 row) - -select '[1,2]' @@ '@# > 1'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1,2]' @@ '@# in (1, 2)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[1,2]' @@ '@# in (1, 3)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":[1,2]}' @@ '@# in (2, 4)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":[1,2]}' @@ 'a.@# in (2, 4)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":[1,2]}' @@ '%.@# in (2, 4)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":[1,2]}' @@ '*.@# in (2, 4)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":[1,2]}' @@ '*.@# ($ = 4 or $ = 2)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":[1,2]}' @@ '@# = 1'::jsquery; - ?column? ----------- - t -(1 row) - ---filter -select '?( not b>0). x'::jsquery; - jsquery ------------------------- - ?((NOT "b" > 0)) ."x" -(1 row) - -select 'a.?(b>0 and x= 0 ) .c'::jsquery; - jsquery ------------------------------------- - "a". ?(("b" > 0 AND "x" = 0)) ."c" -(1 row) - -select 'a.$. ?(b>0 and x= 0 ) . c.k'::jsquery; - jsquery ------------------------------------------- - "a".$. ?(("b" > 0 AND "x" = 0)) ."c"."k" -(1 row) - -select 'a.$.? (b>0 and x.*= 0 ).c.k'::jsquery; - jsquery --------------------------------------------- - "a".$. ?(("b" > 0 AND "x".* = 0)) ."c"."k" -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}, {"a":3, "b":30}]'::jsonb @@ '#. ?(a < 0) (b=20)'::jsquery; - ?column? ----------- - f -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}, {"a":3, "b":30}]'::jsonb @@ '#. ?(a > 0) (b=20)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}, {"a":3, "b":30}]'::jsonb @@ '#. ?(a > 1) (b=20)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}, {"a":3, "b":30}]'::jsonb @@ '#. ?(a > 2) (b=20)'::jsquery; - ?column? ----------- - f -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}, {"a":3, "b":30}]'::jsonb @@ '#. ?(a > 3) (b=20)'::jsquery; - ?column? ----------- - f -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}]'::jsonb ~~ '#.a'::jsquery; - ?column? ----------- - [1, 2] -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}]'::jsonb ~~ '#. ?(a > 1). b'::jsquery; - ?column? ----------- - [20] -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}, {"a":3, "b":30}]'::jsonb ~~ '# . ?(a > 1)'::jsquery; - ?column? ----------------------------------------- - [{"a": 2, "b": 20}, {"a": 3, "b": 30}] -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}, {"a":3, "b":30}]'::jsonb ~~ '%'::jsquery; - ?column? ----------- - -(1 row) - -select '{"a":1, "b":2, "c":3}'::jsonb ~~ '%'::jsquery; - ?column? ------------ - [1, 2, 3] -(1 row) - -select '{"a":1, "b":2, "c":3}'::jsonb ~~ '% . ? ( $ > 2 )'::jsquery; - ?column? ----------- - [3] -(1 row) - -select '{"a":1, "b":2, "c":3}'::jsonb ~~ '% . ? ( $ > 2 ).$'::jsquery; - ?column? ----------- - [3] -(1 row) - -select '{"a":1, "b":2, "c":3}'::jsonb ~~ '? ( % > 2 )'::jsquery; - ?column? ----------------------------- - [{"a": 1, "b": 2, "c": 3}] -(1 row) - -select '{"a":1, "b":2, "c":3}'::jsonb ~~ '? ( %: > 0 )'::jsquery; - ?column? ----------------------------- - [{"a": 1, "b": 2, "c": 3}] -(1 row) - -select '{"a":1, "b":2, "c":3}'::jsonb ~~ '? ( %: > 2 )'::jsquery; - ?column? ----------- - -(1 row) - -select '[{"a":1, "b":10}, {"a":2, "b":20}, {"a":3, "b":30}]'::jsonb ~~ '#'::jsquery; - ?column? ------------------------------------------------------------ - [{"a": 1, "b": 10}, {"a": 2, "b": 20}, {"a": 3, "b": 30}] -(1 row) - -select '[1,2,3]'::jsonb ~~ '#'::jsquery; - ?column? ------------ - [1, 2, 3] -(1 row) - -select '[1,2,3]'::jsonb ~~ '#. ?($ > 2)'::jsquery; - ?column? ----------- - [3] -(1 row) - -select '[1,2,3]'::jsonb ~~ '#. ?($ > 2).$'::jsquery; - ?column? ----------- - [3] -(1 row) - -select '[1,2,3]'::jsonb ~~ ' ?(#.$ > 2).$'::jsquery; - ?column? -------------- - [[1, 2, 3]] -(1 row) - -select '[1,2,3]'::jsonb ~~ ' ?(#:.$ > 2).$'::jsquery; - ?column? ----------- - -(1 row) - -select '[1,2,3]'::jsonb ~~ ' ?(#:.$ > 0).$'::jsquery; - ?column? -------------- - [[1, 2, 3]] -(1 row) - -select '{"a": {"b": {"c": 1}}}'::jsonb ~~ '*.?(c >0)'::jsquery; - ?column? ------------- - [{"c": 1}] -(1 row) - -select '{"a": {"b": {"c": 1}}}'::jsonb ~~ '?(*.c >0)'::jsquery; - ?column? --------------------------- - [{"a": {"b": {"c": 1}}}] -(1 row) - -select '{"tags":[{"term":["NYC", "CYN"]}, {"term":["1NYC", "1CYN"]} ]}'::jsonb ~~ 'tags.#.term.#. ? ( $ = "NYC")'::jsquery; - ?column? ----------- - ["NYC"] -(1 row) - -select '{"tags":[{"term":["NYC", "CYN"]}, {"term":["1NYC", "1CYN"]} ]}'::jsonb ~~ 'tags.#.term. ? ( # = "NYC")'::jsquery; - ?column? ------------------- - [["NYC", "CYN"]] -(1 row) - ---ALL -select 'a.*: = 4'::jsquery; - jsquery ------------- - "a".*: = 4 -(1 row) - -select '%: = 4'::jsquery; - jsquery ---------- - %: = 4 -(1 row) - -select '#:.i = 4'::jsquery; - jsquery ------------- - #:."i" = 4 -(1 row) - -select '[]' @@ '#: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[2,3,4]' @@ '#: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[2,3,5]' @@ '#: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - f -(1 row) - -select '[2,3,5]' @@ '# ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - t -(1 row) - -select '[2,3,"x"]' @@ '#: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{}' @@ '%: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{}' @@ '*: ($ is object)'::jsquery; - ?column? ----------- - t -(1 row) - -select '"a"' @@ '*: is string'::jsquery; - ?column? ----------- - t -(1 row) - -select '1' @@ '*: is string'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":2,"b":3,"c":4}' @@ '%: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":2,"b":3,"c":5}' @@ '%: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":2,"b":3,"c":5}' @@ '% ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":2,"b":3,"c":"x"}' @@ '%: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":2,"b":3,"c":4}' @@ '*: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":2,"b":3,"c":5}' @@ '*: ($ > 1 and $ < 5)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":2,"b":3,"c":4}' @@ '*: ($ is object OR ($> 1 and $ < 5))'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":2,"b":3,"c":5}' @@ '*: ($ is object OR ($> 1 and $ < 5))'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"b":{"ba":3, "bb":4}}' @@ '*: ($ is object OR ($ > 1 and $ < 5))'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"b":{"ba":3, "bb":5}}' @@ '*: ($ is object OR ($> 1 and $ < 5))'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":{"ba":3, "bb":4}}' @@ '*: ($ is object OR ($ > 0 and $ < 5))'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":{"ba":3, "bb":5}}' @@ '*: ($ is object OR ($> 0 and $ < 5))'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":{"ba":3, "bb":5}}' @@ '* ($ > 0 and $ < 5)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":{"ba":3, "bb":5}}' @@ '*: ($ is object OR $ is numeric)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":[5,6]}' @@ '*: ($ is object OR $ is numeric)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":[5,6]}' @@ '*: ($ is object OR $ is array OR $ is numeric)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":[5,6, {"c":8}]}' @@ '*: ($ is object OR $ is array OR $ is numeric)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":[5,6, {"c":"x"}]}' @@ '*: ($ is object OR $ is array OR $ is numeric)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":{"aa":1, "ab":2}, "b":[5,6, {"c":null}]}' @@ '*: ($ is object OR $ is array OR $ is numeric)'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":{"aa":1}, "b":{"aa":1, "bb":2}}' @@ '%:.aa is numeric'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":{"aa":1}, "b":{"aa":true, "bb":2}}' @@ '%:.aa is numeric'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a":{"aa":1}, "b":{"aa":1, "bb":2}, "aa":16}' @@ '*: (not $ is object or $.aa is numeric)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a":{"aa":1}, "b":{"aa":1, "bb":2}}' @@ '*: (not $ is object or $.aa is numeric or % is object)'::jsquery; - ?column? ----------- - t -(1 row) - -SELECT 'test.# IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64)'::jsquery; - jsquery ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - "test".# IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64) -(1 row) - -select '[]' @@ '(@# > 0 and #: = 16)'::jsquery; - ?column? ----------- - f -(1 row) - -select '[16]' @@ '(@# > 0 and #: = 16)'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.b or b.d'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.c or b.d'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.g or b.d'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.g or b.c'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.b and b.d'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.c and b.d'::jsquery; - ?column? ----------- - t -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.c and b.b'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb @@ 'a.g and b.d'::jsquery; - ?column? ----------- - f -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and b.d'::jsquery; - ?column? ----------- - [1, 3] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and b.c'::jsquery; - ?column? ----------- - -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and (b.d or b.c)'::jsquery; - ?column? ----------- - [1, 3] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and (b.c or b.d)'::jsquery; - ?column? ----------- - [1, 3] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b and a.c and b.d'::jsquery; - ?column? ------------ - [1, 2, 3] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.b or a.c) and b.d'::jsquery; - ?column? ----------- - [1, 3] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.e or a.c) and b.d'::jsquery; - ?column? ----------- - [2, 3] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ '(a.e or a.g) and b.d'::jsquery; - ?column? ----------- - -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'a.b or (b.d or b.c)'::jsquery; - ?column? ----------- - [1] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d or (a.b or a.c)'::jsquery; - ?column? ----------- - [3] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d or (a.b and a.c)'::jsquery; - ?column? ----------- - [3] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.f or (a.b and a.c)'::jsquery; - ?column? ----------- - [1, 2] -(1 row) - -select '{"a": {"b": 1, "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d and (a.b and a.c)'::jsquery; - ?column? ------------ - [3, 1, 2] -(1 row) - -select '{"a": {"b": [6,5,4], "c": 2}, "b": {"d":3}}'::jsonb ~~ 'b.d and (a.b and a.c)'::jsquery; - ?column? -------------------- - [3, [6, 5, 4], 2] -(1 row) - ---extract entries for index scan -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'); - gin_debug_query_path_value ----------------------------- - AND + - z = 5 , entry 0 + - OR + - x.y.a = 1 , entry 1 + - x.y.b = 2 , entry 2 + - -(1 row) - -SELECT gin_debug_query_path_value('NOT #(x=1) and NOT *(y=1) and NOT %(z=1) '); - gin_debug_query_path_value ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_path_value('#(NOT x=1) and *(NOT y=1) and %(NOT z=1) '); - gin_debug_query_path_value ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_path_value('NOT #(NOT x=1) and NOT *(NOT y=1) and NOT %(NOT z=1) '); - gin_debug_query_path_value ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_path_value('#(x = "a" and y > 0 and y < 1 and z > 0)'); - gin_debug_query_path_value ----------------------------- - #.x = "a" , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('#(x = "a" and y /*-- index */ >= 0 and y < 1 and z > 0)'); - gin_debug_query_path_value ------------------------------ - AND + - #.x = "a" , entry 0 + - #.y >= 0 , < 1 , entry 1 + - -(1 row) - -SELECT gin_debug_query_path_value('#(x /*-- noindex */ = "a" and y > 0 and y <= 1 and z /*-- index */ > 0)'); - gin_debug_query_path_value ------------------------------ - AND + - #.y > 0 , <= 1 , entry 0 + - #.z > 0 , entry 1 + - -(1 row) - -SELECT gin_debug_query_path_value('x = 1 and (y /*-- index */ > 0 and y < 1 OR z > 0)'); - gin_debug_query_path_value ----------------------------- - AND + - x = 1 , entry 0 + - OR + - y > 0 , < 1 , entry 1 + - z > 0 , entry 2 + - -(1 row) - -SELECT gin_debug_query_path_value('%.x = 1'); - gin_debug_query_path_value ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_path_value('*.x = "b"'); - gin_debug_query_path_value ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_path_value('x && [1,2,3]'); - gin_debug_query_path_value ----------------------------- - OR + - x.# = 1 , entry 0 + - x.# = 2 , entry 1 + - x.# = 3 , entry 2 + - -(1 row) - -SELECT gin_debug_query_path_value('x @> [1,2,3]'); - gin_debug_query_path_value ----------------------------- - AND + - x.# = 1 , entry 0 + - x.# = 2 , entry 1 + - x.# = 3 , entry 2 + - -(1 row) - -SELECT gin_debug_query_path_value('x <@ [1,2,3]'); - gin_debug_query_path_value ----------------------------- - OR + - x = [] , entry 0 + - x.# = 1 , entry 1 + - x.# = 2 , entry 2 + - x.# = 3 , entry 3 + - -(1 row) - -SELECT gin_debug_query_path_value('x = *'); - gin_debug_query_path_value ----------------------------- - x = * , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('x is boolean'); - gin_debug_query_path_value ----------------------------- - x IS boolean , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('x is string'); - gin_debug_query_path_value ----------------------------- - x IS string , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('x is numeric'); - gin_debug_query_path_value ----------------------------- - x IS numeric , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('x is array'); - gin_debug_query_path_value ----------------------------- - x IS array , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('x is object'); - gin_debug_query_path_value ----------------------------- - x IS object , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('#:(x=1) AND %:(y=1) AND *:(z=1)'); - gin_debug_query_path_value ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_path_value('#:(NOT x=1) AND %:(NOT y=1) AND *:(NOT z=1)'); - gin_debug_query_path_value ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_path_value('NOT #:(NOT x=1) AND NOT %:(NOT y=1) AND NOT *:(NOT z=1)'); - gin_debug_query_path_value ----------------------------- - #.x = 1 , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('$ = true'); - gin_debug_query_path_value ----------------------------- - $ = true , entry 0 + - -(1 row) - -SELECT gin_debug_query_path_value('$ . ? (review_votes > 10) . review_rating < 7'); - gin_debug_query_path_value --------------------------------- - AND + - review_rating < 7 , entry 0 + - review_votes > 10 , entry 1 + - -(1 row) - -SELECT gin_debug_query_path_value('similar_product_ids . ? (# = "B0002W4TL2") . $'); - gin_debug_query_path_value -------------------------------------------------- - similar_product_ids.# = "B0002W4TL2" , entry 0 + - -(1 row) - -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'); - gin_debug_query_value_path ----------------------------- - AND + - z = 5 , entry 0 + - OR + - x.y.a = 1 , entry 1 + - x.y.b = 2 , entry 2 + - -(1 row) - -SELECT gin_debug_query_value_path('NOT #(x=1) and NOT *(y=1) and NOT %(z=1) '); - gin_debug_query_value_path ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_value_path('#(NOT x=1) and *(NOT y=1) and %(NOT z=1) '); - gin_debug_query_value_path ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_value_path('NOT #(NOT x=1) and NOT *(NOT y=1) and NOT %(NOT z=1) '); - gin_debug_query_value_path ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_value_path('#(x = "a" and y > 0 and y < 1 and z > 0)'); - gin_debug_query_value_path ----------------------------- - #.x = "a" , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('#(x = "a" and y /*-- index */ >= 0 and y < 1 and z > 0)'); - gin_debug_query_value_path ------------------------------ - AND + - #.x = "a" , entry 0 + - #.y >= 0 , < 1 , entry 1 + - -(1 row) - -SELECT gin_debug_query_value_path('#(x /*-- noindex */ = "a" and y > 0 and y <= 1 and z /*-- index */ > 0)'); - gin_debug_query_value_path ------------------------------ - AND + - #.y > 0 , <= 1 , entry 0 + - #.z > 0 , entry 1 + - -(1 row) - -SELECT gin_debug_query_value_path('x = 1 and (y /*-- index */ > 0 and y < 1 OR z > 0)'); - gin_debug_query_value_path ----------------------------- - AND + - x = 1 , entry 0 + - OR + - y > 0 , < 1 , entry 1 + - z > 0 , entry 2 + - -(1 row) - -SELECT gin_debug_query_value_path('%.x = 1'); - gin_debug_query_value_path ----------------------------- - %.x = 1 , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('*.x = "b"'); - gin_debug_query_value_path ----------------------------- - *.x = "b" , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('x && [1,2,3]'); - gin_debug_query_value_path ----------------------------- - OR + - x.# = 1 , entry 0 + - x.# = 2 , entry 1 + - x.# = 3 , entry 2 + - -(1 row) - -SELECT gin_debug_query_value_path('x @> [1,2,3]'); - gin_debug_query_value_path ----------------------------- - AND + - x.# = 1 , entry 0 + - x.# = 2 , entry 1 + - x.# = 3 , entry 2 + - -(1 row) - -SELECT gin_debug_query_value_path('x <@ [1,2,3]'); - gin_debug_query_value_path ----------------------------- - OR + - x = [] , entry 0 + - x.# = 1 , entry 1 + - x.# = 2 , entry 2 + - x.# = 3 , entry 3 + - -(1 row) - -SELECT gin_debug_query_value_path('x = [1,2,3]'); - gin_debug_query_value_path ----------------------------- - AND + - x.# = 1 , entry 0 + - x.# = 2 , entry 1 + - x.# = 3 , entry 2 + - -(1 row) - -SELECT gin_debug_query_value_path('x = *'); - gin_debug_query_value_path ----------------------------- - x = * , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('x is boolean'); - gin_debug_query_value_path ----------------------------- - x IS boolean , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('x is string'); - gin_debug_query_value_path ----------------------------- - x IS string , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('x is numeric'); - gin_debug_query_value_path ----------------------------- - x IS numeric , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('x is array'); - gin_debug_query_value_path ----------------------------- - x IS array , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('x is object'); - gin_debug_query_value_path ----------------------------- - x IS object , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('#:(x=1) AND %:(y=1) AND *:(z=1)'); - gin_debug_query_value_path ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_value_path('#:(NOT x=1) AND %:(NOT y=1) AND *:(NOT z=1)'); - gin_debug_query_value_path ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_value_path('NOT #:(NOT x=1) AND NOT %:(NOT y=1) AND NOT *:(NOT z=1)'); - gin_debug_query_value_path ----------------------------- - AND + - #.x = 1 , entry 0 + - %.y = 1 , entry 1 + - *.z = 1 , entry 2 + - -(1 row) - -SELECT gin_debug_query_value_path('(@# > 0 and #: = 16)'); - gin_debug_query_value_path ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_value_path('*.@# ($ = 4 or $ = 2)'); - gin_debug_query_value_path ----------------------------- - NULL + - -(1 row) - -SELECT gin_debug_query_value_path('tags.#.term. ? ( # = "NYC").x > 0'); - gin_debug_query_value_path ----------------------------------- - tags.#.term.# = "NYC" , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('$ = true'); - gin_debug_query_value_path ----------------------------- - $ = true , entry 0 + - -(1 row) - -SELECT gin_debug_query_value_path('$ . ? (review_votes > 10) . review_rating < 7'); - gin_debug_query_value_path --------------------------------- - AND + - review_rating < 7 , entry 0 + - review_votes > 10 , entry 1 + - -(1 row) - -SELECT gin_debug_query_value_path('similar_product_ids . ? (# = "B0002W4TL2") . $'); - gin_debug_query_value_path -------------------------------------------------- - similar_product_ids.# = "B0002W4TL2" , entry 0 + - -(1 row) - ----table and index -select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 > 0; - count -------- - 654 -(1 row) - -select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 > 19; - count -------- - 13 -(1 row) - -select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 < 19; - count -------- - 985 -(1 row) - -select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 >= 19; - count -------- - 16 -(1 row) - -select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 <= 19; - count -------- - 988 -(1 row) - -select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 = 19; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 > 16 AND - (v->>'review_helpful_votes')::int4 < 20; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 0'::jsquery; - count -------- - 654 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 19'::jsquery; - count -------- - 13 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes < 19'::jsquery; - count -------- - 985 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes >= 19'::jsquery; - count -------- - 16 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes <= 19'::jsquery; - count -------- - 988 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes = 19'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 16'::jsquery AND - v @@ 'review_helpful_votes < 20'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 16 and review_helpful_votes < 20'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes ($ > 16 and $ < 20)'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids && ["0440180295"]'::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids(# = "0440180295") '::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#($ = "0440180295") '::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids && ["0440180295"] and product_sales_rank > 300000'::jsquery; - count -------- - 4 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids <@ ["B00000DG0U", "B00004SQXU", "B0001XAM18", "B00000FDBU", "B00000FDBV", "B000002H2H", "B000002H6C", "B000002H5E", "B000002H97", "B000002HMH"]'::jsquery; - count -------- - 54 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids @> ["B000002H2H", "B000002H6C"]'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ 'customer_id = null'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_votes = true'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 'product_group = false'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 't = *'::jsquery; - count -------- - 10 -(1 row) - -select count(*) from test_jsquery where v @@ 't is boolean'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is string'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is numeric'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is array'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is object'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is boolean'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is string'::jsquery; - count -------- - 4 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is numeric'::jsquery; - count -------- - 5 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is array'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is object'::jsquery; - count -------- - 1017 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is numeric'::jsquery; - count -------- - 51 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is string'::jsquery; - count -------- - 1001 -(1 row) - -select count(*) from test_jsquery where v @@ 'NOT similar_product_ids.#: (NOT $ = "0440180295")'::jsquery; - count -------- - 40 -(1 row) - -select count(*) from test_jsquery where v @@ '$ > 2'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ '$ = false'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't'::jsquery; - count -------- - 10 -(1 row) - -select count(*) from test_jsquery where v @@ '$'::jsquery; - count -------- - 1034 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#'::jsquery; - count -------- - 1001 -(1 row) - -select count(*) from test_jsquery where v @@ '$ . ? (review_votes > 10) . review_rating < 7'::jsquery; - count -------- - 79 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids . ? (# = "B0002W4TL2") . $'::jsquery; - count -------- - 3 -(1 row) - -select v from test_jsquery where v @@ 'array <@ [2,3]'::jsquery order by v; - v -------------------- - {"array": [2]} - {"array": [2, 3]} -(2 rows) - -select v from test_jsquery where v @@ 'array && [2,3]'::jsquery order by v; - v ----------------------- - {"array": [2]} - {"array": [2, 3]} - {"array": [1, 2, 3]} - {"array": [2, 3, 4]} - {"array": [3, 4, 5]} -(5 rows) - -select v from test_jsquery where v @@ 'array @> [2,3]'::jsquery order by v; - v ----------------------- - {"array": [2, 3]} - {"array": [1, 2, 3]} - {"array": [2, 3, 4]} -(3 rows) - -select v from test_jsquery where v @@ 'array = [2,3]'::jsquery order by v; - v -------------------- - {"array": [2, 3]} -(1 row) - -create index t_idx on test_jsquery using gin (v jsonb_value_path_ops); -set enable_seqscan = off; -explain (costs off) select count(*) from test_jsquery where v @@ 'review_helpful_votes > 0'::jsquery; - QUERY PLAN ------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"review_helpful_votes" > 0'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"review_helpful_votes" > 0'::jsquery) -(5 rows) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 0'::jsquery; - count -------- - 654 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 19'::jsquery; - count -------- - 13 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes < 19'::jsquery; - count -------- - 985 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes >= 19'::jsquery; - count -------- - 16 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes <= 19'::jsquery; - count -------- - 988 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes = 19'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 16'::jsquery AND - v @@ 'review_helpful_votes < 20'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 16 and review_helpful_votes < 20'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes ($ > 16 and $ < 20)'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids && ["0440180295"]'::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids(# = "0440180295") '::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#($ = "0440180295") '::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids && ["0440180295"] and product_sales_rank > 300000'::jsquery; - count -------- - 4 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids <@ ["B00000DG0U", "B00004SQXU", "B0001XAM18", "B00000FDBU", "B00000FDBV", "B000002H2H", "B000002H6C", "B000002H5E", "B000002H97", "B000002HMH"]'::jsquery; - count -------- - 54 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids @> ["B000002H2H", "B000002H6C"]'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ 'customer_id = null'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_votes = true'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 'product_group = false'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 't = *'::jsquery; - count -------- - 10 -(1 row) - -select count(*) from test_jsquery where v @@ 't is boolean'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is string'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is numeric'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is array'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is object'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is boolean'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is string'::jsquery; - count -------- - 4 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is numeric'::jsquery; - count -------- - 5 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is array'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is object'::jsquery; - count -------- - 1017 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is numeric'::jsquery; - count -------- - 51 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is string'::jsquery; - count -------- - 1001 -(1 row) - -select count(*) from test_jsquery where v @@ 'NOT similar_product_ids.#: (NOT $ = "0440180295")'::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ '$ > 2'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ '$ = false'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't'::jsquery; - count -------- - 10 -(1 row) - -select count(*) from test_jsquery where v @@ '$'::jsquery; - count -------- - 1034 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#'::jsquery; - count -------- - 1001 -(1 row) - -select count(*) from test_jsquery where v @@ '$ . ? (review_votes > 10) . review_rating < 7'::jsquery; - count -------- - 79 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids . ? (# = "B0002W4TL2") . $'::jsquery; - count -------- - 3 -(1 row) - -explain (costs off) select v from test_jsquery where v @@ 'array <@ [2,3]'::jsquery order by v; - QUERY PLAN ---------------------------------------------------------------- - Sort - Sort Key: v - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"array" <@ [2, 3]'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"array" <@ [2, 3]'::jsquery) -(6 rows) - -explain (costs off) select v from test_jsquery where v @@ 'array && [2,3]'::jsquery order by v; - QUERY PLAN ---------------------------------------------------------------- - Sort - Sort Key: v - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"array" && [2, 3]'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"array" && [2, 3]'::jsquery) -(6 rows) - -explain (costs off) select v from test_jsquery where v @@ 'array @> [2,3]'::jsquery order by v; - QUERY PLAN ---------------------------------------------------------------- - Sort - Sort Key: v - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"array" @> [2, 3]'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"array" @> [2, 3]'::jsquery) -(6 rows) - -explain (costs off) select v from test_jsquery where v @@ 'array = [2,3]'::jsquery order by v; - QUERY PLAN --------------------------------------------------------------- - Sort - Sort Key: v - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"array" = [2, 3]'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"array" = [2, 3]'::jsquery) -(6 rows) - -select v from test_jsquery where v @@ 'array <@ [2,3]'::jsquery order by v; - v -------------------- - {"array": [2]} - {"array": [2, 3]} -(2 rows) - -select v from test_jsquery where v @@ 'array && [2,3]'::jsquery order by v; - v ----------------------- - {"array": [2]} - {"array": [2, 3]} - {"array": [1, 2, 3]} - {"array": [2, 3, 4]} - {"array": [3, 4, 5]} -(5 rows) - -select v from test_jsquery where v @@ 'array @> [2,3]'::jsquery order by v; - v ----------------------- - {"array": [2, 3]} - {"array": [1, 2, 3]} - {"array": [2, 3, 4]} -(3 rows) - -select v from test_jsquery where v @@ 'array = [2,3]'::jsquery order by v; - v -------------------- - {"array": [2, 3]} -(1 row) - -drop index t_idx; -create index t_idx on test_jsquery using gin (v jsonb_path_value_ops); -set enable_seqscan = off; -explain (costs off) select count(*) from test_jsquery where v @@ 'review_helpful_votes > 0'::jsquery; - QUERY PLAN ------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"review_helpful_votes" > 0'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"review_helpful_votes" > 0'::jsquery) -(5 rows) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 0'::jsquery; - count -------- - 654 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 19'::jsquery; - count -------- - 13 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes < 19'::jsquery; - count -------- - 985 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes >= 19'::jsquery; - count -------- - 16 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes <= 19'::jsquery; - count -------- - 988 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes = 19'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 16'::jsquery AND - v @@ 'review_helpful_votes < 20'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes > 16 and review_helpful_votes < 20'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_helpful_votes ($ > 16 and $ < 20)'::jsquery; - count -------- - 8 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids && ["0440180295"]'::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids(# = "0440180295") '::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#($ = "0440180295") '::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids && ["0440180295"] and product_sales_rank > 300000'::jsquery; - count -------- - 4 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids <@ ["B00000DG0U", "B00004SQXU", "B0001XAM18", "B00000FDBU", "B00000FDBV", "B000002H2H", "B000002H6C", "B000002H5E", "B000002H97", "B000002HMH"]'::jsquery; - count -------- - 54 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids @> ["B000002H2H", "B000002H6C"]'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ 'customer_id = null'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 'review_votes = true'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 'product_group = false'::jsquery; - count -------- - 1 -(1 row) - -select count(*) from test_jsquery where v @@ 't = *'::jsquery; - count -------- - 10 -(1 row) - -select count(*) from test_jsquery where v @@ 't is boolean'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is string'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is numeric'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is array'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't is object'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is boolean'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is string'::jsquery; - count -------- - 4 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is numeric'::jsquery; - count -------- - 5 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is array'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ '$ is object'::jsquery; - count -------- - 1017 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is numeric'::jsquery; - count -------- - 51 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#: is string'::jsquery; - count -------- - 1001 -(1 row) - -select count(*) from test_jsquery where v @@ 'NOT similar_product_ids.#: (NOT $ = "0440180295")'::jsquery; - count -------- - 7 -(1 row) - -select count(*) from test_jsquery where v @@ '$ > 2'::jsquery; - count -------- - 3 -(1 row) - -select count(*) from test_jsquery where v @@ '$ = false'::jsquery; - count -------- - 2 -(1 row) - -select count(*) from test_jsquery where v @@ 't'::jsquery; - count -------- - 10 -(1 row) - -select count(*) from test_jsquery where v @@ '$'::jsquery; - count -------- - 1034 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids.#'::jsquery; - count -------- - 950 -(1 row) - -select count(*) from test_jsquery where v @@ '$ . ? (review_votes > 10) . review_rating < 7'::jsquery; - count -------- - 79 -(1 row) - -select count(*) from test_jsquery where v @@ 'similar_product_ids . ? (# = "B0002W4TL2") . $'::jsquery; - count -------- - 3 -(1 row) - -explain (costs off) select v from test_jsquery where v @@ 'array <@ [2,3]'::jsquery order by v; - QUERY PLAN ---------------------------------------------------------------- - Sort - Sort Key: v - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"array" <@ [2, 3]'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"array" <@ [2, 3]'::jsquery) -(6 rows) - -explain (costs off) select v from test_jsquery where v @@ 'array && [2,3]'::jsquery order by v; - QUERY PLAN ---------------------------------------------------------------- - Sort - Sort Key: v - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"array" && [2, 3]'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"array" && [2, 3]'::jsquery) -(6 rows) - -explain (costs off) select v from test_jsquery where v @@ 'array @> [2,3]'::jsquery order by v; - QUERY PLAN ---------------------------------------------------------------- - Sort - Sort Key: v - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"array" @> [2, 3]'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"array" @> [2, 3]'::jsquery) -(6 rows) - -explain (costs off) select v from test_jsquery where v @@ 'array = [2,3]'::jsquery order by v; - QUERY PLAN --------------------------------------------------------------- - Sort - Sort Key: v - -> Bitmap Heap Scan on test_jsquery - Recheck Cond: (v @@ '"array" = [2, 3]'::jsquery) - -> Bitmap Index Scan on t_idx - Index Cond: (v @@ '"array" = [2, 3]'::jsquery) -(6 rows) - -select v from test_jsquery where v @@ 'array <@ [2,3]'::jsquery order by v; - v -------------------- - {"array": [2]} - {"array": [2, 3]} -(2 rows) - -select v from test_jsquery where v @@ 'array && [2,3]'::jsquery order by v; - v ----------------------- - {"array": [2]} - {"array": [2, 3]} - {"array": [1, 2, 3]} - {"array": [2, 3, 4]} - {"array": [3, 4, 5]} -(5 rows) - -select v from test_jsquery where v @@ 'array @> [2,3]'::jsquery order by v; - v ----------------------- - {"array": [2, 3]} - {"array": [1, 2, 3]} - {"array": [2, 3, 4]} -(3 rows) - -select v from test_jsquery where v @@ 'array = [2,3]'::jsquery order by v; - v -------------------- - {"array": [2, 3]} -(1 row) - -RESET enable_seqscan; diff --git a/jsquery_gram.y b/jsquery_gram.y index fd05e7a..7dd956e 100644 --- a/jsquery_gram.y +++ b/jsquery_gram.y @@ -219,7 +219,6 @@ makeItemList(List *list) { %pure-parser %expect 0 %name-prefix="jsquery_yy" -%error-verbose %parse-param {JsQueryParseItem **result} %union { From dc1b28deb29e599913bf8b5dac0d8f3654149d2d Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Fri, 11 Sep 2026 14:38:00 +0300 Subject: [PATCH 8/8] Fix a typo in jsquery_scan.l --- jsquery_scan.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsquery_scan.l b/jsquery_scan.l index 1452e13..907b319 100644 --- a/jsquery_scan.l +++ b/jsquery_scan.l @@ -168,7 +168,7 @@ unicode \\u[0-9A-Fa-f]{4} \\. { yyerror(NULL, "Escape sequence is invalid"); } -\\ { yyerror(NULL, "Unexpected end after backslesh"); } +\\ { yyerror(NULL, "Unexpected end after backslash"); } <> { yyerror(NULL, "Unexpected end of quoted string"); }