Add defensive "split_only_page" nbtree assertion.
authorPeter Geoghegan <pg@bowt.ie>
Tue, 14 Apr 2020 04:11:03 +0000 (21:11 -0700)
committerPeter Geoghegan <pg@bowt.ie>
Tue, 14 Apr 2020 04:11:03 +0000 (21:11 -0700)
Clearly it's not okay for nbtree to split a page that is the only page
on its level, and then find that it has to split the parent one level up
in turn.  There is simply no code to handle the split_only_page case in
the _bt_insertonpg() "newitem won't fit" branch (only the "newitem fits"
branch handles split_only_page).  Add a defensive assertion that will
fail if a split_only_page call to _bt_insertonpg() somehow ends up
splitting the target/parent page.

I (pgeoghegan) believe that we don't need split_only_page handling for
the "newitem won't fit" branch because anybody calling _bt_insertonpg()
like this would have to hold a lock on the same one and only child page.

src/backend/access/nbtree/nbtinsert.c

index 4fa2e85877a6a6b1a71069077f1c0d5b8df4b5b3..3a7f25df81323695c6f66a15aa55bc408c10528b 100644 (file)
@@ -1183,6 +1183,8 @@ _bt_insertonpg(Relation rel,
                bool            is_only = P_LEFTMOST(lpageop) && P_RIGHTMOST(lpageop);
                Buffer          rbuf;
 
+               Assert(!split_only_page);
+
                /* split the buffer into left and right halves */
                rbuf = _bt_split(rel, itup_key, buf, cbuf, newitemoff, itemsz, itup,
                                                 origitup, nposting, postingoff);