From 91dce62553a0c74fea4c033110f0091f8e128f55 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Mon, 13 Jan 2025 21:46:22 +0300 Subject: [PATCH] Rework fix for #5751 (Available indices are not used in some cases if ORDER BY expression is a filtered one) and also attempt to fix the special case for OR conditions partially matched to an index --- src/jrd/optimizer/Retrieval.cpp | 90 +++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/src/jrd/optimizer/Retrieval.cpp b/src/jrd/optimizer/Retrieval.cpp index e909182359..5ecacf746e 100644 --- a/src/jrd/optimizer/Retrieval.cpp +++ b/src/jrd/optimizer/Retrieval.cpp @@ -1494,45 +1494,69 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions) return invCandidate; } - // Look if a match is already used by previous matches. - bool anyMatchAlreadyUsed = false, matchUsedByNavigation = false; - for (const auto currentMatch : currentInv->matches) + if (!customPlan) { - if (matches.exist(currentMatch)) - { - anyMatchAlreadyUsed = true; + // Look if a match is already used by previous matches + bool anyMatchAlreadyUsed = false, matchUsedByNavigation = false; - if (navigationCandidate && - navigationCandidate->matches.exist(currentMatch)) - { - matchUsedByNavigation = true; - } - - break; - } - } - - if (currentInv->boolean && matches.exist(currentInv->boolean)) - anyMatchAlreadyUsed = true; - - if (anyMatchAlreadyUsed && !customPlan) - { - currentInv->used = true; - - if (matchUsedByNavigation) - continue; - - // If a match on this index was already used by another - // index, add also the other matches from this index. for (const auto currentMatch : currentInv->matches) { - if (!matches.exist(currentMatch)) - matches.add(currentMatch); + if (matches.exist(currentMatch)) + { + anyMatchAlreadyUsed = true; + + if (navigationCandidate && + navigationCandidate->matches.exist(currentMatch)) + { + matchUsedByNavigation = true; + } + + break; + } } - // Restart loop, because other indexes could also be excluded now. - restartLoop = true; - break; + if (const auto currentMatch = currentInv->boolean) + { + if (matches.exist(currentMatch)) + { + anyMatchAlreadyUsed = true; + + if (navigationCandidate && + navigationCandidate->matches.exist(currentMatch)) + { + matchUsedByNavigation = true; + } + } + else if (matchUsedByNavigation) + anyMatchAlreadyUsed = false; + } + + // If some match was already used by another index, skip this index + + if (anyMatchAlreadyUsed) + { + if (!matchUsedByNavigation) + { + // Add the other matches from this index + + for (const auto currentMatch : currentInv->matches) + { + if (!matches.exist(currentMatch)) + matches.add(currentMatch); + } + + if (const auto currentMatch = currentInv->boolean) + { + if (!matches.exist(currentMatch)) + matches.add(currentMatch); + } + } + + // Restart loop, because other indexes could also be excluded now + currentInv->used = true; + restartLoop = true; + break; + } } if (!bestCandidate)