aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/nbtree/nbtutils.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index aaa0c89c7dd..86cec248593 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -1725,6 +1725,7 @@ _bt_killitems(IndexScanDesc scan)
int i;
int numKilled = so->numKilled;
bool killedsomething = false;
+ bool droppedpin PG_USED_FOR_ASSERTS_ONLY;
Assert(BTScanPosIsValid(so->currPos));
@@ -1742,6 +1743,7 @@ _bt_killitems(IndexScanDesc scan)
* re-use of any TID on the page, so there is no need to check the
* LSN.
*/
+ droppedpin = false;
LockBuffer(so->currPos.buf, BT_READ);
page = BufferGetPage(so->currPos.buf);
@@ -1750,6 +1752,7 @@ _bt_killitems(IndexScanDesc scan)
{
Buffer buf;
+ droppedpin = true;
/* Attempt to re-read the buffer, getting pin and lock. */
buf = _bt_getbuf(scan->indexRelation, so->currPos.currPage, BT_READ);
@@ -1795,9 +1798,18 @@ _bt_killitems(IndexScanDesc scan)
int j;
/*
- * Note that we rely on the assumption that heap TIDs in the
- * scanpos items array are always in ascending heap TID order
- * within a posting list
+ * We rely on the convention that heap TIDs in the scanpos
+ * items array are stored in ascending heap TID order for a
+ * group of TIDs that originally came from a posting list
+ * tuple. This convention even applies during backwards
+ * scans, where returning the TIDs in descending order might
+ * seem more natural. This is about effectiveness, not
+ * correctness.
+ *
+ * Note that the page may have been modified in almost any way
+ * since we first read it (in the !droppedpin case), so it's
+ * possible that this posting list tuple wasn't a posting list
+ * tuple when we first encountered its heap TIDs.
*/
for (j = 0; j < nposting; j++)
{
@@ -1806,8 +1818,12 @@ _bt_killitems(IndexScanDesc scan)
if (!ItemPointerEquals(item, &kitem->heapTid))
break; /* out of posting list loop */
- /* kitem must have matching offnum when heap TIDs match */
- Assert(kitem->indexOffset == offnum);
+ /*
+ * kitem must have matching offnum when heap TIDs match,
+ * though only in the common case where the page can't
+ * have been concurrently modified
+ */
+ Assert(kitem->indexOffset == offnum || !droppedpin);
/*
* Read-ahead to later kitems here.