Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 716d506

Browse files
committed
Make sure the btree patch gets into 2.0 as well...
Still submitted by: Massimo Dal Zotto <dz@cs.unitn.it>
1 parent e18d49d commit 716d506

File tree

1 file changed

+50
-9
lines changed

1 file changed

+50
-9
lines changed

src/backend/access/nbtree/nbtinsert.c

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.3 1996/10/23 07:39:00 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.4 1996/10/25 09:55:36 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -815,7 +815,8 @@ _bt_itemcmp(Relation rel,
815815

816816
/*
817817
* _bt_updateitem() -- updates the key of the item identified by the
818-
* oid with the key of newItem (done in place)
818+
* oid with the key of newItem (done in place if
819+
* possible)
819820
*
820821
*/
821822
static void
@@ -829,14 +830,17 @@ _bt_updateitem(Relation rel,
829830
OffsetNumber maxoff;
830831
OffsetNumber i;
831832
ItemPointerData itemPtrData;
832-
BTItem item;
833+
BTItem item, itemCopy;
833834
IndexTuple oldIndexTuple, newIndexTuple;
835+
int newSize, oldSize, first;
834836

835837
page = BufferGetPage(buf);
836838
maxoff = PageGetMaxOffsetNumber(page);
837839

838840
/* locate item on the page */
839-
i = P_HIKEY;
841+
first = P_RIGHTMOST((BTPageOpaque) PageGetSpecialPointer(page)) \
842+
? P_HIKEY : P_FIRSTKEY;
843+
i = first;
840844
do {
841845
item = (BTItem) PageGetItem(page, PageGetItemId(page, i));
842846
i = OffsetNumberNext(i);
@@ -849,9 +853,46 @@ _bt_updateitem(Relation rel,
849853

850854
oldIndexTuple = &(item->bti_itup);
851855
newIndexTuple = &(newItem->bti_itup);
852-
853-
/* keep the original item pointer */
854-
ItemPointerCopy(&(oldIndexTuple->t_tid), &itemPtrData);
855-
CopyIndexTuple(newIndexTuple, &oldIndexTuple);
856-
ItemPointerCopy(&itemPtrData, &(oldIndexTuple->t_tid));
856+
oldSize = DOUBLEALIGN(IndexTupleSize(oldIndexTuple));
857+
newSize = DOUBLEALIGN(IndexTupleSize(newIndexTuple));
858+
#ifdef NBTINSERT_PATCH_DEBUG
859+
printf("_bt_updateitem: newSize=%d, oldSize=%d\n", newSize, oldSize);
860+
#endif
861+
862+
/*
863+
* If new and old item have the same size do the update in place
864+
* and return.
865+
*/
866+
if (oldSize == newSize) {
867+
/* keep the original item pointer */
868+
ItemPointerCopy(&(oldIndexTuple->t_tid), &itemPtrData);
869+
CopyIndexTuple(newIndexTuple, &oldIndexTuple);
870+
ItemPointerCopy(&itemPtrData, &(oldIndexTuple->t_tid));
871+
return;
872+
}
873+
874+
/*
875+
* If new and old items have different size the update in place
876+
* is not possible. In this case the old item is deleted and the
877+
* new one is inserted.
878+
* The new insertion should be done using _bt_insertonpg which
879+
* would also takes care of the page splitting if needed, but
880+
* unfortunately it doesn't work, so PageAddItem is used instead.
881+
* There is the possibility that there is not enough space in the
882+
* page and the item is not inserted.
883+
*/
884+
itemCopy = palloc(newSize);
885+
memmove((char *) itemCopy, (char *) newItem, newSize);
886+
itemCopy->bti_oid = item->bti_oid;
887+
newIndexTuple = &(itemCopy->bti_itup);
888+
ItemPointerCopy(&(oldIndexTuple->t_tid), &(newIndexTuple->t_tid));
889+
890+
/*
891+
* Get the offset number of the item then delete it and insert
892+
* the new item in the same place.
893+
*/
894+
i = OffsetNumberPrev(i);
895+
PageIndexTupleDelete(page, i);
896+
PageAddItem(page, (Item) itemCopy, newSize, i, LP_USED);
897+
pfree(itemCopy);
857898
}

0 commit comments

Comments
 (0)