8000 Revert "Stop btree indexscans upon reaching nulls in either direction." · postwait/postgres@5cd7b68 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 5cd7b68

Browse files
committed
Revert "Stop btree indexscans upon reaching nulls in either direction."
This reverts commit 048fffe. As pointed out by Naoya Anzai, we need to do more work to make that idea handle end-of-index cases, and it is looking like too much risk for a back-patch. So bug #6278 is only going to be fixed in HEAD.
1 parent bf70bf4 commit 5cd7b68

File tree

1 file changed

+65
-42
lines changed

1 file changed

+65
-42
lines changed

src/backend/access/nbtree/nbtutils.c

Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ _bt_freestack(BTStack stack)
176176
* Also, for a DESC column, we commute (flip) all the sk_strategy numbers
177177
* so that the index sorts in the desired direction.
178178
*
179-
* One key purpose of this routine is to discover which scan keys must be
180-
* satisfied to continue the scan. It also attempts to eliminate redundant
181-
* keys and detect contradictory keys. (If the index opfamily provides
182-
* incomplete sets of cross-type operators, we may fail to detect redundant
183-
* or contradictory keys, but we can survive that.)
179+
* One key purpose of this routine is to discover how many scan keys
180+
* must be satisfied to continue the scan. It also attempts to eliminate
181+
* redundant keys and detect contradictory keys. (If the index opfamily
182+
* provides incomplete sets of cross-type operators, we may fail to detect
183+
* redundant or contradictory keys, but we can survive that.)
184184
*
185185
* The output keys must be sorted by index attribute. Presently we expect
186186
* (but verify) that the input keys are already so sorted --- this is done
@@ -215,16 +215,6 @@ _bt_freestack(BTStack stack)
215215
* </<= keys if we can't compare them. The logic about required keys still
216216
* works if we don't eliminate redundant keys.
217217
*
218-
* Note that the reason we need direction-sensitive required-key flags is
219-
* precisely that we may not be able to eliminate redundant keys. Suppose
220-
* we have "x > 4::int AND x > 10::bigint", and we are unable to determine
221-
* which key is more restrictive for lack of a suitable cross-type operator.
222-
* _bt_first will arbitrarily pick one of the keys to do the initial
223-
* positioning with. If it picks x > 4, then the x > 10 condition will fail
224-
* until we reach index entries > 10; but we can't stop the scan just because
225-
* x > 10 is failing. On the other hand, if we are scanning backwards, then
226-
* failure of either key is indeed enough to stop the scan.
227-
*
228218
* As a byproduct of this work, we can detect contradictory quals such
229219
* as "x = 1 AND x > 2". If we see that, we return so->qual_ok = FALSE,
230220
* indicating the scan need not be run at all since no tuples can match.
@@ -953,16 +943,15 @@ _bt_checkkeys(IndexScanDesc scan,
953943
}
954944

955945
/*
956-
* Tuple fails this qual. If it's a required qual, then we can
957-
* conclude no further tuples will pass, either. We can stop
958-
* regardless of the scan direction, because we know that NULLs
959-
* sort to one end or the other of the range of values. If this
960-
* tuple doesn't pass, then no future ones will either, until we
961-
* reach the next set of values of the higher-order index attrs
962-
* (if any) ... and those attrs must have equality quals, else
963-
* this one wouldn't be marked required.
946+
* Tuple fails this qual. If it's a required qual for the current
947+
* scan direction, then we can conclude no further tuples will
948+
* pass, either.
964949
*/
965-
if (key->sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD))
950+
if ((key->sk_flags & SK_BT_REQFWD) &&
951+
ScanDirectionIsForward(dir))
952+
*continuescan = false;
953+
else if ((key->sk_flags & SK_BT_REQBKWD) &&
954+
ScanDirectionIsBackward(dir))
966955
*continuescan = false;
967956

968957
/*
@@ -973,15 +962,32 @@ _bt_checkkeys(IndexScanDesc scan,
973962

974963
if (isNull)
975964
{
976-
/*
977-
* The index entry is NULL, so it must fail this qual (we assume
978-
* all btree operators are strict). Furthermore, we know that
979-
* all remaining entries with the same higher-order index attr
980-
* values must be NULLs too. So, just as above, we can stop the
981-
* scan regardless of direction, if the qual is required.
982-
*/
983-
if (key->sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD))
984-
*continuescan = false;
965+
if (key->sk_flags & SK_BT_NULLS_FIRST)
966+
{
967+
/*
968+
* Since NULLs are sorted before non-NULLs, we know we have
969+
* reached the lower limit of the range of values for this
970+
* index attr. On a backward scan, we can stop if this qual
971+
* is one of the "must match" subset. On a forward scan,
972+
* however, we should keep going.
973+
*/
974+
if ((key->sk_flags & SK_BT_REQBKWD) &&
975+
ScanDirectionIsBackward(dir))
976+
*continuescan = false;
977+
}
978+
else
979+
{
980+
/*
981+
* Since NULLs are sorted after non-NULLs, we know we have
982+
* reached the upper limit of the range of values for this
983+
* index attr. On a forward scan, we can stop if this qual is
984+
* one of the "must match" subset. On a backward scan,
985+
* however, we should keep going.
986+
*/
987+
if ((key->sk_flags & SK_BT_REQFWD) &&
988+
ScanDirectionIsForward(dir))
989+
*continuescan = false;
990+
}
985991

986992
/*
987993
* In any case, this indextuple doesn't match the qual.
@@ -1060,15 +1066,32 @@ _bt_check_rowcompare(ScanKey skey, IndexTuple tuple, TupleDesc tupdesc,
10601066

10611067
if (isNull)
10621068
{
1063-
/*
1064-
* The index entry is NULL, so it must fail this qual (we assume
1065-
* all btree operators are strict). Furthermore, we know that
1066-
* all remaining entries with the same higher-order index attr
1067-
* values must be NULLs too. So, just as above, we can stop the
1068-
* scan regardless of direction, if the qual is required.
1069-
*/
1070-
if (subkey->sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD))
1071-
*continuescan = false;
1069+
if (subkey->sk_flags & SK_BT_NULLS_FIRST)
1070+
{
1071+
/*
1072+
* Since NULLs are sorted before non-NULLs, we know we have
1073+
* reached the lower limit of the range of values for this
1074+
* index attr. On a backward scan, we can stop if this qual is
1075+
* one of the "must match" subset. On a forward scan,
1076+
* however, we should keep going.
1077+
*/
1078+
if ((subkey->sk_flags & SK_BT_REQBKWD) &&
1079+
ScanDirectionIsBackward(dir))
1080+
*continuescan = false;
1081+
}
1082+
else
1083+
{
1084+
/*
1085+
* Since NULLs are sorted after non-NULLs, we know we have
1086+
* reached the upper limit of the range of values for this
1087+
* index attr. On a forward scan, we can stop if this qual is
1088+
* one of the "must match" subset. On a backward scan,
1089+
* however, we should keep going.
1090+
*/
1091+
if ((subkey->sk_flags & SK_BT_REQFWD) &&
1092+
ScanDirectionIsForward(dir))
1093+
*continuescan = false;
1094+
}
10721095

10731096
/*
10741097
* In any case, this indextuple doesn't match the qual.

0 commit comments

Comments
 (0)
0