_bt_check_compare neglected to handle a case that can arise when the
scan's keys are temporarily treated as nonrequired, as an optimization:
whenever a NULL tuple value was encountered that had a skip array whose
current element wasn't already NULL, _bt_check_compare failed to advance
the array to the NULL element. This allowed _bt_check_compare to fail
to return matching tuples containing a NULL value (though only with an
array column that came before a skip array column with NULLs, and only
during _bt_readpage calls that set pstate.forcenonrequired=true on a
page where the higher-order column also had to advance).
To fix, teach _bt_check_compare to handle this case just like any other
case where a skip array key is unsatisfied and must be advanced directly
(due to the key being considered a nonrequired key).
Oversight in commit
8a510275, which optimized nbtree search scan key
comparisons with skip arrays.
Author: Peter Geoghegan <pg@bowt.ie>
Reported-By: Mark Dilger <mark.dilger@enterprisedb.com>
Discussion: https://postgr.es/m/CAHgHdKtLFWZcjr87hMH0hYDHgcifu4Tj7iHz-xh8qsJREt5cqA@mail.gmail.com
if (isNull)
{
+ /*
+ * Scalar scan key isn't satisfied by NULL tuple value.
+ *
+ * If we're treating scan keys as nonrequired, and key is for a
+ * skip array, then we must attempt to advance the array to NULL
+ * (if we're successful then the tuple might match the qual).
+ */
+ if (unlikely(forcenonrequired && key->sk_flags & SK_BT_SKIP))
+ return _bt_advance_array_keys(scan, NULL, tuple, tupnatts,
+ tupdesc, *ikey, false);
+
if (key->sk_flags & SK_BT_NULLS_FIRST)
{
/*
}
/*
- * In any case, this indextuple doesn't match the qual.
+ * This indextuple doesn't match the qual.
*/
return false;
}