mirror of
https://github.com/postgres/postgres.git
synced 2025-06-17 00:02:17 -04:00
Add helper functions to simplify heapgettup code
Here we add heapgettup_start_page() and heapgettup_continue_page() to simplify the code in the heapgettup() function. Author: Melanie Plageman Reviewed-by: David Rowley Discussion: https://postgr.es/m/CAAKRu_bvkhka0CZQun28KTqhuUh5ZqY=_T8QEqZqOL02rpi2bw@mail.gmail.com
This commit is contained in:
parent
f9bc34fcb6
commit
8ca6d49f63
@ -544,6 +544,82 @@ heapgettup_initial_block(HeapScanDesc scan, ScanDirection dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* heapgettup_start_page - helper function for heapgettup()
|
||||||
|
*
|
||||||
|
* Return the next page to scan based on the scan->rs_cbuf and set *linesleft
|
||||||
|
* to the number of tuples on this page. Also set *lineoff to the first
|
||||||
|
* offset to scan with forward scans getting the first offset and backward
|
||||||
|
* getting the final offset on the page.
|
||||||
|
*/
|
||||||
|
static Page
|
||||||
|
heapgettup_start_page(HeapScanDesc scan, ScanDirection dir, int *linesleft,
|
||||||
|
OffsetNumber *lineoff)
|
||||||
|
{
|
||||||
|
Page page;
|
||||||
|
|
||||||
|
Assert(scan->rs_inited);
|
||||||
|
Assert(BufferIsValid(scan->rs_cbuf));
|
||||||
|
|
||||||
|
/* Caller is responsible for ensuring buffer is locked if needed */
|
||||||
|
page = BufferGetPage(scan->rs_cbuf);
|
||||||
|
|
||||||
|
TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, page);
|
||||||
|
|
||||||
|
*linesleft = PageGetMaxOffsetNumber((Page) page) - FirstOffsetNumber + 1;
|
||||||
|
|
||||||
|
if (ScanDirectionIsForward(dir))
|
||||||
|
*lineoff = FirstOffsetNumber;
|
||||||
|
else
|
||||||
|
*lineoff = (OffsetNumber) (*linesleft);
|
||||||
|
|
||||||
|
/* lineoff now references the physically previous or next tid */
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* heapgettup_continue_page - helper function for heapgettup()
|
||||||
|
*
|
||||||
|
* Return the next page to scan based on the scan->rs_cbuf and set *linesleft
|
||||||
|
* to the number of tuples left to scan on this page. Also set *lineoff to
|
||||||
|
* the next offset to scan according to the ScanDirection in 'dir'.
|
||||||
|
*/
|
||||||
|
static inline Page
|
||||||
|
heapgettup_continue_page(HeapScanDesc scan, ScanDirection dir, int *linesleft,
|
||||||
|
OffsetNumber *lineoff)
|
||||||
|
{
|
||||||
|
Page page;
|
||||||
|
|
||||||
|
Assert(scan->rs_inited);
|
||||||
|
Assert(BufferIsValid(scan->rs_cbuf));
|
||||||
|
|
||||||
|
/* Caller is responsible for ensuring buffer is locked if needed */
|
||||||
|
page = BufferGetPage(scan->rs_cbuf);
|
||||||
|
|
||||||
|
TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, page);
|
||||||
|
|
||||||
|
if (ScanDirectionIsForward(dir))
|
||||||
|
{
|
||||||
|
*lineoff = OffsetNumberNext(scan->rs_coffset);
|
||||||
|
*linesleft = PageGetMaxOffsetNumber(page) - (*lineoff) + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The previous returned tuple may have been vacuumed since the
|
||||||
|
* previous scan when we use a non-MVCC snapshot, so we must
|
||||||
|
* re-establish the lineoff <= PageGetMaxOffsetNumber(page) invariant
|
||||||
|
*/
|
||||||
|
*lineoff = Min(PageGetMaxOffsetNumber(page), OffsetNumberPrev(scan->rs_coffset));
|
||||||
|
*linesleft = *lineoff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lineoff now references the physically previous or next tid */
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* heapgettup - fetch next heap tuple
|
* heapgettup - fetch next heap tuple
|
||||||
*
|
*
|
||||||
@ -571,7 +647,6 @@ heapgettup(HeapScanDesc scan,
|
|||||||
ScanKey key)
|
ScanKey key)
|
||||||
{
|
{
|
||||||
HeapTuple tuple = &(scan->rs_ctup);
|
HeapTuple tuple = &(scan->rs_ctup);
|
||||||
Snapshot snapshot = scan->rs_base.rs_snapshot;
|
|
||||||
bool backward = ScanDirectionIsBackward(dir);
|
bool backward = ScanDirectionIsBackward(dir);
|
||||||
BlockNumber block;
|
BlockNumber block;
|
||||||
bool finished;
|
bool finished;
|
||||||
@ -595,21 +670,12 @@ heapgettup(HeapScanDesc scan,
|
|||||||
tuple->t_data = NULL;
|
tuple->t_data = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
scan->rs_inited = true;
|
||||||
|
|
||||||
heapgetpage((TableScanDesc) scan, block);
|
heapgetpage((TableScanDesc) scan, block);
|
||||||
|
|
||||||
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
||||||
page = BufferGetPage(scan->rs_cbuf);
|
page = heapgettup_start_page(scan, dir, &linesleft, &lineoff);
|
||||||
TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, page);
|
|
||||||
|
|
||||||
linesleft = PageGetMaxOffsetNumber(page) - FirstOffsetNumber + 1;
|
|
||||||
|
|
||||||
if (ScanDirectionIsForward(dir))
|
|
||||||
lineoff = FirstOffsetNumber; /* first offnum */
|
|
||||||
else
|
|
||||||
lineoff = (OffsetNumber) linesleft;
|
|
||||||
|
|
||||||
scan->rs_inited = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -617,26 +683,7 @@ heapgettup(HeapScanDesc scan,
|
|||||||
block = scan->rs_cblock;
|
block = scan->rs_cblock;
|
||||||
|
|
||||||
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
||||||
page = BufferGetPage(scan->rs_cbuf);
|
page = heapgettup_continue_page(scan, dir, &linesleft, &lineoff);
|
||||||
TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, page);
|
|
||||||
|
|
||||||
if (ScanDirectionIsForward(dir))
|
|
||||||
{
|
|
||||||
lineoff = OffsetNumberNext(scan->rs_coffset);
|
|
||||||
linesleft = PageGetMaxOffsetNumber(page) - lineoff + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The previous returned tuple may have been vacuumed since the
|
|
||||||
* previous scan when we use a non-MVCC snapshot, so we must
|
|
||||||
* re-establish the lineoff <= PageGetMaxOffsetNumber(page)
|
|
||||||
* invariant
|
|
||||||
*/
|
|
||||||
lineoff = Min(PageGetMaxOffsetNumber(page),
|
|
||||||
OffsetNumberPrev(scan->rs_coffset));
|
|
||||||
linesleft = lineoff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -667,12 +714,12 @@ heapgettup(HeapScanDesc scan,
|
|||||||
* if current tuple qualifies, return it.
|
* if current tuple qualifies, return it.
|
||||||
*/
|
*/
|
||||||
valid = HeapTupleSatisfiesVisibility(tuple,
|
valid = HeapTupleSatisfiesVisibility(tuple,
|
||||||
snapshot,
|
scan->rs_base.rs_snapshot,
|
||||||
scan->rs_cbuf);
|
scan->rs_cbuf);
|
||||||
|
|
||||||
HeapCheckForSerializableConflictOut(valid, scan->rs_base.rs_rd,
|
HeapCheckForSerializableConflictOut(valid, scan->rs_base.rs_rd,
|
||||||
tuple, scan->rs_cbuf,
|
tuple, scan->rs_cbuf,
|
||||||
snapshot);
|
scan->rs_base.rs_snapshot);
|
||||||
|
|
||||||
if (valid && key != NULL)
|
if (valid && key != NULL)
|
||||||
valid = HeapKeyTest(tuple, RelationGetDescr(scan->rs_base.rs_rd),
|
valid = HeapKeyTest(tuple, RelationGetDescr(scan->rs_base.rs_rd),
|
||||||
@ -773,7 +820,8 @@ heapgettup(HeapScanDesc scan,
|
|||||||
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
||||||
|
|
||||||
page = BufferGetPage(scan->rs_cbuf);
|
page = BufferGetPage(scan->rs_cbuf);
|
||||||
TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, page);
|
TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd,
|
||||||
|
page);
|
||||||
linesleft = PageGetMaxOffsetNumber(page);
|
linesleft = PageGetMaxOffsetNumber(page);
|
||||||
if (backward)
|
if (backward)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user