summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-03-01 15:35:03 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2018-03-01 15:35:03 -0500
commit3f26be83ec1e8976566d020da738c032c4aee3f3 (patch)
tree36d9c58f1693ec22f3b958aed292f219714b5e83 /src/backend
parent11e7700e584e818b40013ef8e6bb17d04d8210f8 (diff)
Fix IOS planning when only some index columns can return an attribute.
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
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/optimizer/path/indxpath.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 2952bfb7c22..47a01b3ad0a 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -1791,6 +1791,7 @@ check_index_only(RelOptInfo *rel, IndexOptInfo *index)
bool result;
Bitmapset *attrs_used = NULL;
Bitmapset *index_canreturn_attrs = NULL;
+ Bitmapset *index_cannotreturn_attrs = NULL;
ListCell *lc;
int i;
@@ -1830,7 +1831,11 @@ check_index_only(RelOptInfo *rel, IndexOptInfo *index)
/*
* Construct a bitmapset of columns that the index can return back in an
- * index-only scan.
+ * index-only scan. If there are multiple index columns containing the
+ * same attribute, all of them must be capable of returning the value,
+ * since we might recheck operators on any of them. (Potentially we could
+ * be smarter about that, but it's such a weird situation that it doesn't
+ * seem worth spending a lot of sweat on.)
*/
for (i = 0; i < index->ncolumns; i++)
{
@@ -1847,13 +1852,21 @@ check_index_only(RelOptInfo *rel, IndexOptInfo *index)
index_canreturn_attrs =
bms_add_member(index_canreturn_attrs,
attno - FirstLowInvalidHeapAttributeNumber);
+ else
+ index_cannotreturn_attrs =
+ bms_add_member(index_cannotreturn_attrs,
+ attno - FirstLowInvalidHeapAttributeNumber);
}
+ index_canreturn_attrs = bms_del_members(index_canreturn_attrs,
+ index_cannotreturn_attrs);
+
/* Do we have all the necessary attributes? */
result = bms_is_subset(attrs_used, index_canreturn_attrs);
bms_free(attrs_used);
bms_free(index_canreturn_attrs);
+ bms_free(index_cannotreturn_attrs);
return result;
}