mirror of
https://github.com/postgres/postgres.git
synced 2025-10-31 10:30:33 +03:00
CREATE INDEX ... INCLUDING (column[, ...])
Now indexes (but only B-tree for now) can contain "extra" column(s) which doesn't participate in index structure, they are just stored in leaf tuples. It allows to use index only scan by using single index instead of two or more indexes. Author: Anastasia Lubennikova with minor editorializing by me Reviewers: David Rowley, Peter Geoghegan, Jeff Janes
This commit is contained in:
@@ -78,8 +78,6 @@ static OffsetNumber _bt_findsplitloc(Relation rel, Page page,
|
||||
static void _bt_checksplitloc(FindSplitData *state,
|
||||
OffsetNumber firstoldonright, bool newitemonleft,
|
||||
int dataitemstoleft, Size firstoldonrightsz);
|
||||
static bool _bt_pgaddtup(Page page, Size itemsize, IndexTuple itup,
|
||||
OffsetNumber itup_off);
|
||||
static bool _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
|
||||
int keysz, ScanKey scankey);
|
||||
static void _bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel);
|
||||
@@ -108,18 +106,22 @@ _bt_doinsert(Relation rel, IndexTuple itup,
|
||||
IndexUniqueCheck checkUnique, Relation heapRel)
|
||||
{
|
||||
bool is_unique = false;
|
||||
int natts = rel->rd_rel->relnatts;
|
||||
int indnkeyatts;
|
||||
ScanKey itup_scankey;
|
||||
BTStack stack;
|
||||
Buffer buf;
|
||||
OffsetNumber offset;
|
||||
|
||||
Assert(IndexRelationGetNumberOfAttributes(rel) != 0);
|
||||
indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
|
||||
Assert(indnkeyatts != 0);
|
||||
|
||||
/* we need an insertion scan key to do our search, so build one */
|
||||
itup_scankey = _bt_mkscankey(rel, itup);
|
||||
|
||||
top:
|
||||
/* find the first page containing this key */
|
||||
stack = _bt_search(rel, natts, itup_scankey, false, &buf, BT_WRITE);
|
||||
stack = _bt_search(rel, indnkeyatts, itup_scankey, false, &buf, BT_WRITE);
|
||||
|
||||
offset = InvalidOffsetNumber;
|
||||
|
||||
@@ -134,7 +136,7 @@ top:
|
||||
* move right in the tree. See Lehman and Yao for an excruciatingly
|
||||
* precise description.
|
||||
*/
|
||||
buf = _bt_moveright(rel, buf, natts, itup_scankey, false,
|
||||
buf = _bt_moveright(rel, buf, indnkeyatts, itup_scankey, false,
|
||||
true, stack, BT_WRITE);
|
||||
|
||||
/*
|
||||
@@ -163,7 +165,7 @@ top:
|
||||
TransactionId xwait;
|
||||
uint32 speculativeToken;
|
||||
|
||||
offset = _bt_binsrch(rel, buf, natts, itup_scankey, false);
|
||||
offset = _bt_binsrch(rel, buf, indnkeyatts, itup_scankey, false);
|
||||
xwait = _bt_check_unique(rel, itup, heapRel, buf, offset, itup_scankey,
|
||||
checkUnique, &is_unique, &speculativeToken);
|
||||
|
||||
@@ -199,7 +201,7 @@ top:
|
||||
*/
|
||||
CheckForSerializableConflictIn(rel, NULL, buf);
|
||||
/* do the insertion */
|
||||
_bt_findinsertloc(rel, &buf, &offset, natts, itup_scankey, itup,
|
||||
_bt_findinsertloc(rel, &buf, &offset, indnkeyatts, itup_scankey, itup,
|
||||
stack, heapRel);
|
||||
_bt_insertonpg(rel, buf, InvalidBuffer, stack, itup, offset, false);
|
||||
}
|
||||
@@ -242,7 +244,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
|
||||
uint32 *speculativeToken)
|
||||
{
|
||||
TupleDesc itupdesc = RelationGetDescr(rel);
|
||||
int natts = rel->rd_rel->relnatts;
|
||||
int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
|
||||
SnapshotData SnapshotDirty;
|
||||
OffsetNumber maxoff;
|
||||
Page page;
|
||||
@@ -301,7 +303,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
|
||||
* in real comparison, but only for ordering/finding items on
|
||||
* pages. - vadim 03/24/97
|
||||
*/
|
||||
if (!_bt_isequal(itupdesc, page, offset, natts, itup_scankey))
|
||||
if (!_bt_isequal(itupdesc, page, offset, indnkeyatts, itup_scankey))
|
||||
break; /* we're past all the equal tuples */
|
||||
|
||||
/* okay, we gotta fetch the heap tuple ... */
|
||||
@@ -465,7 +467,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
|
||||
if (P_RIGHTMOST(opaque))
|
||||
break;
|
||||
if (!_bt_isequal(itupdesc, page, P_HIKEY,
|
||||
natts, itup_scankey))
|
||||
indnkeyatts, itup_scankey))
|
||||
break;
|
||||
/* Advance to next non-dead page --- there must be one */
|
||||
for (;;)
|
||||
@@ -980,6 +982,9 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright,
|
||||
OffsetNumber i;
|
||||
bool isroot;
|
||||
bool isleaf;
|
||||
IndexTuple lefthikey;
|
||||
int indnatts = IndexRelationGetNumberOfAttributes(rel);
|
||||
int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
|
||||
|
||||
/* Acquire a new page to split into */
|
||||
rbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
|
||||
@@ -1080,7 +1085,22 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright,
|
||||
itemsz = ItemIdGetLength(itemid);
|
||||
item = (IndexTuple) PageGetItem(origpage, itemid);
|
||||
}
|
||||
if (PageAddItem(leftpage, (Item) item, itemsz, leftoff,
|
||||
|
||||
/*
|
||||
* We must truncate the "high key" item, before insert it onto the leaf page.
|
||||
* It's the only point in insertion process, where we perform truncation.
|
||||
* All other functions work with this high key and do not change it.
|
||||
*/
|
||||
if (indnatts != indnkeyatts && P_ISLEAF(lopaque))
|
||||
{
|
||||
lefthikey = index_truncate_tuple(rel, item);
|
||||
itemsz = IndexTupleSize(lefthikey);
|
||||
itemsz = MAXALIGN(itemsz);
|
||||
}
|
||||
else
|
||||
lefthikey = item;
|
||||
|
||||
if (PageAddItem(leftpage, (Item) lefthikey, itemsz, leftoff,
|
||||
false, false) == InvalidOffsetNumber)
|
||||
{
|
||||
memset(rightpage, 0, BufferGetPageSize(rbuf));
|
||||
@@ -1969,6 +1989,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
|
||||
itemid = PageGetItemId(lpage, P_HIKEY);
|
||||
right_item_sz = ItemIdGetLength(itemid);
|
||||
item = (IndexTuple) PageGetItem(lpage, itemid);
|
||||
|
||||
right_item = CopyIndexTuple(item);
|
||||
ItemPointerSet(&(right_item->t_tid), rbkno, P_HIKEY);
|
||||
|
||||
@@ -2086,7 +2107,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
|
||||
* we insert the tuples in order, so that the given itup_off does
|
||||
* represent the final position of the tuple!
|
||||
*/
|
||||
static bool
|
||||
bool
|
||||
_bt_pgaddtup(Page page,
|
||||
Size itemsize,
|
||||
IndexTuple itup,
|
||||
|
||||
Reference in New Issue
Block a user