diff options
Diffstat (limited to 'src/backend/access')
-rw-r--r-- | src/backend/access/nbtree/nbtsearch.c | 26 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtutils.c | 14 |
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; |