diff --git a/expected/jsquery.out b/expected/jsquery.out index 8c8d3b1..8fd18f4 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; @@ -72,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 --------- @@ -1188,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 @@ -1297,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 ea1f6dc..0000000 --- a/expected/jsquery_1.out +++ /dev/null @@ -1,3384 +0,0 @@ -CREATE EXTENSION jsquery; -set escape_string_warning=off; -set standard_conforming_strings=on; -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/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_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 { 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_op.c b/jsquery_op.c index 29cfe3d..b8405f7 100644 --- a/jsquery_op.c +++ b/jsquery_op.c @@ -30,45 +30,88 @@ #include "jsquery.h" -typedef struct ResultAccum { - StringInfo buf; +/* ResultAccum is used to accumulate values in a Jsonb array. */ +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; static bool recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, ResultAccum *ra); +/* + * Initialize ResultAccum with the opening WJB_BEGIN_ARRAY token. + */ +static void +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); +} + +/* + * Finalize ResultAccum with the closing WJB_END_ARRAY token, and return the + * resulting Jsonb. + */ +static Jsonb * +raFinalize(ResultAccum *ra) +{ + Assert(ra); + +#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 +} + +/* + * Append one element. + * Note: append only if "ra" is vaild and appendable; otherwise, do nothing. + */ static void -appendResult(ResultAccum *ra, JsonbValue *jb) +raAppendElement(ResultAccum *ra, JsonbValue *jb) { if (ra == NULL || ra->missAppend == true) return; - if (ra->jbArrayState == NULL) - pushJsonbValue(&ra->jbArrayState, WJB_BEGIN_ARRAY, NULL); +#if PG_VERSION_NUM < 190000 + Assert(ra->jbArrayState); /* it's a pointer only before PG19 */ +#endif 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); +#if PG_VERSION_NUM < 190000 + Assert(ra->jbArrayState); /* it's a pointer only before PG19 */ +#endif - 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); } @@ -460,32 +503,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; @@ -525,7 +571,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, { if (jsqGetNext(jsq, &elem) == false) { - appendResult(ra, v); + raAppendElement(ra, v); res = true; } else @@ -537,7 +583,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) @@ -567,7 +613,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; @@ -578,7 +624,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) { @@ -605,7 +651,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; } @@ -651,7 +697,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); @@ -677,7 +723,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; } @@ -763,7 +809,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg, if (res) { if (jsqGetNext(jsq, &elem) == false) { - appendResult(ra, jb); + raAppendElement(ra, jb); res = true; } else @@ -842,21 +888,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(); diff --git a/jsquery_scan.l b/jsquery_scan.l index f145650..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"); } @@ -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; 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: 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);