8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 09:20:39 +01:00

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

This commit is contained in:
Dmitry Yemanov 2025-01-13 21:46:22 +03:00
parent 5167c588a4
commit 91dce62553

View File

@ -1494,8 +1494,11 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
return invCandidate; return invCandidate;
} }
// Look if a match is already used by previous matches. if (!customPlan)
{
// Look if a match is already used by previous matches
bool anyMatchAlreadyUsed = false, matchUsedByNavigation = false; bool anyMatchAlreadyUsed = false, matchUsedByNavigation = false;
for (const auto currentMatch : currentInv->matches) for (const auto currentMatch : currentInv->matches)
{ {
if (matches.exist(currentMatch)) if (matches.exist(currentMatch))
@ -1512,28 +1515,49 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
} }
} }
if (currentInv->boolean && matches.exist(currentInv->boolean)) if (const auto currentMatch = currentInv->boolean)
{
if (matches.exist(currentMatch))
{
anyMatchAlreadyUsed = true; anyMatchAlreadyUsed = true;
if (anyMatchAlreadyUsed && !customPlan) if (navigationCandidate &&
navigationCandidate->matches.exist(currentMatch))
{ {
currentInv->used = true; matchUsedByNavigation = true;
}
}
else if (matchUsedByNavigation)
anyMatchAlreadyUsed = false;
}
if (matchUsedByNavigation) // If some match was already used by another index, skip this index
continue;
if (anyMatchAlreadyUsed)
{
if (!matchUsedByNavigation)
{
// Add the other matches from this index
// 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) for (const auto currentMatch : currentInv->matches)
{ {
if (!matches.exist(currentMatch)) if (!matches.exist(currentMatch))
matches.add(currentMatch); matches.add(currentMatch);
} }
// Restart loop, because other indexes could also be excluded now. 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; restartLoop = true;
break; break;
} }
}
if (!bestCandidate) if (!bestCandidate)
{ {