1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-13 14:22:43 +03:00

Clarify why _bt_killitems sorts its items array.

Make it clear why _bt_killitems sorts the scan's so->killedItems[]
array.  Also add an assertion to the _bt_killitems loop (that iterates
through this array) to verify it accesses tuples in leaf page order.

Follow-up to commit bfb335df58.

Author: Peter Geoghegan <pg@bowt.ie>
Suggested-by: Victor Yegorov <vyegorov@gmail.com>
Discussion: https://postgr.es/m/CAGnEboirgArezZDNeFrR8FOGvKF-Xok333s2iVwWi65gZf8MEA@mail.gmail.com
This commit is contained in:
Peter Geoghegan
2025-12-10 20:50:47 -05:00
parent 06761b6096
commit e16c6f0247

View File

@@ -222,11 +222,12 @@ _bt_killitems(IndexScanDesc scan)
so->numKilled = 0; so->numKilled = 0;
/* /*
* so->killedItems[] is in whatever order the scan returned items in. * We need to iterate through so->killedItems[] in leaf page order; the
* Items will appear in descending order during backwards scans. And * loop below expects this (when marking posting list tuples, at least).
* scrollable cursor scans might have duplicate items. * so->killedItems[] is now in whatever order the scan returned items in.
* Scrollable cursor scans might have even saved the same item/TID twice.
* *
* Sort and uniqueify so->killedItems[] to deal with all this. * Sort and unique-ify so->killedItems[] to deal with all this.
*/ */
if (numKilled > 1) if (numKilled > 1)
{ {
@@ -271,6 +272,7 @@ _bt_killitems(IndexScanDesc scan)
minoff = P_FIRSTDATAKEY(opaque); minoff = P_FIRSTDATAKEY(opaque);
maxoff = PageGetMaxOffsetNumber(page); maxoff = PageGetMaxOffsetNumber(page);
/* Iterate through so->killedItems[] in leaf page order */
for (int i = 0; i < numKilled; i++) for (int i = 0; i < numKilled; i++)
{ {
int itemIndex = so->killedItems[i]; int itemIndex = so->killedItems[i];
@@ -279,6 +281,9 @@ _bt_killitems(IndexScanDesc scan)
Assert(itemIndex >= so->currPos.firstItem && Assert(itemIndex >= so->currPos.firstItem &&
itemIndex <= so->currPos.lastItem); itemIndex <= so->currPos.lastItem);
Assert(i == 0 ||
offnum >= so->currPos.items[so->killedItems[i - 1]].indexOffset);
if (offnum < minoff) if (offnum < minoff)
continue; /* pure paranoia */ continue; /* pure paranoia */
while (offnum <= maxoff) while (offnum <= maxoff)