diff options
author | Misha Ivkov <misha.ivkov@10gen.com> | 2019-06-11 17:01:16 -0400 |
---|---|---|
committer | Misha Ivkov <misha.ivkov@10gen.com> | 2019-06-11 17:03:12 -0400 |
commit | 95975c0e9c725ef86ef2fe6a8f5372e8a3f219d3 (patch) | |
tree | 43cb52ccc767e3e5e3efb64f4a8ed64f1af4e233 /src/mongo/db | |
parent | 6fd8c8dc3d029c7e69db80bf0a209905e95c5f72 (diff) | |
download | mongo-95975c0e9c725ef86ef2fe6a8f5372e8a3f219d3.tar.gz |
SERVER-40810 give precedence index filter > hint > index on DISTINCT_SCAN
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/query/get_executor.cpp | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp index ab10194ef30..5d82c6bc539 100644 --- a/src/mongo/db/query/get_executor.cpp +++ b/src/mongo/db/query/get_executor.cpp @@ -225,6 +225,27 @@ CoreIndexInfo indexInfoFromIndexCatalogEntry(const IndexCatalogEntry& ice) { projExec}; } +/** + * If query supports index filters, filter params.indices according to any index filters that have + * been configured. In addition, sets that there were indeed index filters applied. + */ +void applyIndexFilters(Collection* collection, + const CanonicalQuery& canonicalQuery, + QueryPlannerParams* plannerParams) { + if (!IDHackStage::supportsQuery(collection, canonicalQuery)) { + QuerySettings* querySettings = collection->infoCache()->getQuerySettings(); + const auto key = canonicalQuery.encodeKey(); + + // Filter index catalog if index filters are specified for query. + // Also, signal to planner that application hint should be ignored. + if (boost::optional<AllowedIndicesFilter> allowedIndicesFilter = + querySettings->getAllowedIndicesFilter(key)) { + filterAllowedIndexEntries(*allowedIndicesFilter, &plannerParams->indices); + plannerParams->indexFiltersApplied = true; + } + } +} + void fillOutPlannerParams(OperationContext* opCtx, Collection* collection, CanonicalQuery* canonicalQuery, @@ -241,18 +262,7 @@ void fillOutPlannerParams(OperationContext* opCtx, // If query supports index filters, filter params.indices by indices in query settings. // Ignore index filters when it is possible to use the id-hack. - if (!IDHackStage::supportsQuery(collection, *canonicalQuery)) { - QuerySettings* querySettings = collection->infoCache()->getQuerySettings(); - const auto key = canonicalQuery->encodeKey(); - - // Filter index catalog if index filters are specified for query. - // Also, signal to planner that application hint should be ignored. - if (boost::optional<AllowedIndicesFilter> allowedIndicesFilter = - querySettings->getAllowedIndicesFilter(key)) { - filterAllowedIndexEntries(*allowedIndicesFilter, &plannerParams->indices); - plannerParams->indexFiltersApplied = true; - } - } + applyIndexFilters(collection, *canonicalQuery, plannerParams); // We will not output collection scans unless there are no indexed solutions. NO_TABLE_SCAN // overrides this behavior by not outputting a collscan even if there are no indexed @@ -1530,6 +1540,20 @@ QueryPlannerParams fillOutPlannerParamsForDistinct(OperationContext* opCtx, } } + const CanonicalQuery* canonicalQuery = parsedDistinct.getQuery(); + const BSONObj& hint = canonicalQuery->getQueryRequest().getHint(); + + applyIndexFilters(collection, *canonicalQuery, &plannerParams); + + // If there exists an index filter, we ignore all hints. Else, we only keep the index specified + // by the hint. Since we cannot have an index with name $natural, that case will clear the + // plannerParams.indices. + if (!plannerParams.indexFiltersApplied && !hint.isEmpty()) { + std::vector<IndexEntry> temp = + QueryPlannerIXSelect::findIndexesByHint(hint, plannerParams.indices); + temp.swap(plannerParams.indices); + } + return plannerParams; } |