]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
nbtree: Demote minus infinity "can't happen" error.
authorPeter Geoghegan <pg@bowt.ie>
Tue, 10 Mar 2020 21:15:41 +0000 (14:15 -0700)
committerPeter Geoghegan <pg@bowt.ie>
Tue, 10 Mar 2020 21:15:41 +0000 (14:15 -0700)
Only a very basic logic bug in a _bt_insertonpg() caller could lead to a
violation of this invariant.  Besides, any newitemoff used for an
internal page is sanitized using other "can't happen" errors in
_bt_getstackbuf() or its callers, before _bt_insertonpg() even gets
called.

Also, move the error/assertion from the insert-without-split path of
_bt_insertonpg() to the top of the same function.  There is no reason
why this invariant only applies to insertions that happen to not result
in a page split; cover every insertion.  The assertion naturally belongs
next to the existing generic assertions that document relatively
high-level invariants for the item being inserted.

src/backend/access/nbtree/nbtinsert.c

index 03b7e45293a3e5959de7322f2df591a0efea9adc..fb814ef722bcdb203cf62616f015daf0348388d1 100644 (file)
@@ -1082,6 +1082,14 @@ _bt_insertonpg(Relation rel,
                   IndexRelationGetNumberOfKeyAttributes(rel));
        Assert(!BTreeTupleIsPosting(itup));
 
+       /*
+        * Every internal page should have exactly one negative infinity item at
+        * all times.  Only _bt_split() and _bt_newroot() should add items that
+        * become negative infinity items through truncation, since they're the
+        * only routines that allocate new internal pages.
+        */
+       Assert(P_ISLEAF(lpageop) || newitemoff > P_FIRSTDATAKEY(lpageop));
+
        /* The caller should've finished any incomplete splits already. */
        if (P_INCOMPLETE_SPLIT(lpageop))
                elog(ERROR, "cannot insert to incompletely split page %u",
@@ -1212,18 +1220,6 @@ _bt_insertonpg(Relation rel,
                        }
                }
 
-               /*
-                * Every internal page should have exactly one negative infinity item
-                * at all times.  Only _bt_split() and _bt_newroot() should add items
-                * that become negative infinity items through truncation, since
-                * they're the only routines that allocate new internal pages.  Do not
-                * allow a retail insertion of a new item at the negative infinity
-                * offset.
-                */
-               if (!P_ISLEAF(lpageop) && newitemoff == P_FIRSTDATAKEY(lpageop))
-                       elog(ERROR, "cannot insert second negative infinity item in block %u of index \"%s\"",
-                                itup_blkno, RelationGetRelationName(rel));
-
                /* Do the update.  No ereport(ERROR) until changes are logged */
                START_CRIT_SECTION();