diff options
author | David Storch <david.storch@mongodb.com> | 2020-06-10 14:43:08 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-06-15 21:44:40 +0000 |
commit | 80f424c02df47469792917673ab7e6dd77b01421 (patch) | |
tree | 20a77cbd4acbedb26b4700f5f646700e795b2677 /src/mongo/db/query/plan_cache_indexability.cpp | |
parent | 1261db4a593fe06c5139fc0c9877c406d76b5bb4 (diff) | |
download | mongo-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.cpp | 33 |
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); + } } } |