mirror of
https://github.com/postgres/postgres.git
synced 2025-08-28 18:48:04 +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:
@@ -158,7 +158,8 @@ IndexScanEnd(IndexScanDesc scan)
|
||||
*
|
||||
* Construct a string describing the contents of an index entry, in the
|
||||
* form "(key_name, ...)=(key_value, ...)". This is currently used
|
||||
* for building unique-constraint and exclusion-constraint error messages.
|
||||
* for building unique-constraint and exclusion-constraint error messages,
|
||||
* so only key columns of the index are checked and printed.
|
||||
*
|
||||
* Note that if the user does not have permissions to view all of the
|
||||
* columns involved then a NULL is returned. Returning a partial key seems
|
||||
@@ -180,13 +181,15 @@ BuildIndexValueDescription(Relation indexRelation,
|
||||
StringInfoData buf;
|
||||
Form_pg_index idxrec;
|
||||
HeapTuple ht_idx;
|
||||
int natts = indexRelation->rd_rel->relnatts;
|
||||
int indnkeyatts;
|
||||
int i;
|
||||
int keyno;
|
||||
Oid indexrelid = RelationGetRelid(indexRelation);
|
||||
Oid indrelid;
|
||||
AclResult aclresult;
|
||||
|
||||
indnkeyatts = IndexRelationGetNumberOfKeyAttributes(indexRelation);
|
||||
|
||||
/*
|
||||
* Check permissions- if the user does not have access to view all of the
|
||||
* key columns then return NULL to avoid leaking data.
|
||||
@@ -224,7 +227,7 @@ BuildIndexValueDescription(Relation indexRelation,
|
||||
* No table-level access, so step through the columns in the index and
|
||||
* make sure the user has SELECT rights on all of them.
|
||||
*/
|
||||
for (keyno = 0; keyno < idxrec->indnatts; keyno++)
|
||||
for (keyno = 0; keyno < idxrec->indnkeyatts; keyno++)
|
||||
{
|
||||
AttrNumber attnum = idxrec->indkey.values[keyno];
|
||||
|
||||
@@ -250,7 +253,7 @@ BuildIndexValueDescription(Relation indexRelation,
|
||||
appendStringInfo(&buf, "(%s)=(",
|
||||
pg_get_indexdef_columns(indexrelid, true));
|
||||
|
||||
for (i = 0; i < natts; i++)
|
||||
for (i = 0; i < indnkeyatts; i++)
|
||||
{
|
||||
char *val;
|
||||
|
||||
@@ -368,7 +371,7 @@ systable_beginscan(Relation heapRelation,
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < irel->rd_index->indnatts; j++)
|
||||
for (j = 0; j < IndexRelationGetNumberOfAttributes(irel); j++)
|
||||
{
|
||||
if (key[i].sk_attno == irel->rd_index->indkey.values[j])
|
||||
{
|
||||
@@ -376,7 +379,7 @@ systable_beginscan(Relation heapRelation,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == irel->rd_index->indnatts)
|
||||
if (j == IndexRelationGetNumberOfAttributes(irel))
|
||||
elog(ERROR, "column is not in index");
|
||||
}
|
||||
|
||||
@@ -570,7 +573,7 @@ systable_beginscan_ordered(Relation heapRelation,
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < indexRelation->rd_index->indnatts; j++)
|
||||
for (j = 0; j < IndexRelationGetNumberOfAttributes(indexRelation); j++)
|
||||
{
|
||||
if (key[i].sk_attno == indexRelation->rd_index->indkey.values[j])
|
||||
{
|
||||
@@ -578,7 +581,7 @@ systable_beginscan_ordered(Relation heapRelation,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == indexRelation->rd_index->indnatts)
|
||||
if (j == IndexRelationGetNumberOfAttributes(indexRelation))
|
||||
elog(ERROR, "column is not in index");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user