From 011e5438aba40086086473a1b43e8146c029f42f Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Thu, 1 May 2025 23:17:20 +0200 Subject: [PATCH v20250501 5/7] fix: mark/restore call AM mark/restore even with batching, so that the AM can set some fields (e.g. moreRight/moreLeft in nbtree) --- src/backend/access/index/indexam.c | 14 ++++----- src/backend/access/nbtree/nbtree.c | 47 +++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index f0fda6d761c..20d4d65487f 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -516,11 +516,9 @@ index_markpos(IndexScanDesc scan) * Without batching, just use the ammarkpos() callback. With batching * everything is handled at this layer, without calling the AM. */ - if (scan->xs_batches == NULL) - { - scan->indexRelation->rd_indam->ammarkpos(scan); - } - else + scan->indexRelation->rd_indam->ammarkpos(scan); + + if (scan->xs_batches != NULL) { IndexScanBatches *batches = scan->xs_batches; IndexScanBatchPos *pos = &batches->markPos; @@ -588,9 +586,9 @@ index_restrpos(IndexScanDesc scan) * Without batching, just use the amrestrpos() callback. With batching * everything is handled at this layer, without calling the AM. */ - if (scan->xs_batches == NULL) - scan->indexRelation->rd_indam->amrestrpos(scan); - else + scan->indexRelation->rd_indam->amrestrpos(scan); + + if (scan->xs_batches != NULL) { IndexScanBatches *batches = scan->xs_batches; IndexScanBatchPos *pos = &batches->markPos; diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 6ea1dfcc52c..0143df993aa 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -309,10 +309,13 @@ btgetbatch(IndexScanDesc scan, ScanDirection dir) IndexScanBatch batch = INDEX_SCAN_BATCH(scan, scan->xs_batches->nextBatch-1); pos = (BTBatchScanPos) batch->opaque; - if (ScanDirectionIsForward(scan->xs_batches->direction)) - pos->moreRight = true; - else - pos->moreLeft = true; + if (so->needPrimScan) + { + if (ScanDirectionIsForward(scan->xs_batches->direction)) + pos->moreRight = true; + else + pos->moreLeft = true; + } } /* Each loop iteration performs another primitive index scan */ @@ -327,11 +330,7 @@ btgetbatch(IndexScanDesc scan, ScanDirection dir) res = _bt_first_batch(scan, dir); else { - if (so->numArrayKeys) - { - _bt_start_array_keys(scan, so->currPos.dir); - so->needPrimScan = false; - } + so->needPrimScan = false; /* * Now continue the scan. @@ -656,7 +655,20 @@ btmarkpos(IndexScanDesc scan) BTScanOpaque so = (BTScanOpaque) scan->opaque; /* with batching, mark/restore is handled in indexam */ - Assert(scan->xs_batches == NULL); + if (scan->xs_batches != NULL) + { + IndexScanBatch batch = INDEX_SCAN_BATCH(scan, scan->xs_batches->firstBatch); + BTBatchScanPos pos = NULL; + pos = (BTBatchScanPos) batch->opaque; + if (so->needPrimScan) + { + if (ScanDirectionIsForward(scan->xs_batches->direction)) + pos->moreRight = true; + else + pos->moreLeft = true; + } + return; + } /* There may be an old mark with a pin (but no lock). */ BTScanPosUnpinIfPinned(so->markPos); @@ -688,7 +700,20 @@ btrestrpos(IndexScanDesc scan) BTScanOpaque so = (BTScanOpaque) scan->opaque; /* with batching, mark/restore is handled in indexam */ - Assert(scan->xs_batches == NULL); + if (scan->xs_batches != NULL) + { + if (scan->xs_batches->markPos.batch != scan->xs_batches->firstBatch) + { + /* Reset the scan's array keys (see _bt_steppage for why) */ + if (so->numArrayKeys) + { + _bt_start_array_keys(scan, so->currPos.dir); + so->needPrimScan = false; + } + } + + return; + } if (so->markItemIndex >= 0) { -- 2.49.0