8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:03:02 +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->matchedSegments = currentInv->matchedSegments;
invCandidate->dependencies = currentInv->dependencies;
matches.clear();
for (const auto currentMatch : currentInv->matches)
{
if (!matches.exist(currentMatch))
matches.add(currentMatch);
if (!invCandidate->matches.exist(currentMatch))
invCandidate->matches.add(currentMatch);
}
if (currentInv->boolean)
if (const auto currentMatch = currentInv->boolean)
{
if (!matches.exist(currentInv->boolean))
matches.add(currentInv->boolean);
if (!invCandidate->matches.exist(currentMatch))
invCandidate->matches.add(currentMatch);
}
invCandidate->matches.join(matches);
matches.assign(invCandidate->matches);
if (customPlan)
continue;
@ -1581,16 +1581,19 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
invCandidate->dependencies = bestCandidate->dependencies;
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]))
matches.add(bestCandidate->matches[j]);
if (!invCandidate->matches.exist(bestMatch))
invCandidate->matches.add(bestMatch);
}
if (bestCandidate->boolean)
if (const auto bestMatch = bestCandidate->boolean)
{
if (!matches.exist(bestCandidate->boolean))
matches.add(bestCandidate->boolean);
if (!invCandidate->matches.exist(bestMatch))
invCandidate->matches.add(bestMatch);
}
matches.join(invCandidate->matches);
}
else if (!bestCandidate->condition)
{
@ -1617,15 +1620,17 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
for (const auto bestMatch : bestCandidate->matches)
{
if (!matches.exist(bestMatch))
matches.add(bestMatch);
if (!invCandidate->matches.exist(bestMatch))
invCandidate->matches.add(bestMatch);
}
if (bestCandidate->boolean)
if (const auto bestMatch = bestCandidate->boolean)
{
if (!matches.exist(bestCandidate->boolean))
matches.add(bestCandidate->boolean);
if (!invCandidate->matches.exist(bestMatch))
invCandidate->matches.add(bestMatch);
}
matches.join(invCandidate->matches);
}
if (invCandidate->unique)
@ -1659,10 +1664,13 @@ InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions)
invCandidate->cost += navigationCandidate->cost;
++invCandidate->indexes;
invCandidate->navigated = true;
}
if (invCandidate)
invCandidate->matches.join(matches);
for (const auto navMatch : navigationCandidate->matches)
{
if (!invCandidate->matches.exist(navMatch))
invCandidate->matches.add(navMatch);
}
}
return invCandidate;
}