1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Indexes with INCLUDE columns and their support in B-tree

This patch introduces INCLUDE clause to index definition.  This clause
specifies a list of columns which will be included as a non-key part in
the index.  The INCLUDE columns exist solely to allow more queries to
benefit from index-only scans.  Also, such columns don't need to have
appropriate operator classes.  Expressions are not supported as INCLUDE
columns since they cannot be used in index-only scans.

Index access methods supporting INCLUDE are indicated by amcaninclude flag
in IndexAmRoutine.  For now, only B-tree indexes support INCLUDE clause.

In B-tree indexes INCLUDE columns are truncated from pivot index tuples
(tuples located in non-leaf pages and high keys).  Therefore, B-tree indexes
now might have variable number of attributes.  This patch also provides
generic facility to support that: pivot tuples contain number of their
attributes in t_tid.ip_posid.  Free 13th bit of t_info is used for indicating
that.  This facility will simplify further support of index suffix truncation.
The changes of above are backward-compatible, pg_upgrade doesn't need special
handling of B-tree indexes for that.

Bump catalog version

Author: Anastasia Lubennikova with contribition by Alexander Korotkov and me
Reviewed by: Peter Geoghegan, Tomas Vondra, Antonin Houska, Jeff Janes,
			 David Rowley, Alexander Korotkov
Discussion: https://www.postgresql.org/message-id/flat/56168952.4010101@postgrespro.ru
This commit is contained in:
Teodor Sigaev
2018-04-07 23:00:39 +03:00
parent 01bb85169a
commit 8224de4f42
89 changed files with 2112 additions and 467 deletions

View File

@ -63,17 +63,28 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
{
ScanKey skey;
TupleDesc itupdesc;
int natts;
int indnatts PG_USED_FOR_ASSERTS_ONLY;
int indnkeyatts;
int16 *indoption;
int i;
itupdesc = RelationGetDescr(rel);
natts = RelationGetNumberOfAttributes(rel);
indnatts = IndexRelationGetNumberOfAttributes(rel);
indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
indoption = rel->rd_indoption;
skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
Assert(indnkeyatts != 0);
Assert(indnkeyatts <= indnatts);
Assert(BTreeTupGetNAtts(itup, rel) == indnatts ||
BTreeTupGetNAtts(itup, rel) == indnkeyatts);
for (i = 0; i < natts; i++)
/*
* We'll execute search using ScanKey constructed on key columns. Non key
* (included) columns must be omitted.
*/
skey = (ScanKey) palloc(indnkeyatts * sizeof(ScanKeyData));
for (i = 0; i < indnkeyatts; i++)
{
FmgrInfo *procinfo;
Datum arg;
@ -115,16 +126,16 @@ ScanKey
_bt_mkscankey_nodata(Relation rel)
{
ScanKey skey;
int natts;
int indnkeyatts;
int16 *indoption;
int i;
natts = RelationGetNumberOfAttributes(rel);
indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
indoption = rel->rd_indoption;
skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
skey = (ScanKey) palloc(indnkeyatts * sizeof(ScanKeyData));
for (i = 0; i < natts; i++)
for (i = 0; i < indnkeyatts; i++)
{
FmgrInfo *procinfo;
int flags;
@ -2069,3 +2080,30 @@ btproperty(Oid index_oid, int attno,
return false; /* punt to generic code */
}
}
/*
* _bt_truncate_tuple() -- remove non-key (INCLUDE) attributes from index
* tuple.
*
* Transforms an ordinal B-tree leaf index tuple into pivot tuple to be used
* as hikey or non-leaf page tuple with downlink. Note that t_tid offset
* will be overritten in order to represent number of present tuple attributes.
*/
IndexTuple
_bt_truncate_tuple(Relation idxrel, IndexTuple olditup)
{
IndexTuple newitup;
int nkeyattrs = IndexRelationGetNumberOfKeyAttributes(idxrel);
/*
* We're assuming to truncate only regular leaf index tuples which have
* both key and non-key attributes.
*/
Assert(BTreeTupGetNAtts(olditup, idxrel) == IndexRelationGetNumberOfAttributes(idxrel));
newitup = index_truncate_tuple(RelationGetDescr(idxrel),
olditup, nkeyattrs);
BTreeTupSetNAtts(newitup, nkeyattrs);
return newitup;
}