* pages are released; note that new tuple(s) are *not* on the root page
* but in one of the new child pages.
*
+ * If 'newblkno' is not NULL, returns the block number of page the first
+ * new/updated tuple was inserted to. Usually it's the given page, but could
+ * be its right sibling if the page was split.
+ *
* Returns 'true' if the page was split, 'false' otherwise.
*/
bool
gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
Buffer buffer,
IndexTuple *itup, int ntup, OffsetNumber oldoffnum,
+ BlockNumber *newblkno,
Buffer leftchildbuf,
List **splitinfo,
bool markfollowright)
{
+ BlockNumber blkno = BufferGetBlockNumber(buffer);
Page page = BufferGetPage(buffer);
bool is_leaf = (GistPageIsLeaf(page)) ? true : false;
XLogRecPtr recptr;
BlockNumber oldrlink = InvalidBlockNumber;
GistNSN oldnsn = {0, 0};
SplitedPageLayout rootpg;
- BlockNumber blkno = BufferGetBlockNumber(buffer);
bool is_rootsplit;
is_rootsplit = (blkno == GIST_ROOT_BLKNO);
for (i = 0; i < ptr->block.num; i++)
{
- if (PageAddItem(ptr->page, (Item) data, IndexTupleSize((IndexTuple) data), i + FirstOffsetNumber, false, false) == InvalidOffsetNumber)
+ IndexTuple thistup = (IndexTuple) data;
+
+ if (PageAddItem(ptr->page, (Item) data, IndexTupleSize(thistup), i + FirstOffsetNumber, false, false) == InvalidOffsetNumber)
elog(ERROR, "failed to add item to index page in \"%s\"", RelationGetRelationName(rel));
- data += IndexTupleSize((IndexTuple) data);
+
+ /*
+ * If this is the first inserted/updated tuple, let the caller
+ * know which page it landed on.
+ */
+ if (newblkno && ItemPointerEquals(&thistup->t_tid, &(*itup)->t_tid))
+ *newblkno = ptr->block.blkno;
+
+ data += IndexTupleSize(thistup);
}
/* Set up rightlinks */
recptr = GetXLogRecPtrForTemp();
PageSetLSN(page, recptr);
}
+
+ if (newblkno)
+ *newblkno = blkno;
}
/*
* is kept pinned.
* - Lock and pin on 'rightchild' are always released.
*
- * Returns 'true' if the page had to be split. Note that if the page had
- * be split, the inserted/updated might've been inserted to a right sibling
- * of stack->buffer instead of stack->buffer itself.
+ * Returns 'true' if the page had to be split. Note that if the page was
+ * split, the inserted/updated tuples might've been inserted to a right
+ * sibling of stack->buffer instead of stack->buffer itself.
*/
static bool
gistinserttuples(GISTInsertState *state, GISTInsertStack *stack,
/* Insert the tuple(s) to the page, splitting the page if necessary */
is_split = gistplacetopage(state->r, state->freespace, giststate,
stack->buffer,
- tuples, ntup, oldoffnum,
+ tuples, ntup,
+ oldoffnum, NULL,
leftchild,
&splitinfo,
true);
IndexTuple itup);
static bool gistProcessItup(GISTBuildState *buildstate, IndexTuple itup,
BlockNumber startblkno, int startlevel);
-static void gistbufferinginserttuples(GISTBuildState *buildstate,
+static BlockNumber gistbufferinginserttuples(GISTBuildState *buildstate,
Buffer buffer, int level,
IndexTuple *itup, int ntup, OffsetNumber oldoffnum,
BlockNumber parentblk, OffsetNumber downlinkoffnum);
newtup = gistgetadjusted(indexrel, idxtuple, itup, giststate);
if (newtup)
{
- gistbufferinginserttuples(buildstate, buffer, level,
- &newtup, 1, childoffnum,
- InvalidBlockNumber, InvalidOffsetNumber);
+ blkno = gistbufferinginserttuples(buildstate, buffer, level,
+ &newtup, 1, childoffnum,
+ InvalidBlockNumber, InvalidOffsetNumber);
/* gistbufferinginserttuples() released the buffer */
}
else
*
* This is analogous with gistinserttuples() in the regular insertion code.
*
+ * Returns the block number of the page where the (first) new or updated tuple
+ * was inserted. Usually that's the original page, but might be a sibling page
+ * if the original page was split.
+ *
* Caller should hold a lock on 'buffer' on entry. This function will unlock
* and unpin it.
*/
-static void
+static BlockNumber
gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level,
IndexTuple *itup, int ntup, OffsetNumber oldoffnum,
BlockNumber parentblk, OffsetNumber downlinkoffnum)
GISTBuildBuffers *gfbb = buildstate->gfbb;
List *splitinfo;
bool is_split;
+ BlockNumber placed_to_blk = InvalidBlockNumber;
is_split = gistplacetopage(buildstate->indexrel,
buildstate->freespace,
buildstate->giststate,
buffer,
- itup, ntup, oldoffnum,
+ itup, ntup, oldoffnum, &placed_to_blk,
InvalidBuffer,
&splitinfo,
false);
}
else
UnlockReleaseBuffer(buffer);
+
+ return placed_to_blk;
}
/*