Skip to content

Commit 42d1acd

Browse files
committed
Fix yet another crash in page split during GiST index creation.
Commit a7ee7c8 fixed a bug in GiST page split during index creation, where we failed to re-find the position of a downlink after the page containing it was split. However, that fix was incomplete; the other call to gistinserttuples() in the same function needs to also clear 'downlinkoffnum'. Fixes bug #16134 reported by Alexander Lakhin, for real this time. The previous fix was enough to fix the crash with the reproducer script for bug #16162, but the original script for #16134 was still crashing. Backpatch to v12, like the previous incomplete fix. Discussion: https://www.postgresql.org/message-id/d869f537-abe4-d2ea-0510-38cd053f5152%40gmail.com
1 parent e3ac893 commit 42d1acd

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

src/backend/access/gist/gist.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,28 +1338,27 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack,
13381338
}
13391339

13401340
LockBuffer(stack->parent->buffer, GIST_EXCLUSIVE);
1341-
gistFindCorrectParent(state->r, stack);
13421341

13431342
/*
1344-
* insert downlinks for the siblings from right to left, until there are
1343+
* Insert downlinks for the siblings from right to left, until there are
13451344
* only two siblings left.
13461345
*/
13471346
while (list_length(reversed) > 2)
13481347
{
13491348
right = (GISTPageSplitInfo *) linitial(reversed);
13501349
left = (GISTPageSplitInfo *) lsecond(reversed);
13511350

1351+
gistFindCorrectParent(state->r, stack);
13521352
if (gistinserttuples(state, stack->parent, giststate,
13531353
&right->downlink, 1,
13541354
InvalidOffsetNumber,
13551355
left->buf, right->buf, false, false))
13561356
{
13571357
/*
1358-
* If the parent page was split, need to relocate the original
1359-
* parent pointer.
1358+
* If the parent page was split, the existing downlink might
1359+
* have moved.
13601360
*/
13611361
stack->downlinkoffnum = InvalidOffsetNumber;
1362-
gistFindCorrectParent(state->r, stack);
13631362
}
13641363
/* gistinserttuples() released the lock on right->buf. */
13651364
reversed = list_delete_first(reversed);
@@ -1375,13 +1374,21 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack,
13751374
*/
13761375
tuples[0] = left->downlink;
13771376
tuples[1] = right->downlink;
1378-
gistinserttuples(state, stack->parent, giststate,
1379-
tuples, 2,
1380-
stack->downlinkoffnum,
1381-
left->buf, right->buf,
1382-
true, /* Unlock parent */
1383-
unlockbuf /* Unlock stack->buffer if caller wants that */
1384-
);
1377+
gistFindCorrectParent(state->r, stack);
1378+
if (gistinserttuples(state, stack->parent, giststate,
1379+
tuples, 2,
1380+
stack->downlinkoffnum,
1381+
left->buf, right->buf,
1382+
true, /* Unlock parent */
1383+
unlockbuf /* Unlock stack->buffer if caller wants that */
1384+
))
1385+
{
1386+
/*
1387+
* If the parent page was split, the downlink might have moved.
1388+
*/
1389+
stack->downlinkoffnum = InvalidOffsetNumber;
1390+
}
1391+
13851392
Assert(left->buf == stack->buffer);
13861393

13871394
/*

0 commit comments

Comments
 (0)