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 <pg@bowt.ie> Reviewed-By: Masahiro Ikeda <ikedamsh@oss.nttdata.com> 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

Lines changed: 34 additions & 32 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy