summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorMisha Ivkov <misha.ivkov@10gen.com>2019-06-11 17:01:16 -0400
committerMisha Ivkov <misha.ivkov@10gen.com>2019-06-11 17:03:12 -0400
commit95975c0e9c725ef86ef2fe6a8f5372e8a3f219d3 (patch)
tree43cb52ccc767e3e5e3efb64f4a8ed64f1af4e233 /src/mongo/db
parent6fd8c8dc3d029c7e69db80bf0a209905e95c5f72 (diff)
downloadmongo-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.cpp48
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;
}