From 3d261105e8498a6309b612419a23cc3012caf03b Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Thu, 1 May 2025 14:58:02 -0400 Subject: [PATCH v1 2/2] Prevent prematurely nbtree array advancement. Prevent forcenonrequired from prematurely advancing the scan's array keys beyond key space that the scan has yet to read tuples from. Do this by defensively resetting the scan's array keys (to the first array elements for the current scan direction) before the _bt_checkkeys call for pstate.finaltup. Otherwise, it's possible for the scan to fail to return matching tuples in rare edge cases. Oversight in commit 8a510275. --- src/backend/access/nbtree/nbtsearch.c | 3 +++ src/backend/access/nbtree/nbtutils.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 77264ddee..e9e53cd7e 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -1791,6 +1791,8 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum, int truncatt; truncatt = BTreeTupleGetNAtts(itup, rel); + if (pstate.forcenonrequired) + _bt_start_array_keys(scan, dir); pstate.forcenonrequired = false; pstate.startikey = 0; /* _bt_set_startikey ignores P_HIKEY */ _bt_checkkeys(scan, &pstate, arrayKeys, itup, truncatt); @@ -1881,6 +1883,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum, { pstate.forcenonrequired = false; pstate.startikey = 0; + _bt_start_array_keys(scan, dir); } passes_quals = _bt_checkkeys(scan, &pstate, arrayKeys, itup, indnatts); diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 2fbbbc31f..91ff52868 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -2546,6 +2546,8 @@ _bt_set_startikey(IndexScanDesc scan, BTReadPageState *pstate) * Can't let pstate.startikey get set to an ikey beyond a * RowCompare inequality */ + if (start_past_saop_eq || so->skipScan) + return; break; /* unsafe */ } if (key->sk_strategy != BTEqualStrategyNumber) -- 2.49.0