aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/nbtree/nbtsearch.c26
-rw-r--r--src/backend/access/nbtree/nbtutils.c14
2 files changed, 24 insertions, 16 deletions
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index 8f559629cd5..472ce06f190 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -1162,23 +1162,23 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (cur->sk_flags & SK_ROW_HEADER)
{
/*
- * Row comparison header: look to the first row member instead.
- *
- * The member scankeys are already in insertion format (ie, they
- * have sk_func = 3-way-comparison function), but we have to watch
- * out for nulls, which _bt_preprocess_keys didn't check. A null
- * in the first row member makes the condition unmatchable, just
- * like qual_ok = false.
+ * Row comparison header: look to the first row member instead
*/
ScanKey subkey = (ScanKey) DatumGetPointer(cur->sk_argument);
+ /*
+ * Cannot be a NULL in the first row member: _bt_preprocess_keys
+ * would've marked the qual as unsatisfiable, preventing us from
+ * ever getting this far
+ */
Assert(subkey->sk_flags & SK_ROW_MEMBER);
- if (subkey->sk_flags & SK_ISNULL)
- {
- Assert(!so->needPrimScan);
- _bt_parallel_done(scan);
- return false;
- }
+ Assert(subkey->sk_attno == cur->sk_attno);
+ Assert(!(subkey->sk_flags & SK_ISNULL));
+
+ /*
+ * The member scankeys are already in insertion format (ie, they
+ * have sk_func = 3-way-comparison function)
+ */
memcpy(inskey.scankeys + i, subkey, sizeof(ScanKeyData));
/*
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 268b7b02acd..00e17a1f0f9 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -3371,6 +3371,13 @@ _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption)
{
ScanKey subkey = (ScanKey) DatumGetPointer(skey->sk_argument);
+ if (subkey->sk_flags & SK_ISNULL)
+ {
+ /* First row member is NULL, so RowCompare is unsatisfiable */
+ Assert(subkey->sk_flags & SK_ROW_MEMBER);
+ return false;
+ }
+
for (;;)
{
Assert(subkey->sk_flags & SK_ROW_MEMBER);
@@ -3982,13 +3989,14 @@ _bt_check_rowcompare(ScanKey skey, IndexTuple tuple, int tupnatts,
if (subkey->sk_flags & SK_ISNULL)
{
/*
- * Unlike the simple-scankey case, this isn't a disallowed case.
+ * Unlike the simple-scankey case, this isn't a disallowed case
+ * (except when it's the first row element that has the NULL arg).
* But it can never match. If all the earlier row comparison
* columns are required for the scan direction, we can stop the
* scan, because there can't be another tuple that will succeed.
*/
- if (subkey != (ScanKey) DatumGetPointer(skey->sk_argument))
- subkey--;
+ Assert(subkey != (ScanKey) DatumGetPointer(skey->sk_argument));
+ subkey--;
if ((subkey->sk_flags & SK_BT_REQFWD) &&
ScanDirectionIsForward(dir))
*continuescan = false;