]> granicus.if.org Git - postgresql/commitdiff
Don't truncate away non-key attributes for leftmost downlinks.
authorTeodor Sigaev <teodor@sigaev.ru>
Fri, 4 May 2018 09:38:23 +0000 (12:38 +0300)
committerTeodor Sigaev <teodor@sigaev.ru>
Fri, 4 May 2018 09:38:23 +0000 (12:38 +0300)
nbtsort.c does not need to truncate away non-key attributes for the
minimum key of the leftmost page on a level, since this is only used to
build a minus infinity downlink for the level's leftmost page.
Truncating away non-key attributes in advance of truncating away all
attributes in _bt_sortaddtup() does not affect the correctness of CREATE
INDEX, but it is misleading.

Author: Peter Geoghegan
Discussion: https://www.postgresql.org/message-id/CAH2-WzkAS2M3ussHG-s_Av=Zo6dPjOxyu5fNRkYnxQV+YzGQ4w@mail.gmail.com

src/backend/access/nbtree/nbtsort.c

index 0587e42573131179f560e8484fd4ae3fe86120c0..e012df596ed61c9481dd90e71f1a4ae8e351f712 100644 (file)
@@ -934,7 +934,10 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
                        state->btps_next = _bt_pagestate(wstate, state->btps_level + 1);
 
                Assert(BTreeTupleGetNAtts(state->btps_minkey, wstate->index) ==
-                          IndexRelationGetNumberOfKeyAttributes(wstate->index));
+                          IndexRelationGetNumberOfKeyAttributes(wstate->index) ||
+                          P_LEFTMOST(opageop));
+               Assert(BTreeTupleGetNAtts(state->btps_minkey, wstate->index) == 0 ||
+                          !P_LEFTMOST(opageop));
                BTreeInnerTupleSetDownLink(state->btps_minkey, oblkno);
                _bt_buildadd(wstate, state->btps_next, state->btps_minkey);
                pfree(state->btps_minkey);
@@ -974,24 +977,16 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
         * If the new item is the first for its page, stash a copy for later. Note
         * this will only happen for the first item on a level; on later pages,
         * the first item for a page is copied from the prior page in the code
-        * above.
+        * above.  Since the minimum key for an entire level is only used as a
+        * minus infinity downlink, and never as a high key, there is no need to
+        * truncate away non-key attributes at this point.
         */
        if (last_off == P_HIKEY)
        {
-               BTPageOpaque npageop;
-
                Assert(state->btps_minkey == NULL);
-
-               npageop = (BTPageOpaque) PageGetSpecialPointer(npage);
-
-               /*
-                * Truncate included attributes of the tuple that we're going to
-                * insert into the parent page as a downlink
-                */
-               if (indnkeyatts != indnatts && P_ISLEAF(npageop))
-                       state->btps_minkey = _bt_nonkey_truncate(wstate->index, itup);
-               else
-                       state->btps_minkey = CopyIndexTuple(itup);
+               state->btps_minkey = CopyIndexTuple(itup);
+               /* _bt_sortaddtup() will perform full truncation later */
+               BTreeTupleSetNAtts(state->btps_minkey, 0);
        }
 
        /*
@@ -1044,7 +1039,10 @@ _bt_uppershutdown(BTWriteState *wstate, BTPageState *state)
                else
                {
                        Assert(BTreeTupleGetNAtts(s->btps_minkey, wstate->index) ==
-                                  IndexRelationGetNumberOfKeyAttributes(wstate->index));
+                                  IndexRelationGetNumberOfKeyAttributes(wstate->index) ||
+                                  P_LEFTMOST(opaque));
+                       Assert(BTreeTupleGetNAtts(s->btps_minkey, wstate->index) == 0 ||
+                                  !P_LEFTMOST(opaque));
                        BTreeInnerTupleSetDownLink(s->btps_minkey, blkno);
                        _bt_buildadd(wstate, s->btps_next, s->btps_minkey);
                        pfree(s->btps_minkey);