Remove some more "snapshot too old" vestiges.

Commit f691f5b8 removed the logic, but left behind some now-useless
Snapshot arguments to various AM-internal functions, and missed a couple
of comments.

Reported-by: Peter Geoghegan <pg@bowt.ie>
Discussion: https://postgr.es/m/CAH2-Wznj9qSNXZ1P1uWTUD_FeaTezbUazb416EPwi4Qr_jR_6A%40mail.gmail.com
This commit is contained in:
Thomas Munro 2023-09-08 17:12:12 +12:00
parent e722846daf
commit 9f0602539d
16 changed files with 56 additions and 85 deletions

View File

@ -2694,7 +2694,7 @@ bt_rootdescend(BtreeCheckState *state, IndexTuple itup)
*/
Assert(state->readonly && state->rootdescend);
exists = false;
stack = _bt_search(state->rel, NULL, key, &lbuf, BT_READ, NULL);
stack = _bt_search(state->rel, NULL, key, &lbuf, BT_READ);
if (BufferIsValid(lbuf))
{

View File

@ -169,7 +169,7 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
MemoryContext oldcxt = CurrentMemoryContext;
bool autosummarize = BrinGetAutoSummarize(idxRel);
revmap = brinRevmapInitialize(idxRel, &pagesPerRange, NULL);
revmap = brinRevmapInitialize(idxRel, &pagesPerRange);
/*
* origHeapBlk is the block number where the insertion occurred. heapBlk
@ -202,7 +202,7 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
lastPageTuple =
brinGetTupleForHeapBlock(revmap, lastPageRange, &buf, &off,
NULL, BUFFER_LOCK_SHARE, NULL);
NULL, BUFFER_LOCK_SHARE);
if (!lastPageTuple)
{
bool recorded;
@ -222,7 +222,7 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
}
brtup = brinGetTupleForHeapBlock(revmap, heapBlk, &buf, &off,
NULL, BUFFER_LOCK_SHARE, NULL);
NULL, BUFFER_LOCK_SHARE);
/* if range is unsummarized, there's nothing to do */
if (!brtup)
@ -332,8 +332,7 @@ brinbeginscan(Relation r, int nkeys, int norderbys)
scan = RelationGetIndexScan(r, nkeys, norderbys);
opaque = palloc_object(BrinOpaque);
opaque->bo_rmAccess = brinRevmapInitialize(r, &opaque->bo_pagesPerRange,
scan->xs_snapshot);
opaque->bo_rmAccess = brinRevmapInitialize(r, &opaque->bo_pagesPerRange);
opaque->bo_bdesc = brin_build_desc(r);
scan->opaque = opaque;
@ -537,8 +536,7 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
MemoryContextResetAndDeleteChildren(perRangeCxt);
tup = brinGetTupleForHeapBlock(opaque->bo_rmAccess, heapBlk, &buf,
&off, &size, BUFFER_LOCK_SHARE,
scan->xs_snapshot);
&off, &size, BUFFER_LOCK_SHARE);
if (tup)
{
gottuple = true;
@ -880,7 +878,7 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
/*
* Initialize our state, including the deformed tuple state.
*/
revmap = brinRevmapInitialize(index, &pagesPerRange, NULL);
revmap = brinRevmapInitialize(index, &pagesPerRange);
state = initialize_brin_buildstate(index, revmap, pagesPerRange);
/*
@ -1458,8 +1456,7 @@ summarize_range(IndexInfo *indexInfo, BrinBuildState *state, Relation heapRel,
* the same.)
*/
phtup = brinGetTupleForHeapBlock(state->bs_rmAccess, heapBlk, &phbuf,
&offset, &phsz, BUFFER_LOCK_SHARE,
NULL);
&offset, &phsz, BUFFER_LOCK_SHARE);
/* the placeholder tuple must exist */
if (phtup == NULL)
elog(ERROR, "missing placeholder tuple");
@ -1496,7 +1493,7 @@ brinsummarize(Relation index, Relation heapRel, BlockNumber pageRange,
Buffer buf;
BlockNumber startBlk;
revmap = brinRevmapInitialize(index, &pagesPerRange, NULL);
revmap = brinRevmapInitialize(index, &pagesPerRange);
/* determine range of pages to process */
heapNumBlocks = RelationGetNumberOfBlocks(heapRel);
@ -1537,7 +1534,7 @@ brinsummarize(Relation index, Relation heapRel, BlockNumber pageRange,
CHECK_FOR_INTERRUPTS();
tup = brinGetTupleForHeapBlock(revmap, startBlk, &buf, &off, NULL,
BUFFER_LOCK_SHARE, NULL);
BUFFER_LOCK_SHARE);
if (tup == NULL)
{
/* no revmap entry for this heap range. Summarize it. */

View File

@ -68,8 +68,7 @@ static void revmap_physical_extend(BrinRevmap *revmap);
* brinRevmapTerminate when caller is done with it.
*/
BrinRevmap *
brinRevmapInitialize(Relation idxrel, BlockNumber *pagesPerRange,
Snapshot snapshot)
brinRevmapInitialize(Relation idxrel, BlockNumber *pagesPerRange)
{
BrinRevmap *revmap;
Buffer meta;
@ -194,8 +193,7 @@ brinSetHeapBlockItemptr(Buffer buf, BlockNumber pagesPerRange,
*/
BrinTuple *
brinGetTupleForHeapBlock(BrinRevmap *revmap, BlockNumber heapBlk,
Buffer *buf, OffsetNumber *off, Size *size, int mode,
Snapshot snapshot)
Buffer *buf, OffsetNumber *off, Size *size, int mode)
{
Relation idxRel = revmap->rm_irel;
BlockNumber mapBlk;
@ -339,7 +337,7 @@ brinRevmapDesummarizeRange(Relation idxrel, BlockNumber heapBlk)
OffsetNumber regOffset;
ItemId lp;
revmap = brinRevmapInitialize(idxrel, &pagesPerRange, NULL);
revmap = brinRevmapInitialize(idxrel, &pagesPerRange);
revmapBlk = revmap_get_blkno(revmap, heapBlk);
if (!BlockNumberIsValid(revmapBlk))

View File

@ -636,8 +636,7 @@ toast_close_indexes(Relation *toastidxs, int num_indexes, LOCKMODE lock)
*
* Initialize an appropriate TOAST snapshot. We must use an MVCC snapshot
* to initialize the TOAST snapshot; since we don't know which one to use,
* just use the oldest one. This is safe: at worst, we will get a "snapshot
* too old" error that might have been avoided otherwise.
* just use the oldest one.
*/
void
init_toast_snapshot(Snapshot toast_snapshot)

View File

@ -78,7 +78,7 @@ ginTraverseLock(Buffer buffer, bool searchMode)
*/
GinBtreeStack *
ginFindLeafPage(GinBtree btree, bool searchMode,
bool rootConflictCheck, Snapshot snapshot)
bool rootConflictCheck)
{
GinBtreeStack *stack;

View File

@ -1917,7 +1917,7 @@ ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
{
/* search for the leaf page where the first item should go to */
btree.itemptr = insertdata.items[insertdata.curitem];
stack = ginFindLeafPage(&btree, false, true, NULL);
stack = ginFindLeafPage(&btree, false, true);
ginInsertValue(&btree, stack, &insertdata, buildStats);
}
@ -1927,8 +1927,7 @@ ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
* Starts a new scan on a posting tree.
*/
GinBtreeStack *
ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno,
Snapshot snapshot)
ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno)
{
GinBtreeStack *stack;
@ -1936,7 +1935,7 @@ ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno,
btree->fullScan = true;
stack = ginFindLeafPage(btree, true, false, snapshot);
stack = ginFindLeafPage(btree, true, false);
return stack;
}

View File

@ -67,7 +67,7 @@ moveRightIfItNeeded(GinBtreeData *btree, GinBtreeStack *stack, Snapshot snapshot
*/
static void
scanPostingTree(Relation index, GinScanEntry scanEntry,
BlockNumber rootPostingTree, Snapshot snapshot)
BlockNumber rootPostingTree)
{
GinBtreeData btree;
GinBtreeStack *stack;
@ -75,7 +75,7 @@ scanPostingTree(Relation index, GinScanEntry scanEntry,
Page page;
/* Descend to the leftmost leaf page */
stack = ginScanBeginPostingTree(&btree, index, rootPostingTree, snapshot);
stack = ginScanBeginPostingTree(&btree, index, rootPostingTree);
buffer = stack->buffer;
IncrBufferRefCount(buffer); /* prevent unpin in freeGinBtreeStack */
@ -244,8 +244,7 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
PredicateLockPage(btree->index, rootPostingTree, snapshot);
/* Collect all the TIDs in this entry's posting tree */
scanPostingTree(btree->index, scanEntry, rootPostingTree,
snapshot);
scanPostingTree(btree->index, scanEntry, rootPostingTree);
/*
* We lock again the entry page and while it was unlocked insert
@ -344,7 +343,7 @@ restartScanEntry:
ginPrepareEntryScan(&btreeEntry, entry->attnum,
entry->queryKey, entry->queryCategory,
ginstate);
stackEntry = ginFindLeafPage(&btreeEntry, true, false, snapshot);
stackEntry = ginFindLeafPage(&btreeEntry, true, false);
page = BufferGetPage(stackEntry->buffer);
/* ginFindLeafPage() will have already checked snapshot age. */
@ -419,7 +418,7 @@ restartScanEntry:
needUnlock = false;
stack = ginScanBeginPostingTree(&entry->btree, ginstate->index,
rootPostingTree, snapshot);
rootPostingTree);
entry->buffer = stack->buffer;
/*
@ -652,7 +651,7 @@ startScan(IndexScanDesc scan)
*/
static void
entryLoadMoreItems(GinState *ginstate, GinScanEntry entry,
ItemPointerData advancePast, Snapshot snapshot)
ItemPointerData advancePast)
{
Page page;
int i;
@ -697,7 +696,7 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry,
OffsetNumberNext(GinItemPointerGetOffsetNumber(&advancePast)));
}
entry->btree.fullScan = false;
stack = ginFindLeafPage(&entry->btree, true, false, snapshot);
stack = ginFindLeafPage(&entry->btree, true, false);
/* we don't need the stack, just the buffer. */
entry->buffer = stack->buffer;
@ -807,7 +806,7 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry,
*/
static void
entryGetItem(GinState *ginstate, GinScanEntry entry,
ItemPointerData advancePast, Snapshot snapshot)
ItemPointerData advancePast)
{
Assert(!entry->isFinished);
@ -938,7 +937,7 @@ entryGetItem(GinState *ginstate, GinScanEntry entry,
/* If we've processed the current batch, load more items */
while (entry->offset >= entry->nlist)
{
entryLoadMoreItems(ginstate, entry, advancePast, snapshot);
entryLoadMoreItems(ginstate, entry, advancePast);
if (entry->isFinished)
{
@ -989,7 +988,7 @@ entryGetItem(GinState *ginstate, GinScanEntry entry,
*/
static void
keyGetItem(GinState *ginstate, MemoryContext tempCtx, GinScanKey key,
ItemPointerData advancePast, Snapshot snapshot)
ItemPointerData advancePast)
{
ItemPointerData minItem;
ItemPointerData curPageLossy;
@ -1036,7 +1035,7 @@ keyGetItem(GinState *ginstate, MemoryContext tempCtx, GinScanKey key,
*/
if (ginCompareItemPointers(&entry->curItem, &advancePast) <= 0)
{
entryGetItem(ginstate, entry, advancePast, snapshot);
entryGetItem(ginstate, entry, advancePast);
if (entry->isFinished)
continue;
}
@ -1111,7 +1110,7 @@ keyGetItem(GinState *ginstate, MemoryContext tempCtx, GinScanKey key,
if (ginCompareItemPointers(&entry->curItem, &advancePast) <= 0)
{
entryGetItem(ginstate, entry, advancePast, snapshot);
entryGetItem(ginstate, entry, advancePast);
if (entry->isFinished)
continue;
}
@ -1334,8 +1333,7 @@ scanGetItem(IndexScanDesc scan, ItemPointerData advancePast,
}
/* Fetch the next item for this key that is > advancePast. */
keyGetItem(&so->ginstate, so->tempCtx, key, advancePast,
scan->xs_snapshot);
keyGetItem(&so->ginstate, so->tempCtx, key, advancePast);
if (key->isFinished)
return false;

View File

@ -192,7 +192,7 @@ ginEntryInsert(GinState *ginstate,
ginPrepareEntryScan(&btree, attnum, key, category, ginstate);
btree.isBuild = (buildStats != NULL);
stack = ginFindLeafPage(&btree, false, false, NULL);
stack = ginFindLeafPage(&btree, false, false);
page = BufferGetPage(stack->buffer);
if (btree.findItem(&btree, stack))

View File

@ -2865,10 +2865,6 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat,
* in effect in any case. lazy_scan_prune makes the optimistic assumption
* that any LP_DEAD items it encounters will always be LP_UNUSED by the time
* we're called.
*
* Also don't attempt it if we are doing early pruning/vacuuming, because a
* scan which cannot find a truncated heap page cannot determine that the
* snapshot is too old to read that page.
*/
static bool
should_attempt_truncation(LVRelState *vacrel)

View File

@ -378,7 +378,7 @@ _bt_search_insert(Relation rel, Relation heaprel, BTInsertState insertstate)
/* Cannot use optimization -- descend tree, return proper descent stack */
return _bt_search(rel, heaprel, insertstate->itup_key, &insertstate->buf,
BT_WRITE, NULL);
BT_WRITE);
}
/*
@ -2165,7 +2165,7 @@ _bt_insert_parent(Relation rel,
BlockNumberIsValid(RelationGetTargetBlock(rel))));
/* Find the leftmost page at the next level up */
pbuf = _bt_get_endpoint(rel, opaque->btpo_level + 1, false, NULL);
pbuf = _bt_get_endpoint(rel, opaque->btpo_level + 1, false);
/* Set up a phony stack entry pointing there */
stack = &fakestack;
stack->bts_blkno = BufferGetBlockNumber(pbuf);

View File

@ -1962,8 +1962,7 @@ _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate)
itup_key = _bt_mkscankey(rel, targetkey);
/* find the leftmost leaf page with matching pivot/high key */
itup_key->pivotsearch = true;
stack = _bt_search(rel, NULL, itup_key, &sleafbuf, BT_READ,
NULL);
stack = _bt_search(rel, NULL, itup_key, &sleafbuf, BT_READ);
/* won't need a second lock or pin on leafbuf */
_bt_relbuf(rel, sleafbuf);

View File

@ -43,7 +43,7 @@ static bool _bt_steppage(IndexScanDesc scan, ScanDirection dir);
static bool _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir);
static bool _bt_parallel_readpage(IndexScanDesc scan, BlockNumber blkno,
ScanDirection dir);
static Buffer _bt_walk_left(Relation rel, Buffer buf, Snapshot snapshot);
static Buffer _bt_walk_left(Relation rel, Buffer buf);
static bool _bt_endpoint(IndexScanDesc scan, ScanDirection dir);
static inline void _bt_initialize_more_data(BTScanOpaque so, ScanDirection dir);
@ -83,10 +83,6 @@ _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp)
* which is locked and pinned. No locks are held on the parent pages,
* however!
*
* If the snapshot parameter is not NULL, "old snapshot" checking will take
* place during the descent through the tree. This is not needed when
* positioning for an insert or delete, so NULL is used for those cases.
*
* The returned buffer is locked according to access parameter. Additionally,
* access = BT_WRITE will allow an empty root page to be created and returned.
* When access = BT_READ, an empty index will result in *bufP being set to
@ -98,7 +94,7 @@ _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp)
*/
BTStack
_bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP,
int access, Snapshot snapshot)
int access)
{
BTStack stack_in = NULL;
int page_access = BT_READ;
@ -138,7 +134,7 @@ _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP,
* opportunity to finish splits of internal pages too.
*/
*bufP = _bt_moveright(rel, heaprel, key, *bufP, (access == BT_WRITE),
stack_in, page_access, snapshot);
stack_in, page_access);
/* if this is a leaf page, we're done */
page = BufferGetPage(*bufP);
@ -198,8 +194,7 @@ _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP,
* but before we acquired a write lock. If it has, we may need to
* move right to its new sibling. Do that.
*/
*bufP = _bt_moveright(rel, heaprel, key, *bufP, true, stack_in, BT_WRITE,
snapshot);
*bufP = _bt_moveright(rel, heaprel, key, *bufP, true, stack_in, BT_WRITE);
}
return stack_in;
@ -235,10 +230,6 @@ _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP,
* On entry, we have the buffer pinned and a lock of the type specified by
* 'access'. If we move right, we release the buffer and lock and acquire
* the same on the right sibling. Return value is the buffer we stop at.
*
* If the snapshot parameter is not NULL, "old snapshot" checking will take
* place during the descent through the tree. This is not needed when
* positioning for an insert or delete, so NULL is used for those cases.
*/
Buffer
_bt_moveright(Relation rel,
@ -247,8 +238,7 @@ _bt_moveright(Relation rel,
Buffer buf,
bool forupdate,
BTStack stack,
int access,
Snapshot snapshot)
int access)
{
Page page;
BTPageOpaque opaque;
@ -1373,7 +1363,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
* Use the manufactured insertion scan key to descend the tree and
* position ourselves on the target leaf page.
*/
stack = _bt_search(rel, NULL, &inskey, &buf, BT_READ, scan->xs_snapshot);
stack = _bt_search(rel, NULL, &inskey, &buf, BT_READ);
/* don't need to keep the stack around... */
_bt_freestack(stack);
@ -1392,8 +1382,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (IsolationIsSerializable())
{
PredicateLockRelation(rel, scan->xs_snapshot);
stack = _bt_search(rel, NULL, &inskey, &buf, BT_READ,
scan->xs_snapshot);
stack = _bt_search(rel, NULL, &inskey, &buf, BT_READ);
_bt_freestack(stack);
}
@ -2113,8 +2102,7 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir)
}
/* Step to next physical page */
so->currPos.buf = _bt_walk_left(rel, so->currPos.buf,
scan->xs_snapshot);
so->currPos.buf = _bt_walk_left(rel, so->currPos.buf);
/* if we're physically at end of index, return failure */
if (so->currPos.buf == InvalidBuffer)
@ -2205,7 +2193,7 @@ _bt_parallel_readpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir)
* again if it's important.
*/
static Buffer
_bt_walk_left(Relation rel, Buffer buf, Snapshot snapshot)
_bt_walk_left(Relation rel, Buffer buf)
{
Page page;
BTPageOpaque opaque;
@ -2320,8 +2308,7 @@ _bt_walk_left(Relation rel, Buffer buf, Snapshot snapshot)
* The returned buffer is pinned and read-locked.
*/
Buffer
_bt_get_endpoint(Relation rel, uint32 level, bool rightmost,
Snapshot snapshot)
_bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
{
Buffer buf;
Page page;
@ -2417,7 +2404,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
* version of _bt_search(). We don't maintain a stack since we know we
* won't need it.
*/
buf = _bt_get_endpoint(rel, 0, ScanDirectionIsBackward(dir), scan->xs_snapshot);
buf = _bt_get_endpoint(rel, 0, ScanDirectionIsBackward(dir));
if (!BufferIsValid(buf))
{

View File

@ -815,7 +815,7 @@ spgTestLeafTuple(SpGistScanOpaque so,
*/
static void
spgWalk(Relation index, SpGistScanOpaque so, bool scanWholeIndex,
storeRes_func storeRes, Snapshot snapshot)
storeRes_func storeRes)
{
Buffer buffer = InvalidBuffer;
bool reportedSome = false;
@ -949,7 +949,7 @@ spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
so->tbm = tbm;
so->ntids = 0;
spgWalk(scan->indexRelation, so, true, storeBitmap, scan->xs_snapshot);
spgWalk(scan->indexRelation, so, true, storeBitmap);
return so->ntids;
}
@ -1070,8 +1070,7 @@ spggettuple(IndexScanDesc scan, ScanDirection dir)
}
so->iPtr = so->nPtrs = 0;
spgWalk(scan->indexRelation, so, false, storeGettuple,
scan->xs_snapshot);
spgWalk(scan->indexRelation, so, false, storeGettuple);
if (so->nPtrs == 0)
break; /* must have completed scan */

View File

@ -24,7 +24,7 @@
typedef struct BrinRevmap BrinRevmap;
extern BrinRevmap *brinRevmapInitialize(Relation idxrel,
BlockNumber *pagesPerRange, Snapshot snapshot);
BlockNumber *pagesPerRange);
extern void brinRevmapTerminate(BrinRevmap *revmap);
extern void brinRevmapExtend(BrinRevmap *revmap,
@ -35,7 +35,7 @@ extern void brinSetHeapBlockItemptr(Buffer buf, BlockNumber pagesPerRange,
BlockNumber heapBlk, ItemPointerData tid);
extern BrinTuple *brinGetTupleForHeapBlock(BrinRevmap *revmap,
BlockNumber heapBlk, Buffer *buf, OffsetNumber *off,
Size *size, int mode, Snapshot snapshot);
Size *size, int mode);
extern bool brinRevmapDesummarizeRange(Relation idxrel, BlockNumber heapBlk);
#endif /* BRIN_REVMAP_H */

View File

@ -202,7 +202,7 @@ typedef struct
*/
extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode,
bool rootConflictCheck, Snapshot snapshot);
bool rootConflictCheck);
extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode);
extern void freeGinBtreeStack(GinBtreeStack *stack);
extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack,
@ -230,7 +230,7 @@ extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
ItemPointerData *items, uint32 nitem,
GinStatsData *buildStats);
extern GinBtreeStack *ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno, Snapshot snapshot);
extern GinBtreeStack *ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno);
extern void ginDataFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage);
/*

View File

@ -1231,16 +1231,15 @@ extern void _bt_pendingfsm_finalize(Relation rel, BTVacState *vstate);
* prototypes for functions in nbtsearch.c
*/
extern BTStack _bt_search(Relation rel, Relation heaprel, BTScanInsert key,
Buffer *bufP, int access, Snapshot snapshot);
Buffer *bufP, int access);
extern Buffer _bt_moveright(Relation rel, Relation heaprel, BTScanInsert key,
Buffer buf, bool forupdate, BTStack stack,
int access, Snapshot snapshot);
int access);
extern OffsetNumber _bt_binsrch_insert(Relation rel, BTInsertState insertstate);
extern int32 _bt_compare(Relation rel, BTScanInsert key, Page page, OffsetNumber offnum);
extern bool _bt_first(IndexScanDesc scan, ScanDirection dir);
extern bool _bt_next(IndexScanDesc scan, ScanDirection dir);
extern Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost,
Snapshot snapshot);
extern Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost);
/*
* prototypes for functions in nbtutils.c