From 6964bd9001f6eb0992d783321bc4264b78d8a741 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Fri, 6 Jan 2023 12:39:38 -0500 Subject: [PATCH v5 2/7] Add no movement scan helper No movement scan can be handled first in heapgettup() and heapgettup_pagemode(). Refactor this case into its own helper function to improve readability. --- src/backend/access/heap/heapam.c | 116 ++++++++++++++----------------- 1 file changed, 54 insertions(+), 62 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 4df19fe76c..c80b547809 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -483,6 +483,44 @@ heapgetpage(TableScanDesc sscan, BlockNumber block) scan->rs_ntuples = ntup; } + +/* +* ``no movement'' scan direction: refetch prior tuple +*/ +static void +heapgettup_no_movement(HeapScanDesc scan) +{ + BlockNumber block; + OffsetNumber lineoff; + ItemId lpp; + Page page; + HeapTuple tuple = &(scan->rs_ctup); + + if (!scan->rs_inited) + { + Assert(!BufferIsValid(scan->rs_cbuf)); + tuple->t_data = NULL; + return; + } + + block = ItemPointerGetBlockNumber(&(tuple->t_self)); + if (block != scan->rs_cblock) + heapgetpage((TableScanDesc) scan, block); + + /* Since the tuple was previously fetched, needn't lock page here */ + page = BufferGetPage(scan->rs_cbuf); + TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, page); + lineoff = ItemPointerGetOffsetNumber(&(tuple->t_self)); + lpp = PageGetItemId(page, lineoff); + Assert(ItemIdIsNormal(lpp)); + + tuple->t_data = (HeapTupleHeader) PageGetItem(page, lpp); + tuple->t_len = ItemIdGetLength(lpp); + + return; +} + + /* ---------------- * heapgettup - fetch next heap tuple * @@ -523,6 +561,12 @@ heapgettup(HeapScanDesc scan, int linesleft; ItemId lpp; + if (unlikely(ScanDirectionIsNoMovement(dir))) + { + heapgettup_no_movement(scan); + return; + } + /* * calculate next starting lineoff, given scan direction */ @@ -583,8 +627,9 @@ heapgettup(HeapScanDesc scan, linesleft = lines - lineoff + 1; } - else if (backward) + else { + Assert(backward); /* backward parallel scan not supported */ Assert(scan->rs_base.rs_parallel == NULL); @@ -653,34 +698,6 @@ heapgettup(HeapScanDesc scan, linesleft = lineoff; } - else - { - /* - * ``no movement'' scan direction: refetch prior tuple - */ - if (!scan->rs_inited) - { - Assert(!BufferIsValid(scan->rs_cbuf)); - tuple->t_data = NULL; - return; - } - - block = ItemPointerGetBlockNumber(&(tuple->t_self)); - if (block != scan->rs_cblock) - heapgetpage((TableScanDesc) scan, block); - - /* Since the tuple was previously fetched, needn't lock page here */ - page = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, page); - lineoff = ItemPointerGetOffsetNumber(&(tuple->t_self)); - lpp = PageGetItemId(page, lineoff); - Assert(ItemIdIsNormal(lpp)); - - tuple->t_data = (HeapTupleHeader) PageGetItem(page, lpp); - tuple->t_len = ItemIdGetLength(lpp); - - return; - } /* * advance the scan until we find a qualifying tuple or run out of stuff @@ -861,6 +878,12 @@ heapgettup_pagemode(HeapScanDesc scan, int linesleft; ItemId lpp; + if (unlikely(ScanDirectionIsNoMovement(dir))) + { + heapgettup_no_movement(scan); + return; + } + /* * calculate next starting lineindex, given scan direction */ @@ -918,8 +941,9 @@ heapgettup_pagemode(HeapScanDesc scan, linesleft = lines - lineindex; } - else if (backward) + else { + Assert(backward); /* backward parallel scan not supported */ Assert(scan->rs_base.rs_parallel == NULL); @@ -978,38 +1002,6 @@ heapgettup_pagemode(HeapScanDesc scan, linesleft = lineindex + 1; } - else - { - /* - * ``no movement'' scan direction: refetch prior tuple - */ - if (!scan->rs_inited) - { - Assert(!BufferIsValid(scan->rs_cbuf)); - tuple->t_data = NULL; - return; - } - - block = ItemPointerGetBlockNumber(&(tuple->t_self)); - if (block != scan->rs_cblock) - heapgetpage((TableScanDesc) scan, block); - - /* Since the tuple was previously fetched, needn't lock page here */ - page = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, page); - lineoff = ItemPointerGetOffsetNumber(&(tuple->t_self)); - lpp = PageGetItemId(page, lineoff); - Assert(ItemIdIsNormal(lpp)); - - tuple->t_data = (HeapTupleHeader) PageGetItem(page, lpp); - tuple->t_len = ItemIdGetLength(lpp); - - /* check that rs_cindex is in sync */ - Assert(scan->rs_cindex < scan->rs_ntuples); - Assert(lineoff == scan->rs_vistuples[scan->rs_cindex]); - - return; - } /* * advance the scan until we find a qualifying tuple or run out of stuff -- 2.34.1