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.
|
// when an index on `x` is available.
|
||||||
assertContainsEof({x: {$in: []}});
|
assertContainsEof({x: {$in: []}});
|
||||||
assertContainsEof({x: {$in: []}, y: {$gt: 9}});
|
assertContainsEof({x: {$in: []}, y: {$gt: 9}});
|
||||||
|
assertContainsEof({x: {$elemMatch: {y: {$in: []}}}});
|
||||||
// No relevant index should still produce an EOF plan.
|
// No relevant index should still produce an EOF plan.
|
||||||
assertContainsEof({y: {$in: []}});
|
assertContainsEof({y: {$in: []}});
|
||||||
// Hinting an index should allow EOF plan generation.
|
// Hinting an index should allow EOF plan generation.
|
||||||
|
|
|
||||||
|
|
@ -115,13 +115,17 @@ void ElemMatchObjectMatchExpression::appendSerializedRightHandSide(BSONObjBuilde
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchExpression::ExpressionOptimizerFunc ElemMatchObjectMatchExpression::getOptimizer() const {
|
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);
|
auto& elemExpression = static_cast<ElemMatchObjectMatchExpression&>(*expression);
|
||||||
// The Boolean simplifier is disabled since we don't want to simplify sub-expressions, but
|
// The Boolean simplifier is disabled since we don't want to simplify sub-expressions, but
|
||||||
// simplify the whole expression instead.
|
// simplify the whole expression instead.
|
||||||
elemExpression._sub = MatchExpression::optimize(std::move(elemExpression._sub),
|
elemExpression._sub = MatchExpression::optimize(std::move(elemExpression._sub),
|
||||||
/* enableSimplification */ false);
|
/* enableSimplification */ false);
|
||||||
|
|
||||||
|
if (elemExpression._sub->isTriviallyFalse()) {
|
||||||
|
return std::make_unique<AlwaysFalseMatchExpression>();
|
||||||
|
}
|
||||||
|
|
||||||
return expression;
|
return expression;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -551,6 +551,27 @@ TEST(ExpressionOptimizeTest, EmptyInOptimizesToAlwaysFalse) {
|
||||||
ASSERT_BSONOBJ_EQ(optimizedMatchExpression->serialize(), fromjson("{$alwaysFalse: 1}"));
|
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) {
|
TEST(ExpressionOptimizeTest, InWithJustRegexesIsNotOptimizedToAlwaysFalse) {
|
||||||
BSONObj obj = fromjson("{x: {$in: [/foo/, /bar/]}}");
|
BSONObj obj = fromjson("{x: {$in: [/foo/, /bar/]}}");
|
||||||
std::unique_ptr<MatchExpression> matchExpression(parseMatchExpression(obj));
|
std::unique_ptr<MatchExpression> matchExpression(parseMatchExpression(obj));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue