From c5891e6801264a423b08d6d7c8e0a9565d274db6 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Thu, 20 Jun 2024 16:07:54 -0400 Subject: [PATCH v1] Fix nbtree array unsatisfied inequality check. --- src/backend/access/nbtree/nbtutils.c | 30 ++++++++++------------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 33f94ffd0..e0946af31 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -2449,30 +2449,20 @@ _bt_advance_array_keys(IndexScanDesc scan, BTReadPageState *pstate, &continuescanflip, &opsktrig); /* - * If we ended up here due to the all_required_satisfied criteria, - * test opsktrig in a way that ensures that finaltup contains the same - * prefix of key columns as caller's tuple (a prefix that satisfies - * earlier required-in-current-direction scan keys). - * - * If we ended up here due to the oppodir_inequality_sktrig criteria, - * test opsktrig in a way that ensures that the same scan key that our - * caller found to be unsatisfied (by the scan's tuple) was also the - * one unsatisfied just now (by finaltup). That way we'll only start - * a new primitive scan when we're sure that both tuples _don't_ share - * the same prefix of satisfied equality-constrained attribute values, - * and that finaltup has a non-NULL attribute value indicated by the - * unsatisfied scan key at offset opsktrig/sktrig. (This depends on - * _bt_check_compare not caring about the direction that inequalities - * are required in whenever NULL attribute values are unsatisfied. It - * only cares about the scan direction, and its relationship to - * whether NULLs are stored first or last relative to non-NULLs.) + * Only start a new primitive index scan when finaltup has a required + * unsatisfied inequality (unsatisfied in the opposite direction) */ Assert(all_required_satisfied != oppodir_inequality_sktrig); if (unlikely(!continuescanflip && - ((all_required_satisfied && opsktrig > sktrig) || - (oppodir_inequality_sktrig && opsktrig >= sktrig)))) + so->keyData[opsktrig].sk_strategy != BTEqualStrategyNumber)) { - Assert(so->keyData[opsktrig].sk_strategy != BTEqualStrategyNumber); + /* + * It's possible for the same inequality to be unsatisfied by both + * caller's tuple (in scan's direction) and finaltup (in the + * opposite direction) due to _bt_check_compare's behavior with + * NULLs + */ + Assert(opsktrig >= sktrig); /* not opsktrig > sktrig due to NULLs */ /* * Make sure that any non-required arrays are set to the first -- 2.45.1