diff options
author | Ruoxin Xu <ruoxin.xu@mongodb.com> | 2021-09-24 13:43:15 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-09-24 14:23:54 +0000 |
commit | 634867703b7eb40f073198d27633a7c5506e4604 (patch) | |
tree | 70a161bc3cb70f3f3fca99dc64f4e179320df8e2 /src/mongo/dbtests | |
parent | c607f9b63f4764335749ae40a5762d6a305558c1 (diff) | |
download | mongo-634867703b7eb40f073198d27633a7c5506e4604.tar.gz |
SERVER-59854 Remove PlanCacheIndexabilityState from the PlanCache
This patch includes a number of changes to facilitate the use of PlanCacheIndexabilityState with SBE and classic plan cache keys.
* Introduced a plan cache key factory.
* Moved PlanCacheIndexabilityState from the PlanCache into CollectionQueryInfo.
* Templetized QueryPlanner::planSubqueries() so it can be used with classic and SBE plan caches.
* Removed dependency on the CanonicalQuery from the PlanCache class.
Co-authored-by: Anton Korshunov <anton.korshunov@mongodb.com>
Diffstat (limited to 'src/mongo/dbtests')
-rw-r--r-- | src/mongo/dbtests/cursor_manager_test.cpp | 1 | ||||
-rw-r--r-- | src/mongo/dbtests/plan_executor_invalidation_test.cpp | 1 | ||||
-rw-r--r-- | src/mongo/dbtests/plan_ranking.cpp | 3 | ||||
-rw-r--r-- | src/mongo/dbtests/query_plan_executor.cpp | 1 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_cached_plan.cpp | 61 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_collscan.cpp | 1 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_merge_sort.cpp | 1 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_multiplan.cpp | 16 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_sort.cpp | 1 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_tests.cpp | 1 |
10 files changed, 57 insertions, 30 deletions
diff --git a/src/mongo/dbtests/cursor_manager_test.cpp b/src/mongo/dbtests/cursor_manager_test.cpp index ff15eade6e4..1cc8ee1f535 100644 --- a/src/mongo/dbtests/cursor_manager_test.cpp +++ b/src/mongo/dbtests/cursor_manager_test.cpp @@ -44,6 +44,7 @@ #include "mongo/db/exec/working_set_common.h" #include "mongo/db/operation_context.h" #include "mongo/db/query/plan_executor_factory.h" +#include "mongo/db/query/query_planner_params.h" #include "mongo/db/query/query_test_service_context.h" #include "mongo/db/repl/read_concern_level.h" #include "mongo/dbtests/dbtests.h" diff --git a/src/mongo/dbtests/plan_executor_invalidation_test.cpp b/src/mongo/dbtests/plan_executor_invalidation_test.cpp index db2845569d4..a383f25c99b 100644 --- a/src/mongo/dbtests/plan_executor_invalidation_test.cpp +++ b/src/mongo/dbtests/plan_executor_invalidation_test.cpp @@ -43,6 +43,7 @@ #include "mongo/db/matcher/expression_parser.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/query/plan_executor_factory.h" +#include "mongo/db/query/query_planner_params.h" #include "mongo/db/service_context.h" #include "mongo/dbtests/dbtests.h" #include "mongo/unittest/unittest.h" diff --git a/src/mongo/dbtests/plan_ranking.cpp b/src/mongo/dbtests/plan_ranking.cpp index 70d94736a0b..71fcee970c6 100644 --- a/src/mongo/dbtests/plan_ranking.cpp +++ b/src/mongo/dbtests/plan_ranking.cpp @@ -250,7 +250,8 @@ public: StatusWith<std::unique_ptr<PlanCacheEntry>> planCacheEntryWithStatus = CollectionQueryInfo::get(collection.getCollection()) .getPlanCache() - ->getEntry(*(cq.get())); + ->getEntry( + plan_cache_key_factory::make<PlanCacheKey>(*cq, collection.getCollection())); ASSERT_OK(planCacheEntryWithStatus.getStatus()); auto debugInfo = planCacheEntryWithStatus.getValue()->debugInfo; ASSERT(debugInfo); diff --git a/src/mongo/dbtests/query_plan_executor.cpp b/src/mongo/dbtests/query_plan_executor.cpp index 10b316de975..5842a3634ce 100644 --- a/src/mongo/dbtests/query_plan_executor.cpp +++ b/src/mongo/dbtests/query_plan_executor.cpp @@ -52,6 +52,7 @@ #include "mongo/db/pipeline/pipeline.h" #include "mongo/db/pipeline/plan_executor_pipeline.h" #include "mongo/db/query/plan_executor_factory.h" +#include "mongo/db/query/query_planner_params.h" #include "mongo/db/query/query_solution.h" #include "mongo/dbtests/dbtests.h" diff --git a/src/mongo/dbtests/query_stage_cached_plan.cpp b/src/mongo/dbtests/query_stage_cached_plan.cpp index abfcddb97d9..d3cf8bd8a63 100644 --- a/src/mongo/dbtests/query_stage_cached_plan.cpp +++ b/src/mongo/dbtests/query_stage_cached_plan.cpp @@ -48,6 +48,7 @@ #include "mongo/db/query/get_executor.h" #include "mongo/db/query/mock_yield_policies.h" #include "mongo/db/query/plan_cache.h" +#include "mongo/db/query/plan_cache_key_factory.h" #include "mongo/db/query/query_knobs_gen.h" #include "mongo/db/query/query_planner_params.h" #include "mongo/dbtests/dbtests.h" @@ -192,11 +193,12 @@ TEST_F(QueryStageCachedPlan, QueryStageCachedPlanFailureMemoryLimitExceeded) { auto statusWithCQ = CanonicalQuery::canonicalize(opCtx(), std::move(findCommand)); ASSERT_OK(statusWithCQ.getStatus()); const std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); + auto key = plan_cache_key_factory::make<PlanCacheKey>(*cq, collection.getCollection()); // We shouldn't have anything in the plan cache for this shape yet. PlanCache* cache = CollectionQueryInfo::get(collection.getCollection()).getPlanCache(); ASSERT(cache); - ASSERT_EQ(cache->get(*cq).state, PlanCache::CacheEntryState::kNotPresent); + ASSERT_EQ(cache->get(key).state, PlanCache::CacheEntryState::kNotPresent); // Get planner params. QueryPlannerParams plannerParams; @@ -225,7 +227,7 @@ TEST_F(QueryStageCachedPlan, QueryStageCachedPlanFailureMemoryLimitExceeded) { // Plan cache should still be empty, as we don't write to it when we replan a failed // query. - ASSERT_EQ(cache->get(*cq).state, PlanCache::CacheEntryState::kNotPresent); + ASSERT_EQ(cache->get(key).state, PlanCache::CacheEntryState::kNotPresent); } /** @@ -242,11 +244,12 @@ TEST_F(QueryStageCachedPlan, QueryStageCachedPlanHitMaxWorks) { auto statusWithCQ = CanonicalQuery::canonicalize(opCtx(), std::move(findCommand)); ASSERT_OK(statusWithCQ.getStatus()); const std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); + auto key = plan_cache_key_factory::make<PlanCacheKey>(*cq, collection.getCollection()); // We shouldn't have anything in the plan cache for this shape yet. PlanCache* cache = CollectionQueryInfo::get(collection.getCollection()).getPlanCache(); ASSERT(cache); - ASSERT_EQ(cache->get(*cq).state, PlanCache::CacheEntryState::kNotPresent); + ASSERT_EQ(cache->get(key).state, PlanCache::CacheEntryState::kNotPresent); // Get planner params. QueryPlannerParams plannerParams; @@ -278,7 +281,7 @@ TEST_F(QueryStageCachedPlan, QueryStageCachedPlanHitMaxWorks) { // This time we expect to find something in the plan cache. Replans after hitting the // works threshold result in a cache entry. - ASSERT_EQ(cache->get(*cq).state, PlanCache::CacheEntryState::kPresentInactive); + ASSERT_EQ(cache->get(key).state, PlanCache::CacheEntryState::kPresentInactive); } /** @@ -292,6 +295,8 @@ TEST_F(QueryStageCachedPlan, QueryStageCachedPlanAddsActiveCacheEntries) { // CanonicalQueries created in this test will have this shape. const auto shapeCq = canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 123}, b: {$gte: 123}}")); + auto planCacheKey = + plan_cache_key_factory::make<PlanCacheKey>(*shapeCq, collection.getCollection()); // Query can be answered by either index on "a" or index on "b". const auto noResultsCq = @@ -300,17 +305,17 @@ TEST_F(QueryStageCachedPlan, QueryStageCachedPlanAddsActiveCacheEntries) { // We shouldn't have anything in the plan cache for this shape yet. PlanCache* cache = CollectionQueryInfo::get(collection.getCollection()).getPlanCache(); ASSERT(cache); - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kNotPresent); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kNotPresent); // Run the CachedPlanStage with a long-running child plan. Replanning should be // triggered and an inactive entry will be added. forceReplanning(collection.getCollection(), noResultsCq.get()); // Check for an inactive cache entry. - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentInactive); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kPresentInactive); // The works should be 1 for the entry since the query we ran should not have any results. - auto entry = assertGet(cache->getEntry(*shapeCq)); + auto entry = assertGet(cache->getEntry(planCacheKey)); size_t works = 1U; ASSERT_EQ(entry->works, works); @@ -323,9 +328,9 @@ TEST_F(QueryStageCachedPlan, QueryStageCachedPlanAddsActiveCacheEntries) { canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 1}, b: {$gte: 0}}")); forceReplanning(collection.getCollection(), someResultsCq.get()); - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentInactive); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kPresentInactive); // The works on the cache entry should have doubled. - entry = assertGet(cache->getEntry(*shapeCq)); + entry = assertGet(cache->getEntry(planCacheKey)); ASSERT_EQ(entry->works, works); } @@ -335,8 +340,8 @@ TEST_F(QueryStageCachedPlan, QueryStageCachedPlanAddsActiveCacheEntries) { forceReplanning(collection.getCollection(), fewResultsCq.get()); // Now there should be an active cache entry. - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentActive); - entry = assertGet(cache->getEntry(*shapeCq)); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kPresentActive); + entry = assertGet(cache->getEntry(planCacheKey)); // This will query will match {a: 6} through {a:9} (4 works), plus one for EOF = 5 works. ASSERT_EQ(entry->works, 5U); } @@ -350,6 +355,8 @@ TEST_F(QueryStageCachedPlan, DeactivatesEntriesOnReplan) { // CanonicalQueries created in this test will have this shape. const auto shapeCq = canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 123}, b: {$gte: 123}}")); + auto planCacheKey = + plan_cache_key_factory::make<PlanCacheKey>(*shapeCq, collection.getCollection()); // Query can be answered by either index on "a" or index on "b". const auto noResultsCq = @@ -358,21 +365,25 @@ TEST_F(QueryStageCachedPlan, DeactivatesEntriesOnReplan) { // We shouldn't have anything in the plan cache for this shape yet. PlanCache* cache = CollectionQueryInfo::get(collection.getCollection()).getPlanCache(); ASSERT(cache); - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kNotPresent); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kNotPresent); // Run the CachedPlanStage with a long-running child plan. Replanning should be // triggered and an inactive entry will be added. forceReplanning(collection.getCollection(), noResultsCq.get()); // Check for an inactive cache entry. - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentInactive); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kPresentInactive); // Run the plan again, to create an active entry. forceReplanning(collection.getCollection(), noResultsCq.get()); // The works should be 1 for the entry since the query we ran should not have any results. - ASSERT_EQ(cache->get(*noResultsCq.get()).state, PlanCache::CacheEntryState::kPresentActive); - auto entry = assertGet(cache->getEntry(*shapeCq)); + ASSERT_EQ(cache + ->get(plan_cache_key_factory::make<PlanCacheKey>(*noResultsCq, + collection.getCollection())) + .state, + PlanCache::CacheEntryState::kPresentActive); + auto entry = assertGet(cache->getEntry(planCacheKey)); size_t works = 1U; ASSERT_EQ(entry->works, works); @@ -384,16 +395,16 @@ TEST_F(QueryStageCachedPlan, DeactivatesEntriesOnReplan) { auto highWorksCq = canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 0}, b: {$gte:0}}")); forceReplanning(collection.getCollection(), highWorksCq.get()); - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentInactive); - ASSERT_EQ(assertGet(cache->getEntry(*shapeCq))->works, 2U); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kPresentInactive); + ASSERT_EQ(assertGet(cache->getEntry(planCacheKey))->works, 2U); // Again, force replanning. This time run the initial query which finds no results. The multi // planner will choose a plan with works value lower than the existing inactive // entry. Replanning will thus deactivate the existing entry (it's already // inactive so this is a noop), then create a new entry with a works value of 1. forceReplanning(collection.getCollection(), noResultsCq.get()); - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentActive); - ASSERT_EQ(assertGet(cache->getEntry(*shapeCq))->works, 1U); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kPresentActive); + ASSERT_EQ(assertGet(cache->getEntry(planCacheKey))->works, 1U); } TEST_F(QueryStageCachedPlan, EntriesAreNotDeactivatedWhenInactiveEntriesDisabled) { @@ -408,33 +419,37 @@ TEST_F(QueryStageCachedPlan, EntriesAreNotDeactivatedWhenInactiveEntriesDisabled // CanonicalQueries created in this test will have this shape. const auto shapeCq = canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 123}, b: {$gte: 123}}")); + auto planCacheKey = + plan_cache_key_factory::make<PlanCacheKey>(*shapeCq, collection.getCollection()); // Query can be answered by either index on "a" or index on "b". const auto noResultsCq = canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 11}, b: {$gte: 11}}")); + auto noResultKey = + plan_cache_key_factory::make<PlanCacheKey>(*noResultsCq, collection.getCollection()); // We shouldn't have anything in the plan cache for this shape yet. PlanCache* cache = CollectionQueryInfo::get(collection.getCollection()).getPlanCache(); ASSERT(cache); - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kNotPresent); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kNotPresent); // Run the CachedPlanStage with a long-running child plan. Replanning should be // triggered and an _active_ entry will be added (since the disableInactiveEntries flag is on). forceReplanning(collection.getCollection(), noResultsCq.get()); // Check for an inactive cache entry. - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentActive); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kPresentActive); // Run the plan again. The entry should still be active. forceReplanning(collection.getCollection(), noResultsCq.get()); - ASSERT_EQ(cache->get(*noResultsCq.get()).state, PlanCache::CacheEntryState::kPresentActive); + ASSERT_EQ(cache->get(noResultKey).state, PlanCache::CacheEntryState::kPresentActive); // Run another query which takes long enough to evict the active cache entry. After replanning // is triggered, be sure that the the cache entry is still active. auto highWorksCq = canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 0}, b: {$gte:0}}")); forceReplanning(collection.getCollection(), highWorksCq.get()); - ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentActive); + ASSERT_EQ(cache->get(planCacheKey).state, PlanCache::CacheEntryState::kPresentActive); } TEST_F(QueryStageCachedPlan, ThrowsOnYieldRecoveryWhenIndexIsDroppedBeforePlanSelection) { diff --git a/src/mongo/dbtests/query_stage_collscan.cpp b/src/mongo/dbtests/query_stage_collscan.cpp index 4fafd1fc46e..5094317fd33 100644 --- a/src/mongo/dbtests/query_stage_collscan.cpp +++ b/src/mongo/dbtests/query_stage_collscan.cpp @@ -48,6 +48,7 @@ #include "mongo/db/matcher/expression_parser.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/plan_executor_factory.h" +#include "mongo/db/query/query_planner_params.h" #include "mongo/db/record_id_helpers.h" #include "mongo/db/storage/record_store.h" #include "mongo/dbtests/dbtests.h" diff --git a/src/mongo/dbtests/query_stage_merge_sort.cpp b/src/mongo/dbtests/query_stage_merge_sort.cpp index 76d144add9d..5988d327f3b 100644 --- a/src/mongo/dbtests/query_stage_merge_sort.cpp +++ b/src/mongo/dbtests/query_stage_merge_sort.cpp @@ -46,6 +46,7 @@ #include "mongo/db/json.h" #include "mongo/db/query/collation/collator_interface_mock.h" #include "mongo/db/query/plan_executor_factory.h" +#include "mongo/db/query/query_planner_params.h" #include "mongo/dbtests/dbtests.h" /** diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp index 8160787f241..a2682723b63 100644 --- a/src/mongo/dbtests/query_stage_multiplan.cpp +++ b/src/mongo/dbtests/query_stage_multiplan.cpp @@ -49,6 +49,7 @@ #include "mongo/db/query/collection_query_info.h" #include "mongo/db/query/get_executor.h" #include "mongo/db/query/mock_yield_policies.h" +#include "mongo/db/query/plan_cache_key_factory.h" #include "mongo/db/query/plan_executor_factory.h" #include "mongo/db/query/plan_executor_impl.h" #include "mongo/db/query/plan_summary_stats.h" @@ -298,6 +299,7 @@ TEST_F(QueryStageMultiPlanTest, MPSDoesNotCreateActiveCacheEntryImmediately) { const CollectionPtr& coll = ctx.getCollection(); const auto cq = makeCanonicalQuery(_opCtx.get(), nss, BSON("foo" << 7)); + auto key = plan_cache_key_factory::make<PlanCacheKey>(*cq, coll); // Run an index scan and collection scan, searching for {foo: 7}. auto mps = runMultiPlanner(_expCtx.get(), nss, coll, 7); @@ -305,7 +307,7 @@ TEST_F(QueryStageMultiPlanTest, MPSDoesNotCreateActiveCacheEntryImmediately) { // Be sure that an inactive cache entry was added. PlanCache* cache = CollectionQueryInfo::get(coll).getPlanCache(); ASSERT_EQ(cache->size(), 1U); - auto entry = assertGet(cache->getEntry(*cq)); + auto entry = assertGet(cache->getEntry(key)); ASSERT_FALSE(entry->isActive); const size_t firstQueryWorks = getBestPlanWorks(mps.get()); ASSERT_EQ(firstQueryWorks, entry->works); @@ -317,7 +319,7 @@ TEST_F(QueryStageMultiPlanTest, MPSDoesNotCreateActiveCacheEntryImmediately) { // The last plan run should have required far more works than the previous plan. This means // that the 'works' in the cache entry should have doubled. ASSERT_EQ(cache->size(), 1U); - entry = assertGet(cache->getEntry(*cq)); + entry = assertGet(cache->getEntry(key)); ASSERT_FALSE(entry->isActive); ASSERT_EQ(firstQueryWorks * 2, entry->works); @@ -325,14 +327,14 @@ TEST_F(QueryStageMultiPlanTest, MPSDoesNotCreateActiveCacheEntryImmediately) { // should cause the cache entry's 'works' to be doubled again. mps = runMultiPlanner(_expCtx.get(), nss, coll, 5); ASSERT_EQ(cache->size(), 1U); - entry = assertGet(cache->getEntry(*cq)); + entry = assertGet(cache->getEntry(key)); ASSERT_FALSE(entry->isActive); ASSERT_EQ(firstQueryWorks * 2 * 2, entry->works); // Run the query yet again. This time, an active cache entry should be created. mps = runMultiPlanner(_expCtx.get(), nss, coll, 5); ASSERT_EQ(cache->size(), 1U); - entry = assertGet(cache->getEntry(*cq)); + entry = assertGet(cache->getEntry(key)); ASSERT_TRUE(entry->isActive); ASSERT_EQ(getBestPlanWorks(mps.get()), entry->works); } @@ -353,18 +355,19 @@ TEST_F(QueryStageMultiPlanTest, MPSDoesCreatesActiveEntryWhenInactiveEntriesDisa const CollectionPtr& coll = ctx.getCollection(); const auto cq = makeCanonicalQuery(_opCtx.get(), nss, BSON("foo" << 7)); + auto key = plan_cache_key_factory::make<PlanCacheKey>(*cq, coll); // Run an index scan and collection scan, searching for {foo: 7}. auto mps = runMultiPlanner(_expCtx.get(), nss, coll, 7); // Be sure that an _active_ cache entry was added. PlanCache* cache = CollectionQueryInfo::get(coll).getPlanCache(); - ASSERT_EQ(cache->get(*cq).state, PlanCache::CacheEntryState::kPresentActive); + ASSERT_EQ(cache->get(key).state, PlanCache::CacheEntryState::kPresentActive); // Run the multi-planner again. The entry should still be active. mps = runMultiPlanner(_expCtx.get(), nss, coll, 5); - ASSERT_EQ(cache->get(*cq).state, PlanCache::CacheEntryState::kPresentActive); + ASSERT_EQ(cache->get(key).state, PlanCache::CacheEntryState::kPresentActive); } // Case in which we select a blocking plan as the winner, and a non-blocking plan @@ -387,6 +390,7 @@ TEST_F(QueryStageMultiPlanTest, MPSBackupPlan) { verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(nullptr != cq.get()); + auto key = plan_cache_key_factory::make<PlanCacheKey>(*cq, collection.getCollection()); // Force index intersection. bool forceIxisectOldValue = internalQueryForceIntersectionPlans.load(); diff --git a/src/mongo/dbtests/query_stage_sort.cpp b/src/mongo/dbtests/query_stage_sort.cpp index 1b077356372..8437957b192 100644 --- a/src/mongo/dbtests/query_stage_sort.cpp +++ b/src/mongo/dbtests/query_stage_sort.cpp @@ -45,6 +45,7 @@ #include "mongo/db/json.h" #include "mongo/db/query/plan_executor_factory.h" #include "mongo/db/query/plan_executor_impl.h" +#include "mongo/db/query/query_planner_params.h" #include "mongo/dbtests/dbtests.h" /** diff --git a/src/mongo/dbtests/query_stage_tests.cpp b/src/mongo/dbtests/query_stage_tests.cpp index b1af80b12c4..e5aa014b78c 100644 --- a/src/mongo/dbtests/query_stage_tests.cpp +++ b/src/mongo/dbtests/query_stage_tests.cpp @@ -44,6 +44,7 @@ #include "mongo/db/matcher/expression_parser.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/plan_executor_factory.h" +#include "mongo/db/query/query_planner_params.h" #include "mongo/dbtests/dbtests.h" /** |