mirror of
https://github.com/postgres/postgres.git
synced 2025-07-21 16:02:15 +03:00
Make sure the btree patch gets into 2.0 as well...
Still submitted by: Massimo Dal Zotto <dz@cs.unitn.it>
This commit is contained in:
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.3 1996/10/23 07:39:00 scrappy Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.4 1996/10/25 09:55:36 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -815,7 +815,8 @@ _bt_itemcmp(Relation rel,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* _bt_updateitem() -- updates the key of the item identified by the
|
* _bt_updateitem() -- updates the key of the item identified by the
|
||||||
* oid with the key of newItem (done in place)
|
* oid with the key of newItem (done in place if
|
||||||
|
* possible)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -829,14 +830,17 @@ _bt_updateitem(Relation rel,
|
|||||||
OffsetNumber maxoff;
|
OffsetNumber maxoff;
|
||||||
OffsetNumber i;
|
OffsetNumber i;
|
||||||
ItemPointerData itemPtrData;
|
ItemPointerData itemPtrData;
|
||||||
BTItem item;
|
BTItem item, itemCopy;
|
||||||
IndexTuple oldIndexTuple, newIndexTuple;
|
IndexTuple oldIndexTuple, newIndexTuple;
|
||||||
|
int newSize, oldSize, first;
|
||||||
|
|
||||||
page = BufferGetPage(buf);
|
page = BufferGetPage(buf);
|
||||||
maxoff = PageGetMaxOffsetNumber(page);
|
maxoff = PageGetMaxOffsetNumber(page);
|
||||||
|
|
||||||
/* locate item on the page */
|
/* locate item on the page */
|
||||||
i = P_HIKEY;
|
first = P_RIGHTMOST((BTPageOpaque) PageGetSpecialPointer(page)) \
|
||||||
|
? P_HIKEY : P_FIRSTKEY;
|
||||||
|
i = first;
|
||||||
do {
|
do {
|
||||||
item = (BTItem) PageGetItem(page, PageGetItemId(page, i));
|
item = (BTItem) PageGetItem(page, PageGetItemId(page, i));
|
||||||
i = OffsetNumberNext(i);
|
i = OffsetNumberNext(i);
|
||||||
@ -849,9 +853,46 @@ _bt_updateitem(Relation rel,
|
|||||||
|
|
||||||
oldIndexTuple = &(item->bti_itup);
|
oldIndexTuple = &(item->bti_itup);
|
||||||
newIndexTuple = &(newItem->bti_itup);
|
newIndexTuple = &(newItem->bti_itup);
|
||||||
|
oldSize = DOUBLEALIGN(IndexTupleSize(oldIndexTuple));
|
||||||
/* keep the original item pointer */
|
newSize = DOUBLEALIGN(IndexTupleSize(newIndexTuple));
|
||||||
ItemPointerCopy(&(oldIndexTuple->t_tid), &itemPtrData);
|
#ifdef NBTINSERT_PATCH_DEBUG
|
||||||
CopyIndexTuple(newIndexTuple, &oldIndexTuple);
|
printf("_bt_updateitem: newSize=%d, oldSize=%d\n", newSize, oldSize);
|
||||||
ItemPointerCopy(&itemPtrData, &(oldIndexTuple->t_tid));
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If new and old item have the same size do the update in place
|
||||||
|
* and return.
|
||||||
|
*/
|
||||||
|
if (oldSize == newSize) {
|
||||||
|
/* keep the original item pointer */
|
||||||
|
ItemPointerCopy(&(oldIndexTuple->t_tid), &itemPtrData);
|
||||||
|
CopyIndexTuple(newIndexTuple, &oldIndexTuple);
|
||||||
|
ItemPointerCopy(&itemPtrData, &(oldIndexTuple->t_tid));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If new and old items have different size the update in place
|
||||||
|
* is not possible. In this case the old item is deleted and the
|
||||||
|
* new one is inserted.
|
||||||
|
* The new insertion should be done using _bt_insertonpg which
|
||||||
|
* would also takes care of the page splitting if needed, but
|
||||||
|
* unfortunately it doesn't work, so PageAddItem is used instead.
|
||||||
|
* There is the possibility that there is not enough space in the
|
||||||
|
* page and the item is not inserted.
|
||||||
|
*/
|
||||||
|
itemCopy = palloc(newSize);
|
||||||
|
memmove((char *) itemCopy, (char *) newItem, newSize);
|
||||||
|
itemCopy->bti_oid = item->bti_oid;
|
||||||
|
newIndexTuple = &(itemCopy->bti_itup);
|
||||||
|
ItemPointerCopy(&(oldIndexTuple->t_tid), &(newIndexTuple->t_tid));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the offset number of the item then delete it and insert
|
||||||
|
* the new item in the same place.
|
||||||
|
*/
|
||||||
|
i = OffsetNumberPrev(i);
|
||||||
|
PageIndexTupleDelete(page, i);
|
||||||
|
PageAddItem(page, (Item) itemCopy, newSize, i, LP_USED);
|
||||||
|
pfree(itemCopy);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user