mirror of https://github.com/mongodb/mongo
SERVER-105375 Rewrite obj elemMatch trivially false expressions as alwaysFalse (#36934)
GitOrigin-RevId: dbac78ce6307a45ebc873397486b9323838f6ede
This commit is contained in:
parent
a25a91f17a
commit
3369f76f50
|
|
@ -74,6 +74,7 @@ assertContainsIndexScan({x: {$in: [2]}}, {hint: {x: 1}});
|
|||
// when an index on `x` is available.
|
||||
assertContainsEof({x: {$in: []}});
|
||||
assertContainsEof({x: {$in: []}, y: {$gt: 9}});
|
||||
assertContainsEof({x: {$elemMatch: {y: {$in: []}}}});
|
||||
// No relevant index should still produce an EOF plan.
|
||||
assertContainsEof({y: {$in: []}});
|
||||
// Hinting an index should allow EOF plan generation.
|
||||
|
|
|
|||
|
|
@ -115,13 +115,17 @@ void ElemMatchObjectMatchExpression::appendSerializedRightHandSide(BSONObjBuilde
|
|||
}
|
||||
|
||||
MatchExpression::ExpressionOptimizerFunc ElemMatchObjectMatchExpression::getOptimizer() const {
|
||||
return [](std::unique_ptr<MatchExpression> expression) {
|
||||
return [](std::unique_ptr<MatchExpression> expression) -> std::unique_ptr<MatchExpression> {
|
||||
auto& elemExpression = static_cast<ElemMatchObjectMatchExpression&>(*expression);
|
||||
// The Boolean simplifier is disabled since we don't want to simplify sub-expressions, but
|
||||
// simplify the whole expression instead.
|
||||
elemExpression._sub = MatchExpression::optimize(std::move(elemExpression._sub),
|
||||
/* enableSimplification */ false);
|
||||
|
||||
if (elemExpression._sub->isTriviallyFalse()) {
|
||||
return std::make_unique<AlwaysFalseMatchExpression>();
|
||||
}
|
||||
|
||||
return expression;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -551,6 +551,27 @@ TEST(ExpressionOptimizeTest, EmptyInOptimizesToAlwaysFalse) {
|
|||
ASSERT_BSONOBJ_EQ(optimizedMatchExpression->serialize(), fromjson("{$alwaysFalse: 1}"));
|
||||
}
|
||||
|
||||
TEST(ExpressionOptimizeTest, EmptyInWithinElemMatchExpressionOptimizesToAlwaysFalse) {
|
||||
BSONObj obj = fromjson("{x: {$elemMatch: {y: {$in: []}}}}");
|
||||
std::unique_ptr<MatchExpression> matchExpression(parseMatchExpression(obj));
|
||||
auto optimizedMatchExpression = MatchExpression::optimize(std::move(matchExpression));
|
||||
ASSERT_BSONOBJ_EQ(optimizedMatchExpression->serialize(), fromjson("{$alwaysFalse: 1}"));
|
||||
}
|
||||
|
||||
TEST(ExpressionOptimizeTest, DoubleEmptyInWithinElemMatchExpressionOptimizesToAlwaysFalse) {
|
||||
BSONObj obj = fromjson("{x: {$elemMatch: {y: {$in: []}, z: {$in: []}}}}");
|
||||
std::unique_ptr<MatchExpression> matchExpression(parseMatchExpression(obj));
|
||||
auto optimizedMatchExpression = MatchExpression::optimize(std::move(matchExpression));
|
||||
ASSERT_BSONOBJ_EQ(optimizedMatchExpression->serialize(), fromjson("{$alwaysFalse: 1}"));
|
||||
}
|
||||
|
||||
TEST(ExpressionOptimizeTest, EmptyInAndSmthElseWithinElemMatchExpressionOptimizesToAlwaysFalse) {
|
||||
BSONObj obj = fromjson("{x: {$elemMatch: {y: {$in: []}, z: 1}}}");
|
||||
std::unique_ptr<MatchExpression> matchExpression(parseMatchExpression(obj));
|
||||
auto optimizedMatchExpression = MatchExpression::optimize(std::move(matchExpression));
|
||||
ASSERT_BSONOBJ_EQ(optimizedMatchExpression->serialize(), fromjson("{$alwaysFalse: 1}"));
|
||||
}
|
||||
|
||||
TEST(ExpressionOptimizeTest, InWithJustRegexesIsNotOptimizedToAlwaysFalse) {
|
||||
BSONObj obj = fromjson("{x: {$in: [/foo/, /bar/]}}");
|
||||
std::unique_ptr<MatchExpression> matchExpression(parseMatchExpression(obj));
|
||||
|
|
|
|||
Loading…
Reference in New Issue