@@ -609,7 +609,7 @@ _bt_advance_array_keys(IndexScanDesc scan, ScanDirection dir)
609
609
* so that the index sorts in the desired direction.
610
610
*
611
611
* One key purpose of this routine is to discover which scan keys must be
612
- * satisfied to continue the scan. It also attempts to eliminate redundant
612
+ * satisfied to continue the scan. It also attempts to eliminate redundant
613
613
* keys and detect contradictory keys. (If the index opfamily provides
614
614
* incomplete sets of cross-type operators, we may fail to detect redundant
615
615
* or contradictory keys, but we can survive that.)
@@ -647,15 +647,18 @@ _bt_advance_array_keys(IndexScanDesc scan, ScanDirection dir)
647
647
* </<= keys if we can't compare them. The logic about required keys still
648
648
* works if we don't eliminate redundant keys.
649
649
*
650
- * Note that the reason we need direction-sensitive required-key flags is
650
+ * Note that one reason we need direction-sensitive required-key flags is
651
651
* precisely that we may not be able to eliminate redundant keys. Suppose
652
652
* we have "x > 4::int AND x > 10::bigint", and we are unable to determine
653
653
* which key is more restrictive for lack of a suitable cross-type operator.
654
654
* _bt_first will arbitrarily pick one of the keys to do the initial
655
655
* positioning with. If it picks x > 4, then the x > 10 condition will fail
656
656
* until we reach index entries > 10; but we can't stop the scan just because
657
657
* x > 10 is failing. On the other hand, if we are scanning backwards, then
658
- * failure of either key is indeed enough to stop the scan.
658
+ * failure of either key is indeed enough to stop the scan. (In general, when
659
+ * inequality keys are present, the initial-positioning code only promises to
660
+ * position before the first possible match, not exactly at the first match,
661
+ * for a forward scan; or after the last match for a backward scan.)
659
662
*
660
663
* As a byproduct of this work, we can detect contradictory quals such
661
664
* as "x = 1 AND x > 2". If we see that, we return so->qual_ok = FALSE,
@@ -1394,16 +1397,15 @@ _bt_checkkeys(IndexScanDesc scan,
1394
1397
}
1395
1398
1396
1399
/*
1397
- * Tuple fails this qual. If it's a required qual, then we can
1398
- * conclude no further tuples will pass, either. We can stop
1399
- * regardless of the scan direction, because we know that NULLs
1400
- * sort to one end or the other of the range of values. If this
1401
- * tuple doesn't pass, then no future ones will either, until we
1402
- * reach the next set of values of the higher-order index attrs
1403
- * (if any) ... and those attrs must have equality quals, else
1404
- * this one wouldn't be marked required.
1400
+ * Tuple fails this qual. If it's a required qual for the current
1401
+ * scan direction, then we can conclude no further tuples will
1402
+ * pass, either.
1405
1403
*/
1406
- if (key -> sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD ))
1404
+ if ((key -> sk_flags & SK_BT_REQFWD ) &&
1405
+ ScanDirectionIsForward (dir ))
1406
+ * continuescan = false;
1407
+ else if ((key -> sk_flags & SK_BT_REQBKWD ) &&
1408
+ ScanDirectionIsBackward (dir ))
1407
1409
* continuescan = false;
1408
1410
1409
1411
/*
@@ -1414,15 +1416,38 @@ _bt_checkkeys(IndexScanDesc scan,
1414
1416
1415
1417
if (isNull )
1416
1418
{
1417
- /*
1418
- * The index entry is NULL, so it must fail this qual (we assume
1419
- * all btree operators are strict). Furthermore, we know that
1420
- * all remaining entries with the same higher-order index attr
1421
- * values must be NULLs too. So, just as above, we can stop the
1422
- * scan regardless of direction, if the qual is required.
1423
- */
1424
- if (key -> sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD ))
1425
- * continuescan = false;
1419
+ if (key -> sk_flags & SK_BT_NULLS_FIRST )
1420
+ {
1421
+ /*
1422
+ * Since NULLs are sorted before non-NULLs, we know we have
1423
+ * reached the lower limit of the range of values for this
1424
+ * index attr. On a backward scan, we can stop if this qual
1425
+ * is one of the "must match" subset. We can stop regardless
1426
+ * of whether the qual is > or <, so long as it's required,
1427
+ * because it's not possible for any future tuples to pass.
1428
+ * On a forward scan, however, we must keep going, because we
1429
+ * may have initially positioned to the start of the index.
1430
+ */
1431
+ if ((key -> sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD )) &&
1432
+ ScanDirectionIsBackward (dir ))
1433
+ * continuescan = false;
1434
+ }
1435
+ else
1436
+ {
1437
+ /*
1438
+ * Since NULLs are sorted after non-NULLs, we know we have
1439
+ * reached the upper limit of the range of values for this
1440
+ * index attr. On a forward scan, we can stop if this qual is
1441
+ * one of the "must match" subset. We can stop regardless of
1442
+ * whether the qual is > or <, so long as it's required,
1443
+ * because it's not possible for any future tuples to pass.
1444
+ * On a backward scan, however, we must keep going, because we
1445
+ * may have initially positioned to the end of the index.
1446
+ */
1447
+ if ((key -> sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD )) &&
1448
+ ScanDirectionIsForward (dir ))
1449
+ * continuescan = false;
1450
+ }
1426
1451
1427
1452
/*
1428
1453
* In any case, this indextuple doesn't match the qual.
@@ -1502,15 +1527,38 @@ _bt_check_rowcompare(ScanKey skey, IndexTuple tuple, TupleDesc tupdesc,
1502
1527
1503
1528
if (isNull )
1504
1529
{
1505
- /*
1506
- * The index entry is NULL, so it must fail this qual (we assume
1507
- * all btree operators are strict). Furthermore, we know that
1508
- * all remaining entries with the same higher-order index attr
1509
- * values must be NULLs too. So, just as above, we can stop the
1510
- * scan regardless of direction, if the qual is required.
1511
- */
1512
- if (subkey -> sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD ))
1513
- * continuescan = false;
1530
+ if (subkey -> sk_flags & SK_BT_NULLS_FIRST )
1531
+ {
1532
+ /*
1533
+ * Since NULLs are sorted before non-NULLs, we know we have
1534
+ * reached the lower limit of the range of values for this
1535
+ * index attr. On a backward scan, we can stop if this qual
1536
+ * is one of the "must match" subset. We can stop regardless
1537
+ * of whether the qual is > or <, so long as it's required,
1538
+ * because it's not possible for any future tuples to pass.
1539
+ * On a forward scan, however, we must keep going, because we
1540
+ * may have initially positioned to the start of the index.
1541
+ */
1542
+ if ((subkey -> sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD )) &&
1543
+ ScanDirectionIsBackward (dir ))
1544
+ * continuescan = false;
1545
+ }
1546
+ else
1547
+ {
1548
+ /*
1549
+ * Since NULLs are sorted after non-NULLs, we know we have
1550
+ * reached the upper limit of the range of values for this
1551
+ * index attr. On a forward scan, we can stop if this qual is
1552
+ * one of the "must match" subset. We can stop regardless of
1553
+ * whether the qual is > or <, so long as it's required,
1554
+ * because it's not possible for any future tuples to pass.
1555
+ * On a backward scan, however, we must keep going, because we
1556
+ * may have initially positioned to the end of the index.
1557
+ */
1558
+ if ((subkey -> sk_flags & (SK_BT_REQFWD | SK_BT_REQBKWD )) &&
1559
+ ScanDirectionIsForward (dir ))
1560
+ * continuescan = false;
1561
+ }
1514
1562
1515
1563
/*
1516
1564
* In any case, this indextuple doesn't match the qual.
0 commit comments