mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-20 03:33:23 +02:00
Since 9.5, it's possible that some but not all columns of an index support returning the indexed value for index-only scans. If the same indexed column appears in index columns that behave both ways, check_index_only() supposed that it'd be OK to do an index-only scan testing that column; but that fails if we have to recheck the indexed condition on one of the columns that doesn't support this. In principle we could make this work by remapping the recheck expressions to pull the value from a column that does support returning the indexed value. But such cases are so weird and rare that, at least for now, it doesn't seem worth the trouble. Instead, just teach check_index_only that a value is returnable only if all the index columns containing it are returnable, rather than any of them. Per report from David Pereiro Lagares. Back-patch to 9.5 where the possibility of this situation appeared. Kyotaro Horiguchi Discussion: https://postgr.es/m/1516210494.1798.16.camel@nlpgo.com
106 lines
2.3 KiB
Plaintext
106 lines
2.3 KiB
Plaintext
-- inet check
|
|
CREATE TABLE inettmp (a inet);
|
|
\copy inettmp from 'data/inet.data'
|
|
SET enable_seqscan=on;
|
|
SELECT count(*) FROM inettmp WHERE a < '89.225.196.191';
|
|
count
|
|
-------
|
|
213
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a <= '89.225.196.191';
|
|
count
|
|
-------
|
|
214
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a = '89.225.196.191';
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a >= '89.225.196.191';
|
|
count
|
|
-------
|
|
387
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a > '89.225.196.191';
|
|
count
|
|
-------
|
|
386
|
|
(1 row)
|
|
|
|
CREATE INDEX inetidx ON inettmp USING gist ( a );
|
|
SET enable_seqscan=off;
|
|
SELECT count(*) FROM inettmp WHERE a < '89.225.196.191'::inet;
|
|
count
|
|
-------
|
|
213
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a <= '89.225.196.191'::inet;
|
|
count
|
|
-------
|
|
214
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet;
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a >= '89.225.196.191'::inet;
|
|
count
|
|
-------
|
|
387
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a > '89.225.196.191'::inet;
|
|
count
|
|
-------
|
|
386
|
|
(1 row)
|
|
|
|
VACUUM inettmp;
|
|
-- gist_inet_ops lacks a fetch function, so this should not be index-only scan
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet;
|
|
QUERY PLAN
|
|
--------------------------------------------------------
|
|
Aggregate
|
|
-> Bitmap Heap Scan on inettmp
|
|
Recheck Cond: (a = '89.225.196.191'::inet)
|
|
-> Bitmap Index Scan on inetidx
|
|
Index Cond: (a = '89.225.196.191'::inet)
|
|
(5 rows)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet;
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|
|
DROP INDEX inetidx;
|
|
CREATE INDEX ON inettmp USING gist (a gist_inet_ops, a inet_ops);
|
|
-- likewise here (checks for core planner bug)
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet;
|
|
QUERY PLAN
|
|
--------------------------------------------------------
|
|
Aggregate
|
|
-> Bitmap Heap Scan on inettmp
|
|
Recheck Cond: (a = '89.225.196.191'::inet)
|
|
-> Bitmap Index Scan on inettmp_a_a1_idx
|
|
Index Cond: (a = '89.225.196.191'::inet)
|
|
(5 rows)
|
|
|
|
SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet;
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|