diff --git a/src/jrd/btr.cpp b/src/jrd/btr.cpp index 658fa0d7da..fdcc71672b 100644 --- a/src/jrd/btr.cpp +++ b/src/jrd/btr.cpp @@ -766,7 +766,10 @@ void IndexScanListIterator::makeKeys(thread_db* tdbb, temporary_key* lower, temp m_upperValues[m_segno] = *m_iterator; const auto keyType = - (m_retrieval->irb_desc.idx_flags & idx_unique) ? INTL_KEY_UNIQUE : INTL_KEY_SORT; + (m_retrieval->irb_generic & irb_multi_starting) ? INTL_KEY_MULTI_STARTING : + (m_retrieval->irb_generic & irb_starting) ? INTL_KEY_PARTIAL : + (m_retrieval->irb_desc.idx_flags & idx_unique) ? INTL_KEY_UNIQUE : + INTL_KEY_SORT; // Make the lower bound key diff --git a/src/jrd/optimizer/Retrieval.cpp b/src/jrd/optimizer/Retrieval.cpp index 668859e283..a240c4b88d 100644 --- a/src/jrd/optimizer/Retrieval.cpp +++ b/src/jrd/optimizer/Retrieval.cpp @@ -877,10 +877,6 @@ void Retrieval::getInversionCandidates(InversionCandidateList& inversions, // We can't use the next segments, and we'll need to use // INTL_KEY_PARTIAL to construct the last segment's key. scratch.usePartialKey = true; - - // It's currently impossible to use a list scan with INTL_KEY_PARTIAL - if (scanType == segmentScanList) - scanType = segmentScanNone; } } @@ -931,16 +927,14 @@ void Retrieval::getInversionCandidates(InversionCandidateList& inversions, // An equality scan for any unique index cannot retrieve more // than one row. The same is true for an equivalence scan for - // any primary index. - const bool single_match = + // any primary index. A missing scan for any primary index is + // known to return no rows, but let's treat it the same way. + const bool uniqueMatch = (scanType == segmentScanEqual && (idx->idx_flags & idx_unique)) || - (scanType == segmentScanEquivalent && (idx->idx_flags & idx_primary)); + (scanType == segmentScanEquivalent && (idx->idx_flags & idx_primary)) || + (scanType == segmentScanMissing && (idx->idx_flags & idx_primary)); - // dimitr: IS NULL scan against primary key is guaranteed - // to return zero rows. Do we need yet another - // special case here? - - if (single_match && ((j + 1) == idx->idx_count)) + if (uniqueMatch && ((j + 1) == idx->idx_count)) { // We have found a full equal matching index and it's unique, // so we can stop looking further, because this is the best