*** a/src/backend/access/gist/gist.c --- b/src/backend/access/gist/gist.c *************** *** 625,630 **** gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) --- 625,631 ---- firststack.blkno = GIST_ROOT_BLKNO; firststack.lsn.xrecoff = 0; firststack.parent = NULL; + firststack.childoffnum = InvalidOffsetNumber; state.stack = stack = &firststack; /* *************** *** 701,709 **** gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) BlockNumber childblkno; IndexTuple newtup; GISTInsertStack *item; ! stack->childoffnum = gistchoose(state.r, stack->page, itup, giststate); ! iid = PageGetItemId(stack->page, stack->childoffnum); idxtuple = (IndexTuple) PageGetItem(stack->page, iid); childblkno = ItemPointerGetBlockNumber(&(idxtuple->t_tid)); --- 702,711 ---- BlockNumber childblkno; IndexTuple newtup; GISTInsertStack *item; + OffsetNumber childoffnum; ! childoffnum = gistchoose(state.r, stack->page, itup, giststate); ! iid = PageGetItemId(stack->page, childoffnum); idxtuple = (IndexTuple) PageGetItem(stack->page, iid); childblkno = ItemPointerGetBlockNumber(&(idxtuple->t_tid)); *************** *** 753,759 **** gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) * tuple. */ if (gistinserttuples(&state, stack, giststate, &newtup, 1, ! stack->childoffnum, InvalidBuffer)) { /* * If this was a root split, the root page continues to be --- 755,761 ---- * tuple. */ if (gistinserttuples(&state, stack, giststate, &newtup, 1, ! childoffnum, InvalidBuffer)) { /* * If this was a root split, the root page continues to be *************** *** 777,782 **** gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) --- 779,785 ---- item = (GISTInsertStack *) palloc0(sizeof(GISTInsertStack)); item->blkno = childblkno; item->parent = stack; + item->childoffnum = childoffnum; state.stack = stack = item; } else *************** *** 873,878 **** gistFindPath(Relation r, BlockNumber child) --- 876,882 ---- top = tail = (GISTInsertStack *) palloc0(sizeof(GISTInsertStack)); top->blkno = GIST_ROOT_BLKNO; + top->childoffnum = InvalidOffsetNumber; while (top && top->blkno != child) { *************** *** 919,947 **** gistFindPath(Relation r, BlockNumber child) blkno = ItemPointerGetBlockNumber(&(idxtuple->t_tid)); if (blkno == child) { - OffsetNumber poff = InvalidOffsetNumber; - - /* make childs links */ - ptr = top; - while (ptr->parent) - { - /* move childoffnum.. */ - if (ptr == top) - { - /* first iteration */ - poff = ptr->parent->childoffnum; - ptr->parent->childoffnum = ptr->childoffnum; - } - else - { - OffsetNumber tmp = ptr->parent->childoffnum; - - ptr->parent->childoffnum = poff; - poff = tmp; - } - ptr = ptr->parent; - } - top->childoffnum = i; UnlockReleaseBuffer(buffer); return top; } --- 923,928 ---- *************** *** 980,986 **** gistFindCorrectParent(Relation r, GISTInsertStack *child) parent->page = (Page) BufferGetPage(parent->buffer); /* here we don't need to distinguish between split and page update */ ! if (parent->childoffnum == InvalidOffsetNumber || !XLByteEQ(parent->lsn, PageGetLSN(parent->page))) { /* parent is changed, look child in right links until found */ OffsetNumber i, --- 961,967 ---- parent->page = (Page) BufferGetPage(parent->buffer); /* here we don't need to distinguish between split and page update */ ! if (child->childoffnum == InvalidOffsetNumber || !XLByteEQ(parent->lsn, PageGetLSN(parent->page))) { /* parent is changed, look child in right links until found */ OffsetNumber i, *************** *** 999,1005 **** gistFindCorrectParent(Relation r, GISTInsertStack *child) if (ItemPointerGetBlockNumber(&(idxtuple->t_tid)) == child->blkno) { /* yes!!, found */ ! parent->childoffnum = i; return; } } --- 980,986 ---- if (ItemPointerGetBlockNumber(&(idxtuple->t_tid)) == child->blkno) { /* yes!!, found */ ! child->childoffnum = i; return; } } *************** *** 1103,1109 **** gistformdownlink(Relation rel, Buffer buf, GISTSTATE *giststate, LockBuffer(stack->parent->buffer, GIST_EXCLUSIVE); gistFindCorrectParent(rel, stack); ! iid = PageGetItemId(stack->parent->page, stack->parent->childoffnum); downlink = (IndexTuple) PageGetItem(stack->parent->page, iid); downlink = CopyIndexTuple(downlink); LockBuffer(stack->parent->buffer, GIST_UNLOCK); --- 1084,1090 ---- LockBuffer(stack->parent->buffer, GIST_EXCLUSIVE); gistFindCorrectParent(rel, stack); ! iid = PageGetItemId(stack->parent->page, stack->childoffnum); downlink = (IndexTuple) PageGetItem(stack->parent->page, iid); downlink = CopyIndexTuple(downlink); LockBuffer(stack->parent->buffer, GIST_UNLOCK); *************** *** 1131,1137 **** gistfixsplit(GISTInsertState *state, GISTSTATE *giststate) RelationGetRelationName(state->r), stack->blkno); Assert(GistFollowRight(stack->page)); ! Assert(OffsetNumberIsValid(stack->parent->childoffnum)); buf = stack->buffer; --- 1112,1118 ---- RelationGetRelationName(state->r), stack->blkno); Assert(GistFollowRight(stack->page)); ! Assert(OffsetNumberIsValid(stack->childoffnum)); buf = stack->buffer; *************** *** 1268,1274 **** gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, tuples[1] = right->downlink; gistinserttuples(state, stack->parent, giststate, tuples, 2, ! stack->parent->childoffnum, left->buf); LockBuffer(stack->parent->buffer, GIST_UNLOCK); UnlockReleaseBuffer(right->buf); --- 1249,1255 ---- tuples[1] = right->downlink; gistinserttuples(state, stack->parent, giststate, tuples, 2, ! stack->childoffnum, left->buf); LockBuffer(stack->parent->buffer, GIST_UNLOCK); UnlockReleaseBuffer(right->buf);