@@ -42,6 +42,7 @@ static int _bt_setuppostingitems(BTScanOpaque so, int itemIndex,
4242static 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 );
4546static bool _bt_steppage (IndexScanDesc scan , ScanDirection dir );
4647static 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