Remove unnecessary PageIsEmpty() nbtree build check.
authorPeter Geoghegan <pg@bowt.ie>
Mon, 6 Jul 2020 20:47:29 +0000 (13:47 -0700)
committerPeter Geoghegan <pg@bowt.ie>
Mon, 6 Jul 2020 20:47:29 +0000 (13:47 -0700)
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.

src/backend/access/nbtree/nbtsort.c

index c03998834d4a1915864824c9c1f9ebe314e55f72..e6b72111363e2be69de53f0cff3d7c21b925d3d6 100644 (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);
 }
 
 /*