summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/plan_cache_indexability_test.cpp
diff options
context:
space:
mode:
authorNicholas Zolnierz <nicholas.zolnierz@mongodb.com>2023-02-13 16:34:03 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-02-16 19:20:30 +0000
commitf92c25b160937a960a4bedc066ebcfe20dd35d09 (patch)
treebcfc6a5dad17c21232f890f16f9ef99595c4bbed /src/mongo/db/query/plan_cache_indexability_test.cpp
parent5e4ec1d24431fcdd28b579a024c5c801b8cde4e2 (diff)
downloadmongo-v4.2.tar.gz
SERVER-68434 Fix plan cache key encoding to account for $or in partial index expressionv4.2
(cherry picked from commit f15f2bf8958557b4e8fccc6e8e1c7c8c5834d209) (cherry picked from commit d19b8c60309c3a660a968ae8cf074aef92e1266d) (cherry picked from commit 65dc21eabcdc2bbf952418b6d4988a199c980d43)
Diffstat (limited to 'src/mongo/db/query/plan_cache_indexability_test.cpp')
-rw-r--r--src/mongo/db/query/plan_cache_indexability_test.cpp148
1 files changed, 93 insertions, 55 deletions
diff --git a/src/mongo/db/query/plan_cache_indexability_test.cpp b/src/mongo/db/query/plan_cache_indexability_test.cpp
index 6b4b2b367c3..ae464339f7a 100644
--- a/src/mongo/db/query/plan_cache_indexability_test.cpp
+++ b/src/mongo/db/query/plan_cache_indexability_test.cpp
@@ -92,7 +92,7 @@ TEST(PlanCacheIndexabilityTest, SparseIndexSimple) {
nullptr,
nullptr)});
- auto discriminators = state.getDiscriminators("a");
+ auto discriminators = state.getPathDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1") != discriminators.end());
@@ -133,7 +133,7 @@ TEST(PlanCacheIndexabilityTest, SparseIndexCompound) {
nullptr)});
{
- auto discriminators = state.getDiscriminators("a");
+ auto discriminators = state.getPathDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1_b_1") != discriminators.end());
@@ -146,7 +146,7 @@ TEST(PlanCacheIndexabilityTest, SparseIndexCompound) {
}
{
- auto discriminators = state.getDiscriminators("b");
+ auto discriminators = state.getPathDiscriminators("b");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1_b_1") != discriminators.end());
@@ -179,12 +179,17 @@ TEST(PlanCacheIndexabilityTest, PartialIndexSimple) {
nullptr,
nullptr)});
+ // The partial index is represented as a global discriminator that applies to the entire
+ // incoming MatchExpression.
{
- auto discriminators = state.getDiscriminators("f");
- ASSERT_EQ(1U, discriminators.size());
- ASSERT(discriminators.find("a_1") != discriminators.end());
+ auto discriminators = state.getPathDiscriminators("f");
+ ASSERT_EQ(0U, discriminators.size());
- auto disc = discriminators["a_1"];
+ auto globalDiscriminators = state.getGlobalDiscriminators();
+ ASSERT_EQ(1U, globalDiscriminators.size());
+ ASSERT(globalDiscriminators.find("a_1") != globalDiscriminators.end());
+
+ auto disc = globalDiscriminators["a_1"];
ASSERT_EQ(false,
disc.isMatchCompatibleWithIndex(
parseMatchExpression(BSON("f" << BSON("$gt" << -5))).get()));
@@ -194,7 +199,7 @@ TEST(PlanCacheIndexabilityTest, PartialIndexSimple) {
}
{
- auto discriminators = state.getDiscriminators("a");
+ auto discriminators = state.getPathDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1") != discriminators.end());
@@ -228,32 +233,52 @@ TEST(PlanCacheIndexabilityTest, PartialIndexAnd) {
nullptr,
nullptr)});
+ // partial index discriminators are global to the entire query, so an individual path should not
+ // have any discriminators. Also the entire query must be a subset of the partial filter
+ // expression, not just the leaves.
+ auto globalDiscriminators = state.getGlobalDiscriminators();
+ ASSERT(globalDiscriminators.find("a_1") != globalDiscriminators.end());
+ auto globalDisc = globalDiscriminators["a_1"];
+
{
- auto discriminators = state.getDiscriminators("f");
- ASSERT_EQ(1U, discriminators.size());
- ASSERT(discriminators.find("a_1") != discriminators.end());
+ auto discriminators = state.getPathDiscriminators("f");
+ ASSERT_EQ(0U, discriminators.size());
- auto disc = discriminators["a_1"];
- ASSERT_EQ(false,
- disc.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 0)).get()));
- ASSERT_EQ(true,
- disc.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 1)).get()));
+ ASSERT_EQ(
+ false,
+ globalDisc.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 0)).get()));
+ ASSERT_EQ(
+ false,
+ globalDisc.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 1)).get()));
}
{
- auto discriminators = state.getDiscriminators("g");
- ASSERT_EQ(1U, discriminators.size());
- ASSERT(discriminators.find("a_1") != discriminators.end());
+ auto discriminators = state.getPathDiscriminators("g");
+ ASSERT_EQ(0U, discriminators.size());
- auto disc = discriminators["a_1"];
+ ASSERT_EQ(
+ false,
+ globalDisc.isMatchCompatibleWithIndex(parseMatchExpression(BSON("g" << 0)).get()));
+ ASSERT_EQ(
+ false,
+ globalDisc.isMatchCompatibleWithIndex(parseMatchExpression(BSON("g" << 1)).get()));
+ }
+
+ {
+ // A match expression which is covered entirely by the partial filter should pass the global
+ // discriminator.
ASSERT_EQ(false,
- disc.isMatchCompatibleWithIndex(parseMatchExpression(BSON("g" << 0)).get()));
+ globalDisc.isMatchCompatibleWithIndex(
+ parseMatchExpression(BSON("g" << 1 << "f" << 0)).get()));
ASSERT_EQ(true,
- disc.isMatchCompatibleWithIndex(parseMatchExpression(BSON("g" << 1)).get()));
+ globalDisc.isMatchCompatibleWithIndex(
+ parseMatchExpression(BSON("g" << 1 << "f" << 1)).get()));
}
{
- auto discriminators = state.getDiscriminators("a");
+ // The path 'a' will still have a discriminator for the collation (even though it's
+ // defaulted).
+ auto discriminators = state.getPathDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1") != discriminators.end());
@@ -302,33 +327,44 @@ TEST(PlanCacheIndexabilityTest, MultiplePartialIndexes) {
nullptr,
nullptr)});
- {
- auto discriminators = state.getDiscriminators("f");
- ASSERT_EQ(2U, discriminators.size());
- ASSERT(discriminators.find("a_1") != discriminators.end());
- ASSERT(discriminators.find("b_1") != discriminators.end());
+ // partial index discriminators are global to the entire query, so an individual path within the
+ // partial filter should not have any discriminators. Also the entire query must be a subset of
+ // the partial filter expression, not just the leaves.
+ auto globalDiscriminators = state.getGlobalDiscriminators();
+ ASSERT(globalDiscriminators.find("a_1") != globalDiscriminators.end());
+ ASSERT(globalDiscriminators.find("b_1") != globalDiscriminators.end());
+ auto globalDiscA = globalDiscriminators["a_1"];
+ auto globalDiscB = globalDiscriminators["b_1"];
- auto discA = discriminators["a_1"];
- auto discB = discriminators["b_1"];
+ {
+ auto discriminators = state.getPathDiscriminators("f");
+ ASSERT_EQ(0U, discriminators.size());
- ASSERT_EQ(false,
- discA.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 0)).get()));
- ASSERT_EQ(false,
- discB.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 0)).get()));
+ ASSERT_EQ(
+ false,
+ globalDiscA.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 0)).get()));
+ ASSERT_EQ(
+ false,
+ globalDiscB.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 0)).get()));
- ASSERT_EQ(true,
- discA.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 1)).get()));
- ASSERT_EQ(false,
- discB.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 1)).get()));
+ ASSERT_EQ(
+ true,
+ globalDiscA.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 1)).get()));
+ ASSERT_EQ(
+ false,
+ globalDiscB.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 1)).get()));
- ASSERT_EQ(false,
- discA.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 2)).get()));
- ASSERT_EQ(true,
- discB.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 2)).get()));
+ ASSERT_EQ(
+ false,
+ globalDiscA.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 2)).get()));
+ ASSERT_EQ(
+ true,
+ globalDiscB.isMatchCompatibleWithIndex(parseMatchExpression(BSON("f" << 2)).get()));
}
+ // The paths 'a' and 'b' will have one discriminator each to capture the collation of the index.
{
- auto discriminators = state.getDiscriminators("a");
+ auto discriminators = state.getPathDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1") != discriminators.end());
@@ -342,7 +378,7 @@ TEST(PlanCacheIndexabilityTest, MultiplePartialIndexes) {
}
{
- auto discriminators = state.getDiscriminators("b");
+ auto discriminators = state.getPathDiscriminators("b");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("b_1") != discriminators.end());
@@ -374,7 +410,7 @@ TEST(PlanCacheIndexabilityTest, IndexNeitherSparseNorPartial) {
BSONObj(),
nullptr,
nullptr)});
- auto discriminators = state.getDiscriminators("a");
+ auto discriminators = state.getPathDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1") != discriminators.end());
}
@@ -399,7 +435,7 @@ TEST(PlanCacheIndexabilityTest, DiscriminatorForCollationIndicatesWhenCollations
entry.collator = &collator;
state.updateDiscriminators({entry});
- auto discriminators = state.getDiscriminators("a");
+ auto discriminators = state.getPathDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1") != discriminators.end());
@@ -484,11 +520,11 @@ TEST(PlanCacheIndexabilityTest, CompoundIndexCollationDiscriminator) {
nullptr,
nullptr)});
- auto discriminatorsA = state.getDiscriminators("a");
+ auto discriminatorsA = state.getPathDiscriminators("a");
ASSERT_EQ(1U, discriminatorsA.size());
ASSERT(discriminatorsA.find("a_1_b_1") != discriminatorsA.end());
- auto discriminatorsB = state.getDiscriminators("b");
+ auto discriminatorsB = state.getPathDiscriminators("b");
ASSERT_EQ(1U, discriminatorsB.size());
ASSERT(discriminatorsB.find("a_1_b_1") != discriminatorsB.end());
}
@@ -593,13 +629,15 @@ TEST(PlanCacheIndexabilityTest, WildcardPartialIndexDiscriminator) {
ASSERT_TRUE(wildcardDiscriminators.isMatchCompatibleWithIndex(
parseMatchExpression(fromjson("{b: 6}")).get()));
- // The regular (non-wildcard) set of discriminators for the path "a" should reflect whether a
- // predicate on "a" is compatible with the partial filter expression.
+ // The global discriminator for the index "indexName" should reflect whether a MatchExpression
+ // is compatible with the partial filter expression.
{
- discriminatorsA = state.getDiscriminators("a");
- auto discriminatorsIt = discriminatorsA.find("indexName");
- ASSERT(discriminatorsIt != discriminatorsA.end());
- auto disc = discriminatorsIt->second;
+ discriminatorsA = state.getPathDiscriminators("a");
+ ASSERT(discriminatorsA.find("indexName") == discriminatorsA.end());
+
+ auto globalDisc = state.getGlobalDiscriminators();
+ ASSERT(globalDisc.find("indexName") != globalDisc.end());
+ auto disc = globalDisc["indexName"];
ASSERT_FALSE(
disc.isMatchCompatibleWithIndex(parseMatchExpression(fromjson("{a: 0}")).get()));
@@ -614,7 +652,7 @@ TEST(PlanCacheIndexabilityTest, WildcardPartialIndexDiscriminator) {
// There shouldn't be any regular discriminators associated with path "b".
{
- auto&& discriminatorsB = state.getDiscriminators("b");
+ auto&& discriminatorsB = state.getPathDiscriminators("b");
ASSERT_FALSE(discriminatorsB.count("indexName"));
}
}