Found by code inspection.
planner_access.h handleRIDRangeScan() calls itself recursively on the branches of AndMatchExpressions, but in setting the output value of collScan->hasCompatibleCollation it neglects to consider the recursions, so the value from whichever recursion happened last is the final value.
The recursions should each have a chance to conjunctively falsify it, i.e. updates should be something like
collScan->hasCompatibleCollation = collScan->hasCompatibleCollation && allEltsCollationCompatible;
but instead the first occurrence of this updates it incorrectly (introduced in 7.0.0-rc0 by SERVER-67105 commit https://github.com/mongodb/mongo/commit/9f391ea93fa62f57d6b4576130283d98eec69456 and subsequently backported to 6.0.6):
collScan->hasCompatibleCollation = allEltsCollationCompatible;
and toward the bottom of the function (which is not always reached) there is another incorrect update (introduced in 6.0.0-rc0 by SERVER-60824 commit https://github.com/10gen/mongo/commit/8e4d331e8c20eff3ed50e3d6bb7a1b4a58aa1c16):
// Even if the collations don't match at this point, it's fine, // because the bounds exclude values that use it collScan->hasCompatibleCollation = true;
The fix might be to change the first existing update to use && as I suggested above and delete the second existing update, but this suggestion needs validation from a QO expert.
I confirmed with hana.pearlman@mongodb.com that the current code is incorrect.
- is caused by
-
SERVER-67105 $in queries do not use clustered index
- Closed