mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Support for INCLUDE attributes in GiST indexes
Similarly to B-tree, GiST index access method gets support of INCLUDE attributes. These attributes aren't used for tree navigation and aren't present in non-leaf pages. But they are present in leaf pages and can be fetched during index-only scan. The point of having INCLUDE attributes in GiST indexes is slightly different from the point of having them in B-tree. The main point of INCLUDE attributes in B-tree is to define UNIQUE constraint over part of attributes enabled for index-only scan. In GiST the main point of INCLUDE attributes is to use index-only scan for attributes, whose data types don't have GiST opclasses. Discussion: https://postgr.es/m/73A1A452-AD5F-40D4-BD61-978622FF75C1%40yandex-team.ru Author: Andrey Borodin, with small changes by me Reviewed-by: Andreas Karlsson
This commit is contained in:
@ -75,7 +75,7 @@ gisthandler(PG_FUNCTION_ARGS)
|
||||
amroutine->amclusterable = true;
|
||||
amroutine->ampredlocks = true;
|
||||
amroutine->amcanparallel = false;
|
||||
amroutine->amcaninclude = false;
|
||||
amroutine->amcaninclude = true;
|
||||
amroutine->amkeytype = InvalidOid;
|
||||
|
||||
amroutine->ambuild = gistbuild;
|
||||
@ -1382,8 +1382,10 @@ gistSplit(Relation r,
|
||||
IndexTupleSize(itup[0]), GiSTPageSize,
|
||||
RelationGetRelationName(r))));
|
||||
|
||||
memset(v.spl_lisnull, true, sizeof(bool) * giststate->tupdesc->natts);
|
||||
memset(v.spl_risnull, true, sizeof(bool) * giststate->tupdesc->natts);
|
||||
memset(v.spl_lisnull, true,
|
||||
sizeof(bool) * giststate->nonLeafTupdesc->natts);
|
||||
memset(v.spl_risnull, true,
|
||||
sizeof(bool) * giststate->nonLeafTupdesc->natts);
|
||||
gistSplitByKey(r, page, itup, len, giststate, &v, 0);
|
||||
|
||||
/* form left and right vector */
|
||||
@ -1461,9 +1463,23 @@ initGISTstate(Relation index)
|
||||
|
||||
giststate->scanCxt = scanCxt;
|
||||
giststate->tempCxt = scanCxt; /* caller must change this if needed */
|
||||
giststate->tupdesc = index->rd_att;
|
||||
giststate->leafTupdesc = index->rd_att;
|
||||
|
||||
for (i = 0; i < index->rd_att->natts; i++)
|
||||
/*
|
||||
* The truncated tupdesc for non-leaf index tuples, which doesn't contain
|
||||
* the INCLUDE attributes.
|
||||
*
|
||||
* It is used to form tuples during tuple adjustement and page split.
|
||||
* B-tree creates shortened tuple descriptor for every truncated tuple,
|
||||
* because it is doing this less often: it does not have to form truncated
|
||||
* tuples during page split. Also, B-tree is not adjusting tuples on
|
||||
* internal pages the way GiST does.
|
||||
*/
|
||||
giststate->nonLeafTupdesc = CreateTupleDescCopyConstr(index->rd_att);
|
||||
giststate->nonLeafTupdesc->natts =
|
||||
IndexRelationGetNumberOfKeyAttributes(index);
|
||||
|
||||
for (i = 0; i < IndexRelationGetNumberOfKeyAttributes(index); i++)
|
||||
{
|
||||
fmgr_info_copy(&(giststate->consistentFn[i]),
|
||||
index_getprocinfo(index, i + 1, GIST_CONSISTENT_PROC),
|
||||
@ -1531,6 +1547,21 @@ initGISTstate(Relation index)
|
||||
giststate->supportCollation[i] = DEFAULT_COLLATION_OID;
|
||||
}
|
||||
|
||||
/* No opclass information for INCLUDE attributes */
|
||||
for (; i < index->rd_att->natts; i++)
|
||||
{
|
||||
giststate->consistentFn[i].fn_oid = InvalidOid;
|
||||
giststate->unionFn[i].fn_oid = InvalidOid;
|
||||
giststate->compressFn[i].fn_oid = InvalidOid;
|
||||
giststate->decompressFn[i].fn_oid = InvalidOid;
|
||||
giststate->penaltyFn[i].fn_oid = InvalidOid;
|
||||
giststate->picksplitFn[i].fn_oid = InvalidOid;
|
||||
giststate->equalFn[i].fn_oid = InvalidOid;
|
||||
giststate->distanceFn[i].fn_oid = InvalidOid;
|
||||
giststate->fetchFn[i].fn_oid = InvalidOid;
|
||||
giststate->supportCollation[i] = InvalidOid;
|
||||
}
|
||||
|
||||
MemoryContextSwitchTo(oldCxt);
|
||||
|
||||
return giststate;
|
||||
|
Reference in New Issue
Block a user