@@ -42,6 +42,7 @@ static int _bt_setuppostingitems(BTScanOpaque so, int itemIndex,
42
42
static inline void _bt_savepostingitem (BTScanOpaque so , int itemIndex ,
43
43
OffsetNumber offnum ,
44
44
ItemPointer heapTid , int tupleOffset );
45
+ static inline void _bt_returnitem (IndexScanDesc scan , BTScanOpaque so );
45
46
static bool _bt_steppage (IndexScanDesc scan , ScanDirection dir );
46
47
static bool _bt_readfirstpage (IndexScanDesc scan , OffsetNumber offnum ,
47
48
ScanDirection dir );
@@ -867,8 +868,7 @@ _bt_compare(Relation rel,
867
868
* matching tuple(s) on the page has been loaded into so->currPos. We'll
868
869
* drop all locks and hold onto a pin on page's buffer, except when
869
870
* _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.
872
872
*
873
873
* If there are no matching items in the index, we return false, with no
874
874
* pins or locks held. so->currPos will remain invalid.
@@ -890,7 +890,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
890
890
ScanKeyData notnullkeys [INDEX_MAX_KEYS ];
891
891
int keysz = 0 ;
892
892
StrategyNumber strat_total ;
893
- BTScanPosItem * currItem ;
894
893
895
894
Assert (!BTScanPosIsValid (so -> currPos ));
896
895
@@ -950,7 +949,9 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
950
949
*/
951
950
if (!_bt_readnextpage (scan , blkno , lastcurrblkno , dir , true))
952
951
return false;
953
- goto readcomplete ;
952
+
953
+ _bt_returnitem (scan , so );
954
+ return true;
954
955
}
955
956
}
956
957
else if (so -> numArrayKeys && !so -> needPrimScan )
@@ -1438,14 +1439,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
1438
1439
if (!_bt_readfirstpage (scan , offnum , dir ))
1439
1440
return false;
1440
1441
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 );
1449
1443
return true;
1450
1444
}
1451
1445
@@ -1456,9 +1450,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
1456
1450
* but is not locked, and so->currPos.itemIndex identifies which item was
1457
1451
* previously returned.
1458
1452
*
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.
1462
1455
*
1463
1456
* On failure exit (no more tuples), we invalidate so->currPos. It'll
1464
1457
* still be possible for the scan to return tuples by changing direction,
@@ -1468,7 +1461,6 @@ bool
1468
1461
_bt_next (IndexScanDesc scan , ScanDirection dir )
1469
1462
{
1470
1463
BTScanOpaque so = (BTScanOpaque ) scan -> opaque ;
1471
- BTScanPosItem * currItem ;
1472
1464
1473
1465
Assert (BTScanPosIsValid (so -> currPos ));
1474
1466
@@ -1493,13 +1485,7 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
1493
1485
}
1494
1486
}
1495
1487
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 );
1503
1489
return true;
1504
1490
}
1505
1491
@@ -1560,10 +1546,13 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
1560
1546
so -> currPos .currPage );
1561
1547
}
1562
1548
1563
- /* initialize remaining currPos fields (before moreLeft/moreRight) */
1549
+ /* initialize remaining currPos fields related to current page */
1564
1550
so -> currPos .lsn = BufferGetLSNAtomic (so -> currPos .buf );
1565
1551
so -> currPos .dir = dir ;
1566
1552
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 );
1567
1556
1568
1557
PredicateLockPage (rel , so -> currPos .currPage , scan -> xs_snapshot );
1569
1558
@@ -2002,6 +1991,26 @@ _bt_savepostingitem(BTScanOpaque so, int itemIndex, OffsetNumber offnum,
2002
1991
currItem -> tupleOffset = tupleOffset ;
2003
1992
}
2004
1993
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
+
2005
2014
/*
2006
2015
* _bt_steppage() -- Step to next page containing valid data for scan
2007
2016
*
@@ -2543,7 +2552,6 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
2543
2552
Page page ;
2544
2553
BTPageOpaque opaque ;
2545
2554
OffsetNumber start ;
2546
- BTScanPosItem * currItem ;
2547
2555
2548
2556
Assert (!BTScanPosIsValid (so -> currPos ));
2549
2557
@@ -2593,12 +2601,6 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
2593
2601
if (!_bt_readfirstpage (scan , start , dir ))
2594
2602
return false;
2595
2603
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 );
2603
2605
return true;
2604
2606
}
0 commit comments