diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index efc5284e5b1..9f8277bf8fa 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -1026,6 +1026,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) */ if (chosen == NULL) break; + chosen->sk_flags |= SK_BT_BT_FIRST; startKeys[keysCount++] = chosen; /* diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 1510b97fbe1..84c4022201a 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -1400,7 +1400,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts, bool isNull; Datum test; bool requiredSameDir = false, - requiredOppositeDir = false; + guaranteedByBtFirst = false; /* * Check if the key is required for ordered scan in the same or @@ -1409,9 +1409,10 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts, if (((key->sk_flags & SK_BT_REQFWD) && ScanDirectionIsForward(dir)) || ((key->sk_flags & SK_BT_REQBKWD) && ScanDirectionIsBackward(dir))) requiredSameDir = true; - else if (((key->sk_flags & SK_BT_REQFWD) && ScanDirectionIsBackward(dir)) || - ((key->sk_flags & SK_BT_REQBKWD) && ScanDirectionIsForward(dir))) - requiredOppositeDir = true; + else if ((((key->sk_flags & SK_BT_REQFWD) && ScanDirectionIsBackward(dir)) || + ((key->sk_flags & SK_BT_REQBKWD) && ScanDirectionIsForward(dir))) && + (key->sk_flags & SK_BT_BT_FIRST)) + guaranteedByBtFirst = true; /* * Is the key required for scanning for either forward or backward @@ -1419,7 +1420,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts, * known to be matched, skip the check. Except for the row keys, * where NULLs could be found in the middle of matching values. */ - if ((requiredSameDir || requiredOppositeDir) && + if ((requiredSameDir || guaranteedByBtFirst) && !(key->sk_flags & SK_ROW_HEADER) && requiredMatchedByPrecheck) continue; @@ -1526,7 +1527,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts, * _bt_first() except for the NULLs checking, which have already done * above. */ - if (!requiredOppositeDir) + if (!guaranteedByBtFirst) { test = FunctionCall2Coll(&key->sk_func, key->sk_collation, datum, key->sk_argument); diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 7bfbf3086c8..e7783621a2b 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -1090,6 +1090,7 @@ typedef BTScanOpaqueData *BTScanOpaque; */ #define SK_BT_REQFWD 0x00010000 /* required to continue forward scan */ #define SK_BT_REQBKWD 0x00020000 /* required to continue backward scan */ +#define SK_BT_BT_FIRST 0x00040000 /* used for _bt_first() */ #define SK_BT_INDOPTION_SHIFT 24 /* must clear the above bits */ #define SK_BT_DESC (INDOPTION_DESC << SK_BT_INDOPTION_SHIFT) #define SK_BT_NULLS_FIRST (INDOPTION_NULLS_FIRST << SK_BT_INDOPTION_SHIFT)