summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/plan_cache_key_info_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/query/plan_cache_key_info_test.cpp')
-rw-r--r--src/mongo/db/query/plan_cache_key_info_test.cpp133
1 files changed, 16 insertions, 117 deletions
diff --git a/src/mongo/db/query/plan_cache_key_info_test.cpp b/src/mongo/db/query/plan_cache_key_info_test.cpp
index a13616e12c4..7235386e7f4 100644
--- a/src/mongo/db/query/plan_cache_key_info_test.cpp
+++ b/src/mongo/db/query/plan_cache_key_info_test.cpp
@@ -194,107 +194,6 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyPartialIndex) {
makeKey(*cqGtZero, indexCores));
}
-TEST(PlanCacheKeyInfoTest, ComputeKeyPartialIndexConjunction) {
- BSONObj filterObj = fromjson("{f: {$gt: 0, $lt: 10}}");
- unique_ptr<MatchExpression> filterExpr(parseMatchExpression(filterObj));
-
- const auto keyPattern = BSON("a" << 1);
- const std::vector<CoreIndexInfo> indexCores = {
- CoreIndexInfo(keyPattern,
- IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
- false, // sparse
- IndexEntry::Identifier{""}, // name
- filterExpr.get())}; // filterExpr
-
- unique_ptr<CanonicalQuery> satisfySinglePredicate(canonicalize("{f: {$gt: 0}}"));
- ASSERT_EQ(makeKey(*satisfySinglePredicate, indexCores).getIndexabilityDiscriminators(), "(0)");
-
- unique_ptr<CanonicalQuery> satisfyBothPredicates(canonicalize("{f: {$eq: 5}}"));
- ASSERT_EQ(makeKey(*satisfyBothPredicates, indexCores).getIndexabilityDiscriminators(), "(1)");
-
- unique_ptr<CanonicalQuery> conjSingleField(canonicalize("{f: {$gt: 2, $lt: 9}}"));
- ASSERT_EQ(makeKey(*conjSingleField, indexCores).getIndexabilityDiscriminators(), "(1)");
-
- unique_ptr<CanonicalQuery> conjSingleFieldNoMatch(canonicalize("{f: {$gt: 2, $lt: 11}}"));
- ASSERT_EQ(makeKey(*conjSingleFieldNoMatch, indexCores).getIndexabilityDiscriminators(), "(0)");
-
- // Note that these queries get optimized to a single $in over 'f'.
- unique_ptr<CanonicalQuery> disjSingleFieldBothSatisfy(
- canonicalize("{$or: [{f: {$eq: 2}}, {f: {$eq: 3}}]}"));
- ASSERT_EQ(makeKey(*disjSingleFieldBothSatisfy, indexCores).getIndexabilityDiscriminators(),
- "(1)");
-
- unique_ptr<CanonicalQuery> disjSingleFieldNotSubset(
- canonicalize("{$or: [{f: {$eq: 2}}, {f: {$eq: 11}}]}"));
- ASSERT_EQ(makeKey(*disjSingleFieldNotSubset, indexCores).getIndexabilityDiscriminators(),
- "(0)");
-}
-
-TEST(PlanCacheKeyInfoTest, ComputeKeyPartialIndexDisjunction) {
- BSONObj filterObj = fromjson("{$or: [{f: {$gt: 10}}, {f: {$lt: 0}}]}");
- unique_ptr<MatchExpression> filterExpr(parseMatchExpression(filterObj));
-
- const auto keyPattern = BSON("a" << 1);
- const std::vector<CoreIndexInfo> indexCores = {
- CoreIndexInfo(keyPattern,
- IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
- false, // sparse
- IndexEntry::Identifier{""}, // name
- filterExpr.get())}; // filterExpr
-
- unique_ptr<CanonicalQuery> satisfySinglePredicate(canonicalize("{f: {$eq: 11}}"));
- ASSERT_EQ(makeKey(*satisfySinglePredicate, indexCores).getIndexabilityDiscriminators(), "(1)");
-
- unique_ptr<CanonicalQuery> satisfyNeither(canonicalize("{f: {$eq: 5}}"));
- ASSERT_EQ(makeKey(*satisfyNeither, indexCores).getIndexabilityDiscriminators(), "(0)");
-
- unique_ptr<CanonicalQuery> conjSingleFieldMatch(canonicalize("{f: {$lt: 20, $gt: 10}}"));
- ASSERT_EQ(makeKey(*conjSingleFieldMatch, indexCores).getIndexabilityDiscriminators(), "(1)");
-
- unique_ptr<CanonicalQuery> conjSingleFieldNoMatch(canonicalize("{f: {$gt: 2, $lt: 10}}"));
- ASSERT_EQ(makeKey(*conjSingleFieldNoMatch, indexCores).getIndexabilityDiscriminators(), "(0)");
-
- unique_ptr<CanonicalQuery> conjSingleFieldOverlap(canonicalize("{f: {$gt: 2, $lt: 12}}"));
- ASSERT_EQ(makeKey(*conjSingleFieldOverlap, indexCores).getIndexabilityDiscriminators(), "(0)");
-
- // Although this query is technically a subset of the partial filter, the logic to determine
- // such ('isSubsetOf' in the code) is conservative in how it compares certain shapes of
- // expression trees.
- unique_ptr<CanonicalQuery> disjSingleFieldBothSatisfy(
- canonicalize("{$or: [{f: {$eq: -1}}, {f: {$gt: 10}}]}"));
- ASSERT_EQ(makeKey(*disjSingleFieldBothSatisfy, indexCores).getIndexabilityDiscriminators(),
- "(0)");
-
- unique_ptr<CanonicalQuery> disjSingleFieldNotSubset(
- canonicalize("{$or: [{f: {$eq: 2}}, {f: {$eq: 11}}]}"));
- ASSERT_EQ(makeKey(*disjSingleFieldNotSubset, indexCores).getIndexabilityDiscriminators(),
- "(0)");
-}
-
-TEST(PlanCacheKeyInfoTest, ComputeKeyPartialIndexNestedDisjunction) {
- BSONObj filterObj = fromjson(R"(
- {$and: [
- {$or: [{f: {$gt: 10}}, {f: {$lt: 0}}]},
- {$or: [{f: {$gt: 11}}, {f: {$lt: 1}}]}
- ]})");
- unique_ptr<MatchExpression> filterExpr(parseMatchExpression(filterObj));
-
- const auto keyPattern = BSON("a" << 1);
- const std::vector<CoreIndexInfo> indexCores = {
- CoreIndexInfo(keyPattern,
- IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
- false, // sparse
- IndexEntry::Identifier{""}, // name
- filterExpr.get())}; // filterExpr
-
-
- unique_ptr<CanonicalQuery> satisfySinglePredicate(canonicalize("{f: {$eq: 11}}"));
- ASSERT_EQ(makeKey(*satisfySinglePredicate, indexCores).getIndexabilityDiscriminators(), "(0)");
-
- unique_ptr<CanonicalQuery> notCompat(canonicalize("{f: {$eq: 12}}"));
- ASSERT_EQ(makeKey(*notCompat, indexCores).getIndexabilityDiscriminators(), "(1)");
-}
-
// Query shapes should get the same plan cache key if they have the same collation indexability.
TEST(PlanCacheKeyInfoTest, ComputeKeyCollationIndex) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
@@ -467,8 +366,8 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyWildcardDiscriminatesCorrectlyBasedOnPartia
// The discriminator strings have the format "<xx>". That is, there are two discriminator
// bits for the "x" predicate, the first pertaining to the partialFilterExpression and the
// second around applicability to the wildcard index.
- ASSERT_EQ(compatibleKey.getIndexabilityDiscriminators(), "(1)<1>");
- ASSERT_EQ(incompatibleKey.getIndexabilityDiscriminators(), "(0)<1>");
+ ASSERT_EQ(compatibleKey.getIndexabilityDiscriminators(), "<11>");
+ ASSERT_EQ(incompatibleKey.getIndexabilityDiscriminators(), "<01>");
}
// The partialFilterExpression should lead to a discriminator over field 'x', but not over 'y'.
@@ -483,8 +382,8 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyWildcardDiscriminatesCorrectlyBasedOnPartia
// The discriminator strings have the format "<xx><y>". That is, there are two discriminator
// bits for the "x" predicate (the first pertaining to the partialFilterExpression, the
// second around applicability to the wildcard index) and one discriminator bit for "y".
- ASSERT_EQ(compatibleKey.getIndexabilityDiscriminators(), "(1)<1><1>");
- ASSERT_EQ(incompatibleKey.getIndexabilityDiscriminators(), "(0)<1><1>");
+ ASSERT_EQ(compatibleKey.getIndexabilityDiscriminators(), "<11><1>");
+ ASSERT_EQ(incompatibleKey.getIndexabilityDiscriminators(), "<01><1>");
}
// $eq:null predicates cannot be assigned to a wildcard index. Make sure that this is
@@ -499,8 +398,8 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyWildcardDiscriminatesCorrectlyBasedOnPartia
// The discriminator strings have the format "<xx><y>". That is, there are two discriminator
// bits for the "x" predicate (the first pertaining to the partialFilterExpression, the
// second around applicability to the wildcard index) and one discriminator bit for "y".
- ASSERT_EQ(compatibleKey.getIndexabilityDiscriminators(), "(1)<1><1>");
- ASSERT_EQ(incompatibleKey.getIndexabilityDiscriminators(), "(1)<1><0>");
+ ASSERT_EQ(compatibleKey.getIndexabilityDiscriminators(), "<11><1>");
+ ASSERT_EQ(incompatibleKey.getIndexabilityDiscriminators(), "<11><0>");
}
// Test that the discriminators are correct for an $eq:null predicate on 'x'. This predicate is
@@ -509,7 +408,7 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyWildcardDiscriminatesCorrectlyBasedOnPartia
// result in two "0" bits inside the discriminator string.
{
auto key = makeKey(*canonicalize("{x: {$eq: null}}"), indexCores);
- ASSERT_EQ(key.getIndexabilityDiscriminators(), "(0)<0>");
+ ASSERT_EQ(key.getIndexabilityDiscriminators(), "<00>");
}
}
@@ -550,11 +449,11 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyWildcardDiscriminatesCorrectlyWithPartialFi
const std::vector<CoreIndexInfo> indexCores = {indexInfo};
{
- // TODO update The discriminators should have the format <xx><yy><z>. The 'z' predicate has
- // just one discriminator because it is not referenced in the partial filter expression. All
+ // The discriminators should have the format <xx><yy><z>. The 'z' predicate has just one
+ // discriminator because it is not referenced in the partial filter expression. All
// predicates are compatible.
auto key = makeKey(*canonicalize("{x: {$eq: 1}, y: {$eq: 2}, z: {$eq: 3}}"), indexCores);
- ASSERT_EQ(key.getIndexabilityDiscriminators(), "(1)<1><1><1>");
+ ASSERT_EQ(key.getIndexabilityDiscriminators(), "<11><11><1>");
}
{
@@ -562,7 +461,7 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyWildcardDiscriminatesCorrectlyWithPartialFi
// compatible with the partial filter expression, leading to one of the 'y' bits being set
// to zero.
auto key = makeKey(*canonicalize("{x: {$eq: 1}, y: {$eq: -2}, z: {$eq: 3}}"), indexCores);
- ASSERT_EQ(key.getIndexabilityDiscriminators(), "(0)<1><1><1>");
+ ASSERT_EQ(key.getIndexabilityDiscriminators(), "<11><01><1>");
}
}
@@ -581,20 +480,20 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyDiscriminatesCorrectlyWithPartialFilterAndW
// the predicate is compatible with the partial filter expression, whereas the disciminator
// for 'y' is about compatibility with the wildcard index.
auto key = makeKey(*canonicalize("{x: {$eq: 1}, y: {$eq: 2}, z: {$eq: 3}}"), indexCores);
- ASSERT_EQ(key.getIndexabilityDiscriminators(), "(1)<1>");
+ ASSERT_EQ(key.getIndexabilityDiscriminators(), "<1><1>");
}
{
// Similar to the previous case, except with an 'x' predicate that is incompatible with the
// partial filter expression.
auto key = makeKey(*canonicalize("{x: {$eq: -1}, y: {$eq: 2}, z: {$eq: 3}}"), indexCores);
- ASSERT_EQ(key.getIndexabilityDiscriminators(), "(0)<1>");
+ ASSERT_EQ(key.getIndexabilityDiscriminators(), "<0><1>");
}
{
// Case where the 'y' predicate is not compatible with the wildcard index.
auto key = makeKey(*canonicalize("{x: {$eq: 1}, y: {$eq: null}, z: {$eq: 3}}"), indexCores);
- ASSERT_EQ(key.getIndexabilityDiscriminators(), "(1)<0>");
+ ASSERT_EQ(key.getIndexabilityDiscriminators(), "<1><0>");
}
}
@@ -612,14 +511,14 @@ TEST(PlanCacheKeyInfoTest, ComputeKeyWildcardDiscriminatesCorrectlyWithPartialFi
// The discriminators have the format <x><(x.y)(x.y)<y>. All predicates are compatible
auto key =
makeKey(*canonicalize("{x: {$eq: 1}, y: {$eq: 2}, 'x.y': {$eq: 3}}"), indexCores);
- ASSERT_EQ(key.getIndexabilityDiscriminators(), "(1)<1><1><1>");
+ ASSERT_EQ(key.getIndexabilityDiscriminators(), "<1><11><1>");
}
{
// Here, the predicate on "x.y" is not compatible with the partial filter expression.
auto key =
makeKey(*canonicalize("{x: {$eq: 1}, y: {$eq: 2}, 'x.y': {$eq: -3}}"), indexCores);
- ASSERT_EQ(key.getIndexabilityDiscriminators(), "(0)<1><1><1>");
+ ASSERT_EQ(key.getIndexabilityDiscriminators(), "<1><01><1>");
}
}