8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 22:43:03 +01:00

Do not add fakely used (ignored but unmatched) conjuncts to the inversion match list. This should fix #8379: Incorrect cardinality estimation for retrievals with multiple compound indices having common set of fields.

This commit is contained in:
Dmitry Yemanov 2025-01-09 14:39:19 +03:00
parent 89a88b7f93
commit 6c0d61be29

View File

@ -1393,21 +1393,21 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
invCandidate->nonFullMatchedSegments = 0; invCandidate->nonFullMatchedSegments = 0;
invCandidate->matchedSegments = currentInv->matchedSegments; invCandidate->matchedSegments = currentInv->matchedSegments;
invCandidate->dependencies = currentInv->dependencies; invCandidate->dependencies = currentInv->dependencies;
matches.clear();
for (const auto currentMatch : currentInv->matches) for (const auto currentMatch : currentInv->matches)
{ {
if (!matches.exist(currentMatch)) if (!invCandidate->matches.exist(currentMatch))
matches.add(currentMatch); invCandidate->matches.add(currentMatch);
} }
if (currentInv->boolean) if (const auto currentMatch = currentInv->boolean)
{ {
if (!matches.exist(currentInv->boolean)) if (!invCandidate->matches.exist(currentMatch))
matches.add(currentInv->boolean); invCandidate->matches.add(currentMatch);
} }
invCandidate->matches.join(matches); matches.assign(invCandidate->matches);
if (customPlan) if (customPlan)
continue; continue;
@ -1581,16 +1581,19 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
invCandidate->dependencies = bestCandidate->dependencies; invCandidate->dependencies = bestCandidate->dependencies;
invCandidate->condition = bestCandidate->condition; invCandidate->condition = bestCandidate->condition;
for (FB_SIZE_T j = 0; j < bestCandidate->matches.getCount(); j++) for (const auto bestMatch : bestCandidate->matches)
{ {
if (!matches.exist(bestCandidate->matches[j])) if (!invCandidate->matches.exist(bestMatch))
matches.add(bestCandidate->matches[j]); invCandidate->matches.add(bestMatch);
} }
if (bestCandidate->boolean)
if (const auto bestMatch = bestCandidate->boolean)
{ {
if (!matches.exist(bestCandidate->boolean)) if (!invCandidate->matches.exist(bestMatch))
matches.add(bestCandidate->boolean); invCandidate->matches.add(bestMatch);
} }
matches.join(invCandidate->matches);
} }
else if (!bestCandidate->condition) else if (!bestCandidate->condition)
{ {
@ -1617,15 +1620,17 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
for (const auto bestMatch : bestCandidate->matches) for (const auto bestMatch : bestCandidate->matches)
{ {
if (!matches.exist(bestMatch)) if (!invCandidate->matches.exist(bestMatch))
matches.add(bestMatch); invCandidate->matches.add(bestMatch);
} }
if (bestCandidate->boolean) if (const auto bestMatch = bestCandidate->boolean)
{ {
if (!matches.exist(bestCandidate->boolean)) if (!invCandidate->matches.exist(bestMatch))
matches.add(bestCandidate->boolean); invCandidate->matches.add(bestMatch);
} }
matches.join(invCandidate->matches);
} }
if (invCandidate->unique) if (invCandidate->unique)
@ -1659,10 +1664,13 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
invCandidate->cost += navigationCandidate->cost; invCandidate->cost += navigationCandidate->cost;
++invCandidate->indexes; ++invCandidate->indexes;
invCandidate->navigated = true; invCandidate->navigated = true;
}
if (invCandidate) for (const auto navMatch : navigationCandidate->matches)
invCandidate->matches.join(matches); {
if (!invCandidate->matches.exist(navMatch))
invCandidate->matches.add(navMatch);
}
}
return invCandidate; return invCandidate;
} }