Skip to content

Commit 5ed57cb

Browse files
committed
Fix #8214: Incorrect result of index list scan for a composite index, the second segment of which is a text field with COLLATE UNICODE_CI
1 parent bedf271 commit 5ed57cb

File tree

2 files changed

+10
-13
lines changed

2 files changed

+10
-13
lines changed

src/jrd/btr.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,10 @@ void IndexScanListIterator::makeKeys(thread_db* tdbb, temporary_key* lower, temp
766766
m_upperValues[m_segno] = *m_iterator;
767767

768768
const auto keyType =
769-
(m_retrieval->irb_desc.idx_flags & idx_unique) ? INTL_KEY_UNIQUE : INTL_KEY_SORT;
769+
(m_retrieval->irb_generic & irb_multi_starting) ? INTL_KEY_MULTI_STARTING :
770+
(m_retrieval->irb_generic & irb_starting) ? INTL_KEY_PARTIAL :
771+
(m_retrieval->irb_desc.idx_flags & idx_unique) ? INTL_KEY_UNIQUE :
772+
INTL_KEY_SORT;
770773

771774
// Make the lower bound key
772775

src/jrd/optimizer/Retrieval.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -877,10 +877,6 @@ void Retrieval::getInversionCandidates(InversionCandidateList& inversions,
877877
// We can't use the next segments, and we'll need to use
878878
// INTL_KEY_PARTIAL to construct the last segment's key.
879879
scratch.usePartialKey = true;
880-
881-
// It's currently impossible to use a list scan with INTL_KEY_PARTIAL
882-
if (scanType == segmentScanList)
883-
scanType = segmentScanNone;
884880
}
885881
}
886882

@@ -931,16 +927,14 @@ void Retrieval::getInversionCandidates(InversionCandidateList& inversions,
931927

932928
// An equality scan for any unique index cannot retrieve more
933929
// than one row. The same is true for an equivalence scan for
934-
// any primary index.
935-
const bool single_match =
930+
// any primary index. A missing scan for any primary index is
931+
// known to return no rows, but let's treat it the same way.
932+
const bool uniqueMatch =
936933
(scanType == segmentScanEqual && (idx->idx_flags & idx_unique)) ||
937-
(scanType == segmentScanEquivalent && (idx->idx_flags & idx_primary));
938-
939-
// dimitr: IS NULL scan against primary key is guaranteed
940-
// to return zero rows. Do we need yet another
941-
// special case here?
934+
(scanType == segmentScanEquivalent && (idx->idx_flags & idx_primary)) ||
935+
(scanType == segmentScanMissing && (idx->idx_flags & idx_primary));
942936

943-
if (single_match && ((j + 1) == idx->idx_count))
937+
if (uniqueMatch && ((j + 1) == idx->idx_count))
944938
{
945939
// We have found a full equal matching index and it's unique,
946940
// so we can stop looking further, because this is the best

0 commit comments

Comments
 (0)