Remove unnecessary PageIsEmpty() nbtree build check.

nbtree index builds cannot write out an empty page.  That would mean
that there was no way to create a pivot tuple pointing to the page one
level up, since _bt_truncate() generates one based on page's firstright
tuple.

Replace the unnecessary PageIsEmpty() check with an assertion that
checks that the page has space for at least two line pointers (the
would-be high key line pointer, plus at least one valid "data item"
tuple line pointer).

The PageIsEmpty() check was added by commit 5d9f146c over 20 years ago.
It looks like it has always been unnecessary.
This commit is contained in:
Peter Geoghegan 2020-07-06 13:47:29 -07:00
parent f7f70d5e22
commit 28c16f4947
1 changed files with 18 additions and 17 deletions

View File

@ -267,7 +267,7 @@ static void _bt_build_callback(Relation index, ItemPointer tid, Datum *values,
bool *isnull, bool tupleIsAlive, void *state);
static Page _bt_blnewpage(uint32 level);
static BTPageState *_bt_pagestate(BTWriteState *wstate, uint32 level);
static void _bt_slideleft(Page page);
static void _bt_slideleft(Page rightmostpage);
static void _bt_sortaddtup(Page page, Size itemsize,
IndexTuple itup, OffsetNumber itup_off,
bool newfirstdataitem);
@ -721,31 +721,32 @@ _bt_pagestate(BTWriteState *wstate, uint32 level)
}
/*
* slide an array of ItemIds back one slot (from P_FIRSTKEY to
* P_HIKEY, overwriting P_HIKEY). we need to do this when we discover
* that we have built an ItemId array in what has turned out to be a
* P_RIGHTMOST page.
* Slide the array of ItemIds from the page back one slot (from P_FIRSTKEY to
* P_HIKEY, overwriting P_HIKEY).
*
* _bt_blnewpage() makes the P_HIKEY line pointer appear allocated, but the
* rightmost page on its level is not supposed to get a high key. Now that
* it's clear that this page is a rightmost page, remove the unneeded empty
* P_HIKEY line pointer space.
*/
static void
_bt_slideleft(Page page)
_bt_slideleft(Page rightmostpage)
{
OffsetNumber off;
OffsetNumber maxoff;
ItemId previi;
ItemId thisii;
if (!PageIsEmpty(page))
maxoff = PageGetMaxOffsetNumber(rightmostpage);
Assert(maxoff >= P_FIRSTKEY);
previi = PageGetItemId(rightmostpage, P_HIKEY);
for (off = P_FIRSTKEY; off <= maxoff; off = OffsetNumberNext(off))
{
maxoff = PageGetMaxOffsetNumber(page);
previi = PageGetItemId(page, P_HIKEY);
for (off = P_FIRSTKEY; off <= maxoff; off = OffsetNumberNext(off))
{
thisii = PageGetItemId(page, off);
*previi = *thisii;
previi = thisii;
}
((PageHeader) page)->pd_lower -= sizeof(ItemIdData);
ItemId thisii = PageGetItemId(rightmostpage, off);
*previi = *thisii;
previi = thisii;
}
((PageHeader) rightmostpage)->pd_lower -= sizeof(ItemIdData);
}
/*