From fe153095046571d90c35e3debd4c6547c64e34dd Mon Sep 17 00:00:00 2001
From: Peter Geoghegan <pg@bowt.ie>
Date: Wed, 18 Dec 2024 14:19:45 -0500
Subject: [PATCH v1] Fix failure to reset nbtree scanBehind flag.

Consistently reset so->scanBehind during nbtree array advancement, even
when array advancement was triggered by a non-required array's scan key.
Otherwise it's possible for queries to return wrong answers: any later
recheck call to _bt_check_compare cannot return true unless the scan's
so->scanBehind flag is already set to 'false'.

The so->scanBehind flag is only supposed to suppress returning true from
_bt_advance_array_keys like this when the arrays are advanced using the
page high key -- it was never supposed to happen because so->scanBehind
is still set from back when we read the prior page's high key.
---
 src/backend/access/nbtree/nbtutils.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 50cbf06cb..7ce1df771 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -1813,6 +1813,8 @@ _bt_advance_array_keys(IndexScanDesc scan, BTReadPageState *pstate,
 				all_required_satisfied = true,
 				all_satisfied = true;
 
+	so->scanBehind = so->oppositeDirCheck = false;	/* reset */
+
 	if (sktrig_required)
 	{
 		/*
@@ -1821,8 +1823,6 @@ _bt_advance_array_keys(IndexScanDesc scan, BTReadPageState *pstate,
 		Assert(!_bt_tuple_before_array_skeys(scan, dir, tuple, tupdesc,
 											 tupnatts, false, 0, NULL));
 
-		so->scanBehind = so->oppositeDirCheck = false;	/* reset */
-
 		/*
 		 * Required scan key wasn't satisfied, so required arrays will have to
 		 * advance.  Invalidate page-level state that tracks whether the
-- 
2.45.2

