mirror of
https://github.com/postgres/postgres.git
synced 2025-11-21 00:42:43 +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:
@@ -185,7 +185,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
|
||||
Form_pg_index index;
|
||||
IndexAmRoutine *amroutine;
|
||||
IndexOptInfo *info;
|
||||
int ncolumns;
|
||||
int ncolumns,
|
||||
nkeycolumns;
|
||||
int i;
|
||||
|
||||
/*
|
||||
@@ -238,19 +239,25 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
|
||||
RelationGetForm(indexRelation)->reltablespace;
|
||||
info->rel = rel;
|
||||
info->ncolumns = ncolumns = index->indnatts;
|
||||
info->nkeycolumns = nkeycolumns = index->indnkeyatts;
|
||||
|
||||
info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
|
||||
info->indexcollations = (Oid *) palloc(sizeof(Oid) * ncolumns);
|
||||
info->opfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
|
||||
info->opcintype = (Oid *) palloc(sizeof(Oid) * ncolumns);
|
||||
info->opfamily = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
|
||||
info->opcintype = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
|
||||
info->canreturn = (bool *) palloc(sizeof(bool) * ncolumns);
|
||||
|
||||
for (i = 0; i < ncolumns; i++)
|
||||
{
|
||||
info->indexkeys[i] = index->indkey.values[i];
|
||||
info->indexcollations[i] = indexRelation->rd_indcollation[i];
|
||||
info->canreturn[i] = index_can_return(indexRelation, i + 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < nkeycolumns; 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;
|
||||
@@ -279,10 +286,10 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
|
||||
Assert(amroutine->amcanorder);
|
||||
|
||||
info->sortopfamily = info->opfamily;
|
||||
info->reverse_sort = (bool *) palloc(sizeof(bool) * ncolumns);
|
||||
info->nulls_first = (bool *) palloc(sizeof(bool) * ncolumns);
|
||||
info->reverse_sort = (bool *) palloc(sizeof(bool) * nkeycolumns);
|
||||
info->nulls_first = (bool *) palloc(sizeof(bool) * nkeycolumns);
|
||||
|
||||
for (i = 0; i < ncolumns; i++)
|
||||
for (i = 0; i < nkeycolumns; i++)
|
||||
{
|
||||
int16 opt = indexRelation->rd_indoption[i];
|
||||
|
||||
@@ -306,11 +313,11 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
|
||||
* of current or foreseeable amcanorder index types, it's not
|
||||
* worth expending more effort on now.
|
||||
*/
|
||||
info->sortopfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
|
||||
info->reverse_sort = (bool *) palloc(sizeof(bool) * ncolumns);
|
||||
info->nulls_first = (bool *) palloc(sizeof(bool) * ncolumns);
|
||||
info->sortopfamily = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
|
||||
info->reverse_sort = (bool *) palloc(sizeof(bool) * nkeycolumns);
|
||||
info->nulls_first = (bool *) palloc(sizeof(bool) * nkeycolumns);
|
||||
|
||||
for (i = 0; i < ncolumns; i++)
|
||||
for (i = 0; i < nkeycolumns; i++)
|
||||
{
|
||||
int16 opt = indexRelation->rd_indoption[i];
|
||||
Oid ltopr;
|
||||
@@ -731,7 +738,7 @@ infer_arbiter_indexes(PlannerInfo *root)
|
||||
|
||||
/* Build BMS representation of plain (non expression) index attrs */
|
||||
indexedAttrs = NULL;
|
||||
for (natt = 0; natt < idxForm->indnatts; natt++)
|
||||
for (natt = 0; natt < idxForm->indnkeyatts; natt++)
|
||||
{
|
||||
int attno = idxRel->rd_index->indkey.values[natt];
|
||||
|
||||
@@ -1798,7 +1805,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno)
|
||||
* just the specified attr is unique.
|
||||
*/
|
||||
if (index->unique &&
|
||||
index->ncolumns == 1 &&
|
||||
index->nkeycolumns == 1 &&
|
||||
index->indexkeys[0] == attno &&
|
||||
(index->indpred == NIL || index->predOK))
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user