Failing test for GiST indexes on jsonb arrays
authorPeter Geoghegan <[email protected]>
Sat, 8 Mar 2014 22:31:12 +0000 (14:31 -0800)
committerPeter Geoghegan <[email protected]>
Sat, 8 Mar 2014 22:31:12 +0000 (14:31 -0800)
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
src/test/regress/expected/jsonb.out
src/test/regress/sql/jsonb.sql

index a54ffc0ac8dc77e38cc6f653a25a313f1fcf6c22..0672333f644e385bddd67f907eef5e233f1e0a55 100644 (file)
 {"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"}
 {"wait":null, "line":1000}
 {"age":25}
 {"age":25.0}
-{}
\ No newline at end of file
+{}
index 28cf9b65801ce5d86b2fa83478e836e33641f48b..0c7e4869fe127aa8c8acf1a2ed0ea379ad90469a 100644 (file)
@@ -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);
index f125b79fa00c4cbcc707c01f47fa0819e85b66ff..b91ac14e7795b53059797e992cf4f804fcdd1bc1 100644 (file)
@@ -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;