summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/plan_cache_indexability.cpp
diff options
context:
space:
mode:
authorDavid Storch <david.storch@mongodb.com>2020-06-10 14:43:08 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-06-15 21:44:40 +0000
commit80f424c02df47469792917673ab7e6dd77b01421 (patch)
tree20a77cbd4acbedb26b4700f5f646700e795b2677 /src/mongo/db/query/plan_cache_indexability.cpp
parent1261db4a593fe06c5139fc0c9877c406d76b5bb4 (diff)
downloadmongo-80f424c02df47469792917673ab7e6dd77b01421.tar.gz
SERVER-48614 Fix plan cache discriminators for partial wildcard indexes
Previously, discrimination based on the partial filter expression was done for all paths included in the wildcard projection. This could lead to a situation where two queries were erroneously assigned the same plan cache key. The fix is to ensure that for wildcard indexes, partial index discriminators are instead registered only for those paths mentioned in the partial filter expression. Unlike other kinds of wildcard index discriminators (e.g. handling concerns of null equality or collation), the paths in the partial filter expression are known a priori. Therefore, discrimination based on the partial filter can be done in the same way for wildcard and non-wildcard indexes.
Diffstat (limited to 'src/mongo/db/query/plan_cache_indexability.cpp')
-rw-r--r--src/mongo/db/query/plan_cache_indexability.cpp33
1 files changed, 19 insertions, 14 deletions
diff --git a/src/mongo/db/query/plan_cache_indexability.cpp b/src/mongo/db/query/plan_cache_indexability.cpp
index 4846cd85778..216b714dbed 100644
--- a/src/mongo/db/query/plan_cache_indexability.cpp
+++ b/src/mongo/db/query/plan_cache_indexability.cpp
@@ -119,7 +119,7 @@ void PlanCacheIndexabilityState::processWildcardIndex(const CoreIndexInfo& cii)
invariant(cii.type == IndexType::INDEX_WILDCARD);
_wildcardIndexDiscriminators.emplace_back(
- cii.wildcardProjection->exec(), cii.identifier.catalogName, cii.filterExpr, cii.collator);
+ cii.wildcardProjection->exec(), cii.identifier.catalogName, cii.collator);
}
void PlanCacheIndexabilityState::processIndexCollation(const std::string& indexName,
@@ -159,10 +159,6 @@ IndexToDiscriminatorMap PlanCacheIndexabilityState::buildWildcardDiscriminators(
cid.addDiscriminator(QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex);
cid.addDiscriminator(nodeIsConservativelySupportedBySparseIndex);
cid.addDiscriminator(getCollatedIndexDiscriminator(wildcardDiscriminator.collator));
- if (wildcardDiscriminator.filterExpr) {
- cid.addDiscriminator(
- getPartialIndexDiscriminator(wildcardDiscriminator.filterExpr));
- }
}
}
return ret;
@@ -174,19 +170,28 @@ void PlanCacheIndexabilityState::updateDiscriminators(
_wildcardIndexDiscriminators.clear();
for (const auto& idx : indexCores) {
- if (idx.type == IndexType::INDEX_WILDCARD) {
- processWildcardIndex(idx);
- continue;
- }
-
- if (idx.sparse) {
- processSparseIndex(idx.identifier.catalogName, idx.keyPattern);
- }
+ // If necessary, add discriminators for the paths mentioned in the partial filter
+ // expression. Unlike most of the discriminator logic, this is shared for wildcard and
+ // non-wildcard indexes.
if (idx.filterExpr) {
processPartialIndex(idx.identifier.catalogName, idx.filterExpr);
}
- processIndexCollation(idx.identifier.catalogName, idx.keyPattern, idx.collator);
+ if (idx.type == IndexType::INDEX_WILDCARD) {
+ // The set of paths for which we should add disciminators for wildcard indexes (outside
+ // of those paths mentioned in the partial filter expression) is not known a priori.
+ // Instead, we just record some information about the wildcard index so that the
+ // discriminators can be constructed on demand at query runtime.
+ processWildcardIndex(idx);
+ } else {
+ // If the index is not wildcard, add discriminators for fields mentioned in the key
+ // pattern.
+ if (idx.sparse) {
+ processSparseIndex(idx.identifier.catalogName, idx.keyPattern);
+ }
+
+ processIndexCollation(idx.identifier.catalogName, idx.keyPattern, idx.collator);
+ }
}
}