Consistently truncate non-key suffix columns.
authorPeter Geoghegan
Mon, 30 Mar 2020 19:03:57 +0000 (12:03 -0700)
committerPeter Geoghegan
Mon, 30 Mar 2020 19:03:57 +0000 (12:03 -0700)
INCLUDE indexes failed to have their non-key attributes physically
truncated away in certain rare cases.  This led to physically larger
pivot tuples that contained useless non-key attribute values.  The
impact on users should be negligible, but this is still clearly a
regression (Postgres 11 supports INCLUDE indexes, and yet was not
affected).

The bug appeared in commit dd299df8, which introduced "true" suffix
truncation of key attributes.

Discussion: https://postgr.es/m/CAH2-Wz=E8pkV9ivRSFHtv812H5ckf8s1-yhx61_WrJbKccGcrQ@mail.gmail.com
Backpatch: 12-, where "true" suffix truncation was introduced.

src/backend/access/nbtree/nbtutils.c

index 93fab264ae4d5c2dd208b87c17c2ca5796e702aa..a1e7636adb16cc182603023462169e5d22126a69 100644 (file)
@@ -2143,7 +2143,8 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright,
    {
        IndexTuple  tidpivot;
 
-       pivot = index_truncate_tuple(itupdesc, firstright, keepnatts);
+       pivot = index_truncate_tuple(itupdesc, firstright,
+                                    Min(keepnatts, nkeyatts));
 
        /*
         * If there is a distinguishing key attribute within new pivot tuple,
@@ -2173,6 +2174,10 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright,
        /*
         * No truncation was possible, since key attributes are all equal.
         * It's necessary to add a heap TID attribute to the new pivot tuple.
+        *
+        * This path is only taken when rel is not an INCLUDE index.  It
+        * avoids a second palloc0() by avoiding the index_truncate_tuple()
+        * call completely.
         */
        Assert(natts == nkeyatts);
        newsize = IndexTupleSize(firstright) + MAXALIGN(sizeof(ItemPointerData));