summaryrefslogtreecommitdiff
path: root/src/mongo/db/matcher/expression_algo_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/matcher/expression_algo_test.cpp')
-rw-r--r--src/mongo/db/matcher/expression_algo_test.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/mongo/db/matcher/expression_algo_test.cpp b/src/mongo/db/matcher/expression_algo_test.cpp
index 8679c759cd5..3e0922bd9fc 100644
--- a/src/mongo/db/matcher/expression_algo_test.cpp
+++ b/src/mongo/db/matcher/expression_algo_test.cpp
@@ -181,6 +181,14 @@ TEST(ExpressionAlgoIsSubsetOf, CompareAnd_GT) {
ASSERT_FALSE(expression::isSubsetOf(filter.get(), query.get()));
}
+TEST(ExpressionAlgoIsSubsetOf, CompareAnd_SingleField) {
+ ParsedMatchExpression filter("{a: {$gt: 5, $lt: 7}}");
+ ParsedMatchExpression query("{a: {$gt: 5, $lt: 6}}");
+
+ ASSERT_TRUE(expression::isSubsetOf(query.get(), filter.get()));
+ ASSERT_FALSE(expression::isSubsetOf(filter.get(), query.get()));
+}
+
TEST(ExpressionAlgoIsSubsetOf, CompareOr_LT) {
ParsedMatchExpression lt5("{a: {$lt: 5}}");
ParsedMatchExpression eq2OrEq3("{$or: [{a: 2}, {a: 3}]}");
@@ -931,6 +939,15 @@ TEST(IsIndependent, NonRenameableExpressionIsNotIndependent) {
}
}
+TEST(IsIndependent, EmptyDependencySetsPassIsOnlyDependentOn) {
+ BSONObj matchPredicate = fromjson("{}");
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto swMatchExpression = MatchExpressionParser::parse(matchPredicate, std::move(expCtx));
+ ASSERT_OK(swMatchExpression.getStatus());
+ auto matchExpression = std::move(swMatchExpression.getValue());
+ ASSERT_TRUE(expression::isOnlyDependentOn(*matchExpression.get(), {}));
+}
+
TEST(SplitMatchExpression, AndWithSplittableChildrenIsSplittable) {
BSONObj matchPredicate = fromjson("{$and: [{a: 1}, {b: 1}]}");
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
@@ -1368,6 +1385,31 @@ TEST(SplitMatchExpression, ShouldMoveIndependentPredicateWhenThereAreMultipleRen
ASSERT_FALSE(splitExpr.second.get());
}
+TEST(SplitMatchExpression, ShouldNotSplitWhenRand) {
+ const auto randExpr = "{$expr: {$lt: [{$rand: {}}, {$const: 0.25}]}}";
+ const auto assertMatchDoesNotSplit = [&](const std::string& exprString) {
+ BSONObj matchPredicate = fromjson(exprString);
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto matcher = MatchExpressionParser::parse(matchPredicate, std::move(expCtx));
+ ASSERT_OK(matcher.getStatus());
+
+ auto&& [split, residual] =
+ expression::splitMatchExpressionBy(std::move(matcher.getValue()), {}, {});
+ ASSERT_FALSE(split.get());
+ ASSERT_TRUE(residual.get());
+
+ BSONObjBuilder oldBob;
+ residual->serialize(&oldBob, true);
+ ASSERT_BSONOBJ_EQ(oldBob.obj(), fromjson(randExpr));
+ };
+
+ // We should not push down a $match with a $rand expression.
+ assertMatchDoesNotSplit(randExpr);
+
+ // This is equivalent to 'randExpr'.
+ assertMatchDoesNotSplit("{$sampleRate: 0.25}");
+}
+
TEST(ApplyRenamesToExpression, ShouldApplyBasicRenamesForAMatchWithExpr) {
BSONObj matchPredicate = fromjson("{$expr: {$eq: ['$a.b', '$c']}}");
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());