Skip to content

Commit 4e6e375

Browse files
Add nbtree amgettuple return item function.
This makes it easier to add precondition assertions. We now assert that the last call to _bt_readpage succeeded, and that the current item index is within the bounds of the currPos items array. Author: Peter Geoghegan <[email protected]> Reviewed-By: Masahiro Ikeda <[email protected]> Discussion: https://postgr.es/m/CAH2-WznFkEs9K1PtNruti5JjawY-dwj+gkaEh_k1ZE+1xLLGkA@mail.gmail.com
1 parent 38c1871 commit 4e6e375

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

src/backend/access/nbtree/nbtsearch.c

+34-32
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static int _bt_setuppostingitems(BTScanOpaque so, int itemIndex,
4242
static inline void _bt_savepostingitem(BTScanOpaque so, int itemIndex,
4343
OffsetNumber offnum,
4444
ItemPointer heapTid, int tupleOffset);
45+
static inline void _bt_returnitem(IndexScanDesc scan, BTScanOpaque so);
4546
static bool _bt_steppage(IndexScanDesc scan, ScanDirection dir);
4647
static bool _bt_readfirstpage(IndexScanDesc scan, OffsetNumber offnum,
4748
ScanDirection dir);
@@ -867,8 +868,7 @@ _bt_compare(Relation rel,
867868
* matching tuple(s) on the page has been loaded into so->currPos. We'll
868869
* drop all locks and hold onto a pin on page's buffer, except when
869870
* _bt_drop_lock_and_maybe_pin dropped the pin to avoid blocking VACUUM.
870-
* scan->xs_heaptid is set to the heap TID of the current tuple, and if
871-
* requested, scan->xs_itup points to a copy of the index tuple.
871+
* _bt_returnitem sets the next item to return to scan on success exit.
872872
*
873873
* If there are no matching items in the index, we return false, with no
874874
* pins or locks held. so->currPos will remain invalid.
@@ -890,7 +890,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
890890
ScanKeyData notnullkeys[INDEX_MAX_KEYS];
891891
int keysz = 0;
892892
StrategyNumber strat_total;
893-
BTScanPosItem *currItem;
894893

895894
Assert(!BTScanPosIsValid(so->currPos));
896895

@@ -950,7 +949,9 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
950949
*/
951950
if (!_bt_readnextpage(scan, blkno, lastcurrblkno, dir, true))
952951
return false;
953-
goto readcomplete;
952+
953+
_bt_returnitem(scan, so);
954+
return true;
954955
}
955956
}
956957
else if (so->numArrayKeys && !so->needPrimScan)
@@ -1438,14 +1439,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
14381439
if (!_bt_readfirstpage(scan, offnum, dir))
14391440
return false;
14401441

1441-
readcomplete:
1442-
/* OK, itemIndex says what to return */
1443-
Assert(BTScanPosIsValid(so->currPos));
1444-
currItem = &so->currPos.items[so->currPos.itemIndex];
1445-
scan->xs_heaptid = currItem->heapTid;
1446-
if (scan->xs_want_itup)
1447-
scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset);
1448-
1442+
_bt_returnitem(scan, so);
14491443
return true;
14501444
}
14511445

@@ -1456,9 +1450,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
14561450
* but is not locked, and so->currPos.itemIndex identifies which item was
14571451
* previously returned.
14581452
*
1459-
* On successful exit, scan->xs_heaptid is set to the TID of the next
1460-
* heap tuple, and if requested, scan->xs_itup points to a copy of the
1461-
* index tuple. so->currPos is updated as needed.
1453+
* On success exit, so->currPos is updated as needed, and _bt_returnitem
1454+
* sets the next item to return to the scan. so->currPos remains valid.
14621455
*
14631456
* On failure exit (no more tuples), we invalidate so->currPos. It'll
14641457
* still be possible for the scan to return tuples by changing direction,
@@ -1468,7 +1461,6 @@ bool
14681461
_bt_next(IndexScanDesc scan, ScanDirection dir)
14691462
{
14701463
BTScanOpaque so = (BTScanOpaque) scan->opaque;
1471-
BTScanPosItem *currItem;
14721464

14731465
Assert(BTScanPosIsValid(so->currPos));
14741466

@@ -1493,13 +1485,7 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
14931485
}
14941486
}
14951487

1496-
/* OK, itemIndex says what to return */
1497-
Assert(BTScanPosIsValid(so->currPos));
1498-
currItem = &so->currPos.items[so->currPos.itemIndex];
1499-
scan->xs_heaptid = currItem->heapTid;
1500-
if (scan->xs_want_itup)
1501-
scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset);
1502-
1488+
_bt_returnitem(scan, so);
15031489
return true;
15041490
}
15051491

@@ -1560,10 +1546,13 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
15601546
so->currPos.currPage);
15611547
}
15621548

1563-
/* initialize remaining currPos fields (before moreLeft/moreRight) */
1549+
/* initialize remaining currPos fields related to current page */
15641550
so->currPos.lsn = BufferGetLSNAtomic(so->currPos.buf);
15651551
so->currPos.dir = dir;
15661552
so->currPos.nextTupleOffset = 0;
1553+
/* either moreLeft or moreRight should be set now (may be unset later) */
1554+
Assert(ScanDirectionIsForward(dir) ? so->currPos.moreRight :
1555+
so->currPos.moreLeft);
15671556

15681557
PredicateLockPage(rel, so->currPos.currPage, scan->xs_snapshot);
15691558

@@ -2002,6 +1991,26 @@ _bt_savepostingitem(BTScanOpaque so, int itemIndex, OffsetNumber offnum,
20021991
currItem->tupleOffset = tupleOffset;
20031992
}
20041993

1994+
/*
1995+
* Return the index item from so->currPos.items[so->currPos.itemIndex] to the
1996+
* index scan by setting the relevant fields in caller's index scan descriptor
1997+
*/
1998+
static inline void
1999+
_bt_returnitem(IndexScanDesc scan, BTScanOpaque so)
2000+
{
2001+
BTScanPosItem *currItem = &so->currPos.items[so->currPos.itemIndex];
2002+
2003+
/* Most recent _bt_readpage must have succeeded */
2004+
Assert(BTScanPosIsValid(so->currPos));
2005+
Assert(so->currPos.itemIndex >= so->currPos.firstItem);
2006+
Assert(so->currPos.itemIndex <= so->currPos.lastItem);
2007+
2008+
/* Return next item, per amgettuple contract */
2009+
scan->xs_heaptid = currItem->heapTid;
2010+
if (so->currTuples)
2011+
scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset);
2012+
}
2013+
20052014
/*
20062015
* _bt_steppage() -- Step to next page containing valid data for scan
20072016
*
@@ -2543,7 +2552,6 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
25432552
Page page;
25442553
BTPageOpaque opaque;
25452554
OffsetNumber start;
2546-
BTScanPosItem *currItem;
25472555

25482556
Assert(!BTScanPosIsValid(so->currPos));
25492557

@@ -2593,12 +2601,6 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
25932601
if (!_bt_readfirstpage(scan, start, dir))
25942602
return false;
25952603

2596-
/* OK, itemIndex says what to return */
2597-
Assert(BTScanPosIsValid(so->currPos));
2598-
currItem = &so->currPos.items[so->currPos.itemIndex];
2599-
scan->xs_heaptid = currItem->heapTid;
2600-
if (scan->xs_want_itup)
2601-
scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset);
2602-
2604+
_bt_returnitem(scan, so);
26032605
return true;
26042606
}

0 commit comments

Comments
 (0)