Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6bdc300

Browse files
committed
Fix indexable-row-comparison logic to account for covering indexes.
indxpath.c needs a good deal more attention for covering indexes than it's gotten. But so far as I can tell, the only really awful breakage is in expand_indexqual_rowcompare (nee adjust_rowcompare_for_index), which was only half fixed in c266ed3. The other problems aren't bad enough to take the risk of a just-before-wrap fix. The problem here is that if the leading column of a row comparison matches an index (allowing this code to be reached), and some later column doesn't match the index, it'll nonetheless believe that that column matches the first included index column. Typically that'll lead to an error like "operator M is not a member of opfamily N" as a result of fetching a garbage opfamily OID. But with enough bad luck, maybe a broken plan would be generated. Discussion: https://postgr.es/m/25526.1549847928@sss.pgh.pa.us
1 parent 72d71e0 commit 6bdc300

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

src/backend/optimizer/path/indxpath.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -3979,7 +3979,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
39793979
break; /* no good, volatile comparison value */
39803980

39813981
/*
3982-
* The Var side can match any column of the index.
3982+
* The Var side can match any key column of the index.
39833983
*/
39843984
for (i = 0; i < index->nkeycolumns; i++)
39853985
{
@@ -3991,7 +3991,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
39913991

39923992
break;
39933993
}
3994-
if (i >= index->ncolumns)
3994+
if (i >= index->nkeycolumns)
39953995
break; /* no match found */
39963996

39973997
/* Add column number to returned list */

src/test/regress/expected/index_including.out

+17
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,23 @@ INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) A
127127
ERROR: null value in column "c2" violates not-null constraint
128128
DETAIL: Failing row contains (1, null, 3, (4,4),(4,4)).
129129
INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x;
130+
explain (costs off)
131+
select * from tbl where (c1,c2,c3) < (2,5,1);
132+
QUERY PLAN
133+
------------------------------------------------
134+
Bitmap Heap Scan on tbl
135+
Filter: (ROW(c1, c2, c3) < ROW(2, 5, 1))
136+
-> Bitmap Index Scan on covering
137+
Index Cond: (ROW(c1, c2) <= ROW(2, 5))
138+
(4 rows)
139+
140+
select * from tbl where (c1,c2,c3) < (2,5,1);
141+
c1 | c2 | c3 | c4
142+
----+----+----+----
143+
1 | 2 | |
144+
2 | 4 | |
145+
(2 rows)
146+
130147
DROP TABLE tbl;
131148
CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
132149
UNIQUE(c1,c2) INCLUDE(c3,c4));

src/test/regress/sql/index_including.sql

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conre
7373
INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
7474
INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
7575
INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x;
76+
explain (costs off)
77+
select * from tbl where (c1,c2,c3) < (2,5,1);
78+
select * from tbl where (c1,c2,c3) < (2,5,1);
7679
DROP TABLE tbl;
7780

7881
CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,

0 commit comments

Comments
 (0)