1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-12 21:01:52 +03:00

Add support for index-only scans in GiST.

This adds a new GiST opclass method, 'fetch', which is used to reconstruct
the original Datum from the value stored in the index. Also, the 'canreturn'
index AM interface function gains a new 'attno' argument. That makes it
possible to use index-only scans on a multi-column index where some of the
opclasses support index-only scans but some do not.

This patch adds support in the box and point opclasses. Other opclasses
can added later as follow-on patches (btree_gist would be particularly
interesting).

Anastasia Lubennikova, with additional fixes and modifications by me.
This commit is contained in:
Heikki Linnakangas
2015-03-26 19:12:00 +02:00
parent 8fa393a6d7
commit d04c8ed904
24 changed files with 575 additions and 73 deletions

View File

@ -1786,15 +1786,13 @@ check_index_only(RelOptInfo *rel, IndexOptInfo *index)
{
bool result;
Bitmapset *attrs_used = NULL;
Bitmapset *index_attrs = NULL;
Bitmapset *index_canreturn_attrs = NULL;
ListCell *lc;
int i;
/* Index-only scans must be enabled, and index must be capable of them */
/* Index-only scans must be enabled */
if (!enable_indexonlyscan)
return false;
if (!index->canreturn)
return false;
/*
* Check that all needed attributes of the relation are available from the
@ -1824,7 +1822,10 @@ check_index_only(RelOptInfo *rel, IndexOptInfo *index)
pull_varattnos((Node *) rinfo->clause, rel->relid, &attrs_used);
}
/* Construct a bitmapset of columns stored in the index. */
/*
* Construct a bitmapset of columns that the index can return back in an
* index-only scan.
*/
for (i = 0; i < index->ncolumns; i++)
{
int attno = index->indexkeys[i];
@ -1836,16 +1837,17 @@ check_index_only(RelOptInfo *rel, IndexOptInfo *index)
if (attno == 0)
continue;
index_attrs =
bms_add_member(index_attrs,
attno - FirstLowInvalidHeapAttributeNumber);
if (index->canreturn[i])
index_canreturn_attrs =
bms_add_member(index_canreturn_attrs,
attno - FirstLowInvalidHeapAttributeNumber);
}
/* Do we have all the necessary attributes? */
result = bms_is_subset(attrs_used, index_attrs);
result = bms_is_subset(attrs_used, index_canreturn_attrs);
bms_free(attrs_used);
bms_free(index_attrs);
bms_free(index_canreturn_attrs);
return result;
}

View File

@ -207,6 +207,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
info->indexcollations = (Oid *) palloc(sizeof(Oid) * ncolumns);
info->opfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
info->opcintype = (Oid *) palloc(sizeof(Oid) * ncolumns);
info->canreturn = (bool *) palloc(sizeof(bool) * ncolumns);
for (i = 0; i < ncolumns; i++)
{
@ -214,11 +215,11 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
info->indexcollations[i] = indexRelation->rd_indcollation[i];
info->opfamily[i] = indexRelation->rd_opfamily[i];
info->opcintype[i] = indexRelation->rd_opcintype[i];
info->canreturn[i] = index_can_return(indexRelation, i + 1);
}
info->relam = indexRelation->rd_rel->relam;
info->amcostestimate = indexRelation->rd_am->amcostestimate;
info->canreturn = index_can_return(indexRelation);
info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop;
info->amoptionalkey = indexRelation->rd_am->amoptionalkey;
info->amsearcharray = indexRelation->rd_am->amsearcharray;