diff options
| author | Tom Lane | 2012-03-11 20:29:04 +0000 |
|---|---|---|
| committer | Tom Lane | 2012-03-11 20:29:59 +0000 |
| commit | c6a11b89e48dfb47b305cea405924333dabc20b6 (patch) | |
| tree | 1ef16196fa824d0515789c59f34e46e829a43966 /src/test | |
| parent | fc227a4e3b84f7bc243c4606780dde28aea257ee (diff) | |
Teach SPGiST to store nulls and do whole-index scans.
This patch fixes the other major compatibility-breaking limitation of
SPGiST, that it didn't store anything for null values of the indexed
column, and so could not support whole-index scans or "x IS NULL"
tests. The approach is to create a wholly separate search tree for
the null entries, and use fixed "allTheSame" insertion and search
rules when processing this tree, instead of calling the index opclass
methods. This way the opclass methods do not need to worry about
dealing with nulls.
Catversion bump is for pg_am updates as well as the change in on-disk
format of SPGiST indexes; there are some tweaks in SPGiST WAL records
as well.
Heavily rewritten version of a patch by Oleg Bartunov and Teodor Sigaev.
(The original also stored nulls separately, but it reused GIN code to do
so; which required undesirable compromises in the on-disk format, and
would likely lead to bugs due to the GIN code being required to work in
two very different contexts.)
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/create_index.out | 112 | ||||
| -rw-r--r-- | src/test/regress/sql/create_index.sql | 32 |
2 files changed, 144 insertions, 0 deletions
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index b1fcada1be4..b7497b047f7 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -68,6 +68,7 @@ CREATE TABLE quad_point_tbl AS SELECT point(unique1,unique2) AS p FROM tenk1; INSERT INTO quad_point_tbl SELECT '(333.0,400.0)'::point FROM generate_series(1,1000); +INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL); CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p); CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl; CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops); @@ -227,6 +228,24 @@ SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0 (10,10) (4 rows) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + count +------- + 3 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + count +------- + 11000 +(1 row) + +SELECT count(*) FROM quad_point_tbl; + count +------- + 11003 +(1 row) + SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; count ------- @@ -679,6 +698,50 @@ SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0 (4 rows) EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p IS NULL) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + count +------- + 3 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p IS NOT NULL) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + count +------- + 11000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl +(2 rows) + +SELECT count(*) FROM quad_point_tbl; + count +------- + 11003 +(1 row) + +EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; QUERY PLAN ----------------------------------------------------------- @@ -1109,6 +1172,55 @@ SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0 (4 rows) EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + QUERY PLAN +---------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p IS NULL) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p IS NULL) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + count +------- + 3 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + QUERY PLAN +---------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p IS NOT NULL) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p IS NOT NULL) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + count +------- + 11000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl; + QUERY PLAN +---------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + -> Bitmap Index Scan on sp_quad_ind +(3 rows) + +SELECT count(*) FROM quad_point_tbl; + count +------- + 11003 +(1 row) + +EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; QUERY PLAN --------------------------------------------------------------- diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql index 5e5fc22579b..57f52612dfa 100644 --- a/src/test/regress/sql/create_index.sql +++ b/src/test/regress/sql/create_index.sql @@ -102,6 +102,8 @@ CREATE TABLE quad_point_tbl AS INSERT INTO quad_point_tbl SELECT '(333.0,400.0)'::point FROM generate_series(1,1000); +INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL); + CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p); CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl; @@ -172,6 +174,12 @@ SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM quad_point_tbl; + SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; @@ -306,6 +314,18 @@ SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0 SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl; +SELECT count(*) FROM quad_point_tbl; + +EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; @@ -423,6 +443,18 @@ SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0 SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl; +SELECT count(*) FROM quad_point_tbl; + +EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; |
