From b88a365c8008c909103574ec9879ebd16260cacd Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Sat, 8 Mar 2014 14:31:12 -0800 Subject: [PATCH] Failing test for GiST indexes on jsonb arrays Even though in some contexts jsonb arrays of strings have as keys (or at least indexable values) their string elements, this only works with seqscan plans. Both GiST and GIN are broken here, which I'm inclined to consider a submission-blocking issue. This presumably breaks non-utf8 tests for now, but currently it isn't clear to me how I ought to deal with that, so pending an answer I'll go ahead and commit this. --- src/test/regress/data/jsonb.data | 3 ++- src/test/regress/expected/jsonb.out | 31 ++++++++++++++++++++++------- src/test/regress/sql/jsonb.sql | 12 ++++++++--- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/test/regress/data/jsonb.data b/src/test/regress/data/jsonb.data index a54ffc0ac8..0672333f64 100644 --- a/src/test/regress/data/jsonb.data +++ b/src/test/regress/data/jsonb.data @@ -988,6 +988,7 @@ {"world":"CAB", "org":21, "indexed":true, "line":988, "abstract":"ABC"} {"title":"CBC", "status":66, "line":989} {} +{"array":["foo", "bar", "baz"]} {"line":991, "abstract":"BA", "node":"BBB"} {"line":992, "disabled":true, "pos":29, "public":false} {"state":53, "wait":"CB", "subtitle":"CCC", "line":993, "date":"CAC", "public":false, "coauthors":"BB"} @@ -1001,4 +1002,4 @@ {"wait":null, "line":1000} {"age":25} {"age":25.0} -{} \ No newline at end of file +{} diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out index 28cf9b6580..0c7e4869fe 100644 --- a/src/test/regress/expected/jsonb.out +++ b/src/test/regress/expected/jsonb.out @@ -424,6 +424,8 @@ SELECT '{"x":"y"}'::jsonb <> '{"x":"z"}'::jsonb; t (1 row) +CREATE TABLE testjsonb (j jsonb); +\copy testjsonb FROM 'data/jsonb.data' -- containment SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b"}'); jsonb_contains @@ -737,6 +739,13 @@ SELECT jsonb '{"a":"null", "b":"qq"}' ? 'a'; t (1 row) +-- array exists - array elements should behave as keys +SELECT 1 from testjsonb WHERE j->'array' ? 'bar'; + ?column? +---------- + 1 +(1 row) + SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['a','b']); jsonb_exists_any ------------------ @@ -1324,8 +1333,6 @@ SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped; (1 row) -- indexing -CREATE TABLE testjsonb (j jsonb); -\copy testjsonb FROM 'data/jsonb.data' SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; count ------- @@ -1424,8 +1431,17 @@ SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled']; 42 (1 row) +-- array exists - array elements should behave as keys (for index scans too) +CREATE INDEX jidx_array ON testjsonb USING gist((j->'array')); +SELECT 1 from testjsonb WHERE j->'array' ? 'bar'; + ?column? +---------- + 1 +(1 row) + RESET enable_seqscan; DROP INDEX jidx; +DROP INDEX jidx_array; CREATE INDEX jidx ON testjsonb USING gin (j); SET enable_seqscan = off; SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; @@ -1480,7 +1496,7 @@ RESET enable_seqscan; SELECT count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow; count ------- - 4783 + 4784 (1 row) SELECT key, count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow GROUP BY key ORDER BY count DESC, key; @@ -1509,20 +1525,21 @@ SELECT key, count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow GRO auth | 168 abstract | 161 age | 2 -(23 rows) + array | 1 +(24 rows) -- sort/hash SELECT count(distinct j) FROM testjsonb; count ------- - 886 + 887 (1 row) SET enable_hashagg = off; SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2; count ------- - 886 + 887 (1 row) SET enable_hashagg = on; @@ -1530,7 +1547,7 @@ SET enable_sort = off; SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2; count ------- - 886 + 887 (1 row) SELECT distinct * FROM (values (jsonb '{}' || ''),('{}')) v(j); diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql index f125b79fa0..b91ac14e77 100644 --- a/src/test/regress/sql/jsonb.sql +++ b/src/test/regress/sql/jsonb.sql @@ -108,6 +108,9 @@ SELECT '{"x":"y"}'::jsonb = '{"x":"z"}'::jsonb; SELECT '{"x":"y"}'::jsonb <> '{"x":"y"}'::jsonb; SELECT '{"x":"y"}'::jsonb <> '{"x":"z"}'::jsonb; +CREATE TABLE testjsonb (j jsonb); +\copy testjsonb FROM 'data/jsonb.data' + -- containment SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b"}'); SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "c":null}'); @@ -165,6 +168,8 @@ SELECT jsonb '{"a":null, "b":"qq"}' ? 'a'; SELECT jsonb '{"a":null, "b":"qq"}' ? 'b'; SELECT jsonb '{"a":null, "b":"qq"}' ? 'c'; SELECT jsonb '{"a":"null", "b":"qq"}' ? 'a'; +-- array exists - array elements should behave as keys +SELECT 1 from testjsonb WHERE j->'array' ? 'bar'; SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['a','b']); SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['b','a']); @@ -294,9 +299,6 @@ SELECT jsonb '{ "a": "dollar \u0024 character" }' ->> 'a' AS correct_everyWHERE SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped; -- indexing -CREATE TABLE testjsonb (j jsonb); -\copy testjsonb FROM 'data/jsonb.data' - SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}'; SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}'; @@ -317,10 +319,14 @@ SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}'; SELECT count(*) FROM testjsonb WHERE j ? 'public'; SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled']; SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled']; +-- array exists - array elements should behave as keys (for index scans too) +CREATE INDEX jidx_array ON testjsonb USING gist((j->'array')); +SELECT 1 from testjsonb WHERE j->'array' ? 'bar'; RESET enable_seqscan; DROP INDEX jidx; +DROP INDEX jidx_array; CREATE INDEX jidx ON testjsonb USING gin (j); SET enable_seqscan = off; -- 2.39.5