summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/nbtree/nbtsearch.c14
-rw-r--r--src/backend/access/nbtree/nbtutils.c6
2 files changed, 15 insertions, 5 deletions
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index 15f3bec1ab0..e0bbb97cbec 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -1628,6 +1628,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
* corresponding need for the left-link, since splits always go right.
*/
so->currPos.nextPage = opaque->btpo_next;
+ so->currPos.dir = dir;
/* initialize tuple workspace to empty */
so->currPos.nextTupleOffset = 0;
@@ -2083,16 +2084,24 @@ _bt_steppage(IndexScanDesc scan, ScanDirection dir)
* In effect, btrestpos leaves advancing the arrays up to the first
* _bt_readpage call (that takes place after it has restored markPos).
*/
- Assert(so->markPos.dir == dir);
if (so->needPrimScan)
{
- if (ScanDirectionIsForward(dir))
+ if (ScanDirectionIsForward(so->currPos.dir))
so->markPos.moreRight = true;
else
so->markPos.moreLeft = true;
}
}
+ /*
+ * Cancel primitive index scans that were scheduled when the call to
+ * _bt_readpage for currPos happened to use the opposite direction to the
+ * one that we're stepping in now. (It's okay to leave the scan's array
+ * keys as-is, since the next _bt_readpage will advance them.)
+ */
+ if (so->currPos.dir != dir)
+ so->needPrimScan = false;
+
if (ScanDirectionIsForward(dir))
{
/* Walk right to the next page with data */
@@ -2653,7 +2662,6 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
static inline void
_bt_initialize_more_data(BTScanOpaque so, ScanDirection dir)
{
- so->currPos.dir = dir;
if (so->needPrimScan)
{
Assert(so->numArrayKeys);
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index c22ccec789d..8d047d8873f 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -2426,8 +2426,10 @@ new_prim_scan:
/*
* End this primitive index scan, but schedule another.
*
- * Note: If the scan direction happens to change, this scheduled primitive
- * index scan won't go ahead after all.
+ * Note: We make a soft assumption that the current scan direction will
+ * also be used within _bt_next, when it is asked to step off this page.
+ * It is up to _bt_next to cancel this scheduled primitive index scan
+ * whenever it steps to a page in the direction opposite currPos.dir.
*/
pstate->continuescan = false; /* Tell _bt_readpage we're done... */
so->needPrimScan = true; /* ...but call _bt_first again */