diff options
author | Ian Boros <ian.boros@mongodb.com> | 2020-03-03 15:26:40 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-04-13 21:11:41 +0000 |
commit | 5388b23cb85e84eb4ce5a2c03b250e62ff89ea1f (patch) | |
tree | 5f607e0c9b5e8bd333ffdfc600abfbea5e99b32b | |
parent | c58d35e8b8cd53875a4296e5e70070e2667194d9 (diff) | |
download | mongo-5388b23cb85e84eb4ce5a2c03b250e62ff89ea1f.tar.gz |
SERVER-46921 make collection of timing info opt in in PlanStage
36 files changed, 179 insertions, 128 deletions
diff --git a/src/mongo/db/commands/find_cmd.cpp b/src/mongo/db/commands/find_cmd.cpp index 6046efd2364..d578e04ca6d 100644 --- a/src/mongo/db/commands/find_cmd.cpp +++ b/src/mongo/db/commands/find_cmd.cpp @@ -113,7 +113,8 @@ boost::intrusive_ptr<ExpressionContext> makeExpressionContext( std::move(collator), nullptr, // mongoProcessInterface StringMap<ExpressionContext::ResolvedNamespace>{}, - boost::none // uuid + boost::none, // uuid + CurOp::get(opCtx)->dbProfileLevel() > 0 // mayDbProfile ); expCtx->tempDir = storageGlobalParams.dbpath + "/_tmp"; return expCtx; diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index fae03f2159a..7c4517c0744 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -364,8 +364,12 @@ public: } } - exec = uassertStatusOK(PlanExecutor::make( - opCtx, std::move(ws), std::move(root), nullptr, PlanExecutor::NO_YIELD, cursorNss)); + exec = uassertStatusOK(PlanExecutor::make(expCtx, + std::move(ws), + std::move(root), + nullptr, + PlanExecutor::NO_YIELD, + cursorNss)); for (long long objCount = 0; objCount < batchSize; objCount++) { Document nextDoc; diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp index 0c3cf1c3053..b50fbc89ad6 100644 --- a/src/mongo/db/commands/list_indexes.cpp +++ b/src/mongo/db/commands/list_indexes.cpp @@ -174,7 +174,7 @@ public: } exec = uassertStatusOK(PlanExecutor::make( - opCtx, std::move(ws), std::move(root), nullptr, PlanExecutor::NO_YIELD, nss)); + expCtx, std::move(ws), std::move(root), nullptr, PlanExecutor::NO_YIELD, nss)); for (long long objCount = 0; objCount < batchSize; objCount++) { Document nextDoc; diff --git a/src/mongo/db/commands/map_reduce_agg.cpp b/src/mongo/db/commands/map_reduce_agg.cpp index 4f29ccdb627..4535e0d8abd 100644 --- a/src/mongo/db/commands/map_reduce_agg.cpp +++ b/src/mongo/db/commands/map_reduce_agg.cpp @@ -96,7 +96,9 @@ auto makeExpressionContext(OperationContext* opCtx, std::move(resolvedCollator), MongoProcessInterface::create(opCtx), StringMap<ExpressionContext::ResolvedNamespace>{}, // resolvedNamespaces - uuid); + uuid, + CurOp::get(opCtx)->dbProfileLevel() > 0 // mayDbProfile + ); expCtx->tempDir = storageGlobalParams.dbpath + "/_tmp"; return expCtx; } diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp index 6f8e47dc7a8..68b919233fe 100644 --- a/src/mongo/db/commands/run_aggregate.cpp +++ b/src/mongo/db/commands/run_aggregate.cpp @@ -375,7 +375,8 @@ boost::intrusive_ptr<ExpressionContext> makeExpressionContext( std::move(collator), MongoProcessInterface::create(opCtx), uassertStatusOK(resolveInvolvedNamespaces(opCtx, request)), - uuid); + uuid, + CurOp::get(opCtx)->dbProfileLevel() > 0); expCtx->tempDir = storageGlobalParams.dbpath + "/_tmp"; expCtx->inMultiDocumentTransaction = opCtx->inMultiDocumentTransaction(); diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h index 8c8c66f5514..2e11e447718 100644 --- a/src/mongo/db/curop.h +++ b/src/mongo/db/curop.h @@ -427,6 +427,10 @@ public: */ void raiseDbProfileLevel(int dbProfileLevel); + int dbProfileLevel() const { + return _dbprofile; + } + /** * Gets the network operation type. No lock is required if called by the thread executing * the operation, but the lock must be held if called from another thread. diff --git a/src/mongo/db/exec/cached_plan.cpp b/src/mongo/db/exec/cached_plan.cpp index a5571725990..4930433ce74 100644 --- a/src/mongo/db/exec/cached_plan.cpp +++ b/src/mongo/db/exec/cached_plan.cpp @@ -76,7 +76,7 @@ Status CachedPlanStage::pickBestPlan(PlanYieldPolicy* yieldPolicy) { // Adds the amount of time taken by pickBestPlan() to executionTimeMillis. There's lots of // execution work that happens here, so this is needed for the time accounting to // make sense. - ScopedTimer timer(getClock(), &_commonStats.executionTimeMillis); + auto optTimer = getOptTimer(); // During plan selection, the list of indices we are using to plan must remain stable, so the // query will die during yield recovery if any index has been dropped. However, once plan diff --git a/src/mongo/db/exec/multi_plan.cpp b/src/mongo/db/exec/multi_plan.cpp index 4fa9b8766a2..94c1eebae42 100644 --- a/src/mongo/db/exec/multi_plan.cpp +++ b/src/mongo/db/exec/multi_plan.cpp @@ -61,6 +61,15 @@ using std::vector; // static const char* MultiPlanStage::kStageType = "MULTI_PLAN"; +namespace { +void markShouldCollectTimingInfoOnSubtree(PlanStage* root) { + root->markShouldCollectTimingInfo(); + for (auto&& child : root->getChildren()) { + markShouldCollectTimingInfoOnSubtree(child.get()); + } +} +} // namespace + MultiPlanStage::MultiPlanStage(ExpressionContext* expCtx, const Collection* collection, CanonicalQuery* cq, @@ -79,6 +88,11 @@ void MultiPlanStage::addPlan(std::unique_ptr<QuerySolution> solution, WorkingSet* ws) { _children.emplace_back(std::move(root)); _candidates.push_back(CandidatePlan(std::move(solution), _children.back().get(), ws)); + + // Tell the new candidate plan that it must collect timing info. This timing info will + // later be stored in the plan cache, and may be used for explain output. + PlanStage* newChild = _children.back().get(); + markShouldCollectTimingInfoOnSubtree(newChild); } bool MultiPlanStage::isEOF() { @@ -201,7 +215,7 @@ Status MultiPlanStage::pickBestPlan(PlanYieldPolicy* yieldPolicy) { // Adds the amount of time taken by pickBestPlan() to executionTimeMillis. There's lots of // execution work that happens here, so this is needed for the time accounting to // make sense. - ScopedTimer timer(getClock(), &_commonStats.executionTimeMillis); + auto optTimer = getOptTimer(); size_t numWorks = getTrialPeriodWorks(opCtx(), collection()); size_t numResults = getTrialPeriodNumToReturn(*_query); diff --git a/src/mongo/db/exec/plan_stage.cpp b/src/mongo/db/exec/plan_stage.cpp index 06ae012db86..22bdbbc41b9 100644 --- a/src/mongo/db/exec/plan_stage.cpp +++ b/src/mongo/db/exec/plan_stage.cpp @@ -33,32 +33,10 @@ #include "mongo/db/exec/plan_stage.h" -#include "mongo/db/exec/scoped_timer.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" namespace mongo { - -PlanStage::StageState PlanStage::work(WorkingSetID* out) { - invariant(_opCtx); - ScopedTimer timer(getClock(), &_commonStats.executionTimeMillis); - ++_commonStats.works; - - StageState workResult = doWork(out); - - if (StageState::ADVANCED == workResult) { - ++_commonStats.advanced; - } else if (StageState::NEED_TIME == workResult) { - ++_commonStats.needTime; - } else if (StageState::NEED_YIELD == workResult) { - ++_commonStats.needYield; - } else if (StageState::FAILURE == workResult) { - _commonStats.failed = true; - } - - return workResult; -} - void PlanStage::saveState() { ++_commonStats.yields; for (auto&& child : _children) { diff --git a/src/mongo/db/exec/plan_stage.h b/src/mongo/db/exec/plan_stage.h index 3a9475a5ca4..652bc62d051 100644 --- a/src/mongo/db/exec/plan_stage.h +++ b/src/mongo/db/exec/plan_stage.h @@ -33,6 +33,7 @@ #include <vector> #include "mongo/db/exec/plan_stats.h" +#include "mongo/db/exec/scoped_timer.h" #include "mongo/db/exec/working_set.h" #include "mongo/db/pipeline/expression_context.h" @@ -109,6 +110,11 @@ public: PlanStage(const char* typeName, ExpressionContext* expCtx) : _commonStats(typeName), _opCtx(expCtx->opCtx), _expCtx(expCtx) { invariant(expCtx); + if (expCtx->explain || expCtx->mayDbProfile) { + // Populating the field for execution time indicates that this stage should time each + // call to work(). + _commonStats.executionTimeMillis.emplace(0); + } } protected: @@ -194,7 +200,25 @@ public: * Stage returns StageState::ADVANCED if *out is set to the next unit of output. Otherwise, * returns another value of StageState to indicate the stage's status. */ - StageState work(WorkingSetID* out); + StageState work(WorkingSetID* out) { + auto optTimer(getOptTimer()); + + ++_commonStats.works; + + StageState workResult = doWork(out); + + if (StageState::ADVANCED == workResult) { + ++_commonStats.advanced; + } else if (StageState::NEED_TIME == workResult) { + ++_commonStats.needTime; + } else if (StageState::NEED_YIELD == workResult) { + ++_commonStats.needYield; + } else if (StageState::FAILURE == workResult) { + _commonStats.failed = true; + } + + return workResult; + } /** * Returns true if no more work can be done on the query / out of results. @@ -338,6 +362,15 @@ public: */ virtual const SpecificStats* getSpecificStats() const = 0; + /** + * Force this stage to collect timing info during its execution. Must not be called after + * execution has started. + */ + void markShouldCollectTimingInfo() { + invariant(!_commonStats.executionTimeMillis || *_commonStats.executionTimeMillis == 0); + _commonStats.executionTimeMillis.emplace(0); + } + protected: /** * Performs one unit of work. See comment at work() above. @@ -388,6 +421,18 @@ protected: return _expCtx; } + /** + * Returns an optional timer which is used to collect time spent executing the current + * stage. May return boost::none if it is not necessary to collect timing info. + */ + boost::optional<ScopedTimer> getOptTimer() { + if (_commonStats.executionTimeMillis) { + return {{getClock(), _commonStats.executionTimeMillis.get_ptr()}}; + } + + return boost::none; + } + Children _children; CommonStats _commonStats; diff --git a/src/mongo/db/exec/plan_stats.h b/src/mongo/db/exec/plan_stats.h index ea75f673b81..8e3d2dfadff 100644 --- a/src/mongo/db/exec/plan_stats.h +++ b/src/mongo/db/exec/plan_stats.h @@ -68,7 +68,6 @@ struct CommonStats { advanced(0), needTime(0), needYield(0), - executionTimeMillis(0), failed(false), isEOF(false) {} @@ -92,8 +91,13 @@ struct CommonStats { // is no filter affixed, then 'filter' should be an empty BSONObj. BSONObj filter; - // Time elapsed while working inside this stage. - long long executionTimeMillis; + // Time elapsed while working inside this stage. When this field is set to boost::none, + // timing info will not be collected during query execution. + // + // The field must be populated when running explain or when running with the profiler on. It + // must also be populated when multi planning, in order to gather stats stored in the plan + // cache. + boost::optional<long long> executionTimeMillis; // TODO: have some way of tracking WSM sizes (or really any series of #s). We can measure // the size of our inputs and the size of our outputs. We can do a lot with the WS here. diff --git a/src/mongo/db/exec/scoped_timer.h b/src/mongo/db/exec/scoped_timer.h index 33ddb192873..c11c424e59a 100644 --- a/src/mongo/db/exec/scoped_timer.h +++ b/src/mongo/db/exec/scoped_timer.h @@ -45,6 +45,7 @@ class ScopedTimer { ScopedTimer& operator=(const ScopedTimer&) = delete; public: + ScopedTimer(ScopedTimer&& other) = default; ScopedTimer(ClockSource* cs, long long* counter); ~ScopedTimer(); diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp index 7baabe4a011..13489617671 100644 --- a/src/mongo/db/exec/stagedebug_cmd.cpp +++ b/src/mongo/db/exec/stagedebug_cmd.cpp @@ -183,7 +183,7 @@ public: expCtx.get(), ws.get(), std::move(userRoot), nullptr, collection); auto statusWithPlanExecutor = PlanExecutor::make( - opCtx, std::move(ws), std::move(rootFetch), collection, PlanExecutor::YIELD_AUTO); + expCtx, std::move(ws), std::move(rootFetch), collection, PlanExecutor::YIELD_AUTO); fassert(28536, statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/db/exec/subplan.cpp b/src/mongo/db/exec/subplan.cpp index 054f48e3a2b..910a061e3d2 100644 --- a/src/mongo/db/exec/subplan.cpp +++ b/src/mongo/db/exec/subplan.cpp @@ -424,7 +424,7 @@ Status SubplanStage::choosePlanWholeQuery(PlanYieldPolicy* yieldPolicy) { Status SubplanStage::pickBestPlan(PlanYieldPolicy* yieldPolicy) { // Adds the amount of time taken by pickBestPlan() to executionTimeMillis. There's lots of // work that happens here, so this is needed for the time accounting to make sense. - ScopedTimer timer(getClock(), &_commonStats.executionTimeMillis); + auto optTimer = getOptTimer(); // During plan selection, the list of indices we are using to plan must remain stable, so the // query will die during yield recovery if any index has been dropped. However, once plan diff --git a/src/mongo/db/pipeline/document_source.cpp b/src/mongo/db/pipeline/document_source.cpp index f6b5b38c486..51e8d8b85df 100644 --- a/src/mongo/db/pipeline/document_source.cpp +++ b/src/mongo/db/pipeline/document_source.cpp @@ -54,7 +54,11 @@ using std::vector; DocumentSource::DocumentSource(const StringData stageName, const intrusive_ptr<ExpressionContext>& pCtx) - : pSource(nullptr), pExpCtx(pCtx), _commonStats(stageName.rawData()) {} + : pSource(nullptr), pExpCtx(pCtx), _commonStats(stageName.rawData()) { + if (pExpCtx->shouldCollectDocumentSourceExecStats()) { + _commonStats.executionTimeMillis.emplace(0); + } +} namespace { struct ParserRegistration { diff --git a/src/mongo/db/pipeline/document_source.h b/src/mongo/db/pipeline/document_source.h index 3e04bb594bf..9ea177d52d5 100644 --- a/src/mongo/db/pipeline/document_source.h +++ b/src/mongo/db/pipeline/document_source.h @@ -255,7 +255,7 @@ public: GetNextResult getNext() { pExpCtx->checkForInterrupt(); - if (MONGO_likely(!pExpCtx->shouldCollectExecStats())) { + if (MONGO_likely(!pExpCtx->shouldCollectDocumentSourceExecStats())) { return doGetNext(); } @@ -264,7 +264,8 @@ public: auto fcs = serviceCtx->getFastClockSource(); invariant(fcs); - ScopedTimer timer(fcs, &_commonStats.executionTimeMillis); + invariant(_commonStats.executionTimeMillis); + ScopedTimer timer(fcs, _commonStats.executionTimeMillis.get_ptr()); ++_commonStats.works; GetNextResult next = doGetNext(); diff --git a/src/mongo/db/pipeline/expression_context.cpp b/src/mongo/db/pipeline/expression_context.cpp index 0c6f80e8b82..fb790531f29 100644 --- a/src/mongo/db/pipeline/expression_context.cpp +++ b/src/mongo/db/pipeline/expression_context.cpp @@ -50,7 +50,8 @@ ExpressionContext::ExpressionContext(OperationContext* opCtx, std::unique_ptr<CollatorInterface> collator, std::shared_ptr<MongoProcessInterface> processInterface, StringMap<ResolvedNamespace> resolvedNamespaces, - boost::optional<UUID> collUUID) + boost::optional<UUID> collUUID, + bool mayDbProfile) : ExpressionContext(opCtx, request.getExplain(), request.isFromMongos(), @@ -63,7 +64,8 @@ ExpressionContext::ExpressionContext(OperationContext* opCtx, std::move(collator), std::move(processInterface), std::move(resolvedNamespaces), - std::move(collUUID)) { + std::move(collUUID), + mayDbProfile) { if (request.getIsMapReduceCommand()) { // mapReduce command JavaScript invocation is only subject to the server global // 'jsHeapLimitMB' limit. @@ -84,7 +86,8 @@ ExpressionContext::ExpressionContext( std::unique_ptr<CollatorInterface> collator, const std::shared_ptr<MongoProcessInterface>& mongoProcessInterface, StringMap<ExpressionContext::ResolvedNamespace> resolvedNamespaces, - boost::optional<UUID> collUUID) + boost::optional<UUID> collUUID, + bool mayDbProfile) : explain(explain), fromMongos(fromMongos), needsMerge(needsMerge), @@ -98,6 +101,7 @@ ExpressionContext::ExpressionContext( ? TimeZoneDatabase::get(opCtx->getServiceContext()) : nullptr), variablesParseState(variables.useIdGenerator()), + mayDbProfile(mayDbProfile), _collator(std::move(collator)), _documentComparator(_collator.get()), _valueComparator(_collator.get()), @@ -117,7 +121,8 @@ ExpressionContext::ExpressionContext( ExpressionContext::ExpressionContext(OperationContext* opCtx, std::unique_ptr<CollatorInterface> collator, const NamespaceString& nss, - const boost::optional<RuntimeConstants>& runtimeConstants) + const boost::optional<RuntimeConstants>& runtimeConstants, + bool mayDbProfile) : ns(nss), opCtx(opCtx), mongoProcessInterface(std::make_shared<StubMongoProcessInterface>()), @@ -125,6 +130,7 @@ ExpressionContext::ExpressionContext(OperationContext* opCtx, ? TimeZoneDatabase::get(opCtx->getServiceContext()) : nullptr), variablesParseState(variables.useIdGenerator()), + mayDbProfile(mayDbProfile), _collator(std::move(collator)), _documentComparator(_collator.get()), _valueComparator(_collator.get()) { @@ -182,7 +188,8 @@ intrusive_ptr<ExpressionContext> ExpressionContext::copyWith( std::move(collator), mongoProcessInterface, _resolvedNamespaces, - uuid); + uuid, + mayDbProfile); expCtx->inMongos = inMongos; expCtx->maxFeatureCompatibilityVersion = maxFeatureCompatibilityVersion; diff --git a/src/mongo/db/pipeline/expression_context.h b/src/mongo/db/pipeline/expression_context.h index cbb0aab0c4b..80104b06a37 100644 --- a/src/mongo/db/pipeline/expression_context.h +++ b/src/mongo/db/pipeline/expression_context.h @@ -107,7 +107,8 @@ public: std::unique_ptr<CollatorInterface> collator, std::shared_ptr<MongoProcessInterface> mongoProcessInterface, StringMap<ExpressionContext::ResolvedNamespace> resolvedNamespaces, - boost::optional<UUID> collUUID); + boost::optional<UUID> collUUID, + bool mayDbProfile = true); /** * Constructs an ExpressionContext to be used for Pipeline parsing and evaluation. This version @@ -126,7 +127,8 @@ public: std::unique_ptr<CollatorInterface> collator, const std::shared_ptr<MongoProcessInterface>& mongoProcessInterface, StringMap<ExpressionContext::ResolvedNamespace> resolvedNamespaces, - boost::optional<UUID> collUUID); + boost::optional<UUID> collUUID, + bool mayDbProfile); /** * Constructs an ExpressionContext suitable for use outside of the aggregation system, including @@ -137,7 +139,8 @@ public: ExpressionContext(OperationContext* opCtx, std::unique_ptr<CollatorInterface> collator, const NamespaceString& ns, - const boost::optional<RuntimeConstants>& runtimeConstants = boost::none); + const boost::optional<RuntimeConstants>& runtimeConstants = boost::none, + bool mayDbProfile = true); /** * Used by a pipeline to check for interrupts so that killOp() works. Throws a UserAssertion if @@ -170,7 +173,10 @@ public: return _collator.get(); } - bool shouldCollectExecStats() const { + /** + * Whether to track timing information and "work" counts in the agg layer. + */ + bool shouldCollectDocumentSourceExecStats() const { return static_cast<bool>(explain); } @@ -352,6 +358,10 @@ public: // True if this ExpressionContext is used to parse a collection validator expression. bool isParsingCollectionValidator = false; + // Indicates where there is any chance this operation will be profiled. Must be set at + // construction. + const bool mayDbProfile = true; + protected: static const int kInterruptCheckPeriod = 128; diff --git a/src/mongo/db/pipeline/expression_context_for_test.h b/src/mongo/db/pipeline/expression_context_for_test.h index 23bd4cce4ce..cb1d0deab58 100644 --- a/src/mongo/db/pipeline/expression_context_for_test.h +++ b/src/mongo/db/pipeline/expression_context_for_test.h @@ -75,8 +75,9 @@ public: RuntimeConstants(Date_t::now(), Timestamp(1, 0)), {}, // collator std::make_shared<StubMongoProcessInterface>(), - {}, // resolvedNamespaces - {} // collUUID + {}, // resolvedNamespaces + {}, // collUUID + false // mayDbProfile ) { // If there is an existing global ServiceContext, adopt it. Otherwise, create a new context. // Similarly, we create a new OperationContext or adopt an existing context as appropriate. @@ -93,7 +94,6 @@ public: // Resolve the active OperationContext and set it on the ExpressionContextForTest. opCtx = _testOpCtx ? _testOpCtx.get() : Client::getCurrent()->getOperationContext(); - // As we don't have an OperationContext or TimeZoneDatabase prior to base class // ExpressionContext construction, we must resolve one. If there exists a TimeZoneDatabase // associated with the current ServiceContext, adopt it. Otherwise, create a @@ -125,8 +125,9 @@ public: RuntimeConstants(Date_t::now(), Timestamp(1, 0)), {}, // collator std::make_shared<StubMongoProcessInterface>(), - {}, // resolvedNamespaces - {} // collUUID + {}, // resolvedNamespaces + {}, // collUUID + false // mayDbProfile ), _serviceContext(opCtx->getServiceContext()) { // Resolve the TimeZoneDatabase to be used by this ExpressionContextForTest. diff --git a/src/mongo/db/pipeline/pipeline.cpp b/src/mongo/db/pipeline/pipeline.cpp index 2cfa0754d57..156450b961f 100644 --- a/src/mongo/db/pipeline/pipeline.cpp +++ b/src/mongo/db/pipeline/pipeline.cpp @@ -64,7 +64,8 @@ Value appendExecStats(Value docSource, const CommonStats& stats) { invariant(docSource.getType() == BSONType::Object); MutableDocument doc(docSource.getDocument()); auto nReturned = static_cast<long long>(stats.advanced); - auto executionTimeMillisEstimate = static_cast<long long>(stats.executionTimeMillis); + invariant(stats.executionTimeMillis); + auto executionTimeMillisEstimate = static_cast<long long>(*stats.executionTimeMillis); doc.addField("nReturned", Value(nReturned)); doc.addField("executionTimeMillisEstimate", Value(executionTimeMillisEstimate)); return Value(doc.freeze()); diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp index b35e720fcf6..926a9e2f7ac 100644 --- a/src/mongo/db/pipeline/pipeline_d.cpp +++ b/src/mongo/db/pipeline/pipeline_d.cpp @@ -170,7 +170,7 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> createRandomCursorEx } return PlanExecutor::make( - opCtx, std::move(ws), std::move(root), coll, PlanExecutor::YIELD_AUTO); + expCtx, std::move(ws), std::move(root), coll, PlanExecutor::YIELD_AUTO); } StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> attemptToGetExecutor( diff --git a/src/mongo/db/query/explain.cpp b/src/mongo/db/query/explain.cpp index 8e86973cde4..1287315005d 100644 --- a/src/mongo/db/query/explain.cpp +++ b/src/mongo/db/query/explain.cpp @@ -327,7 +327,11 @@ void Explain::statsToBSON(const PlanStageStats& stats, // Some top-level exec stats get pulled out of the root stage. if (verbosity >= ExplainOptions::Verbosity::kExecStats) { bob->appendNumber("nReturned", stats.common.advanced); - bob->appendNumber("executionTimeMillisEstimate", stats.common.executionTimeMillis); + // Include executionTimeMillis if it was recorded. + if (stats.common.executionTimeMillis) { + bob->appendNumber("executionTimeMillisEstimate", *stats.common.executionTimeMillis); + } + bob->appendNumber("works", stats.common.works); bob->appendNumber("advanced", stats.common.advanced); bob->appendNumber("needTime", stats.common.needTime); @@ -729,7 +733,8 @@ void Explain::generateSinglePlanExecutionInfo(const PlanStageStats* stats, if (totalTimeMillis) { out->appendNumber("executionTimeMillis", *totalTimeMillis); } else { - out->appendNumber("executionTimeMillisEstimate", stats->common.executionTimeMillis); + invariant(stats->common.executionTimeMillis); + out->appendNumber("executionTimeMillisEstimate", *stats->common.executionTimeMillis); } // Flatten the stats tree into a list. @@ -957,7 +962,6 @@ void Explain::getSummaryStats(const PlanExecutor& exec, PlanSummaryStats* statsO // root stage of the plan tree. const CommonStats* common = root->getCommonStats(); statsOut->nReturned = common->advanced; - statsOut->executionTimeMillis = common->executionTimeMillis; // The other fields are aggregations over the stages in the plan tree. We flatten // the tree into a list and then compute these aggregations. diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp index 6285c023a37..db1ead9711d 100644 --- a/src/mongo/db/query/get_executor.cpp +++ b/src/mongo/db/query/get_executor.cpp @@ -780,7 +780,7 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDelete( "nss_ns"_attr = nss.ns(), "request_getQuery"_attr = redact(request->getQuery())); return PlanExecutor::make( - opCtx, std::move(ws), std::make_unique<EOFStage>(expCtx.get()), nullptr, policy, nss); + expCtx, std::move(ws), std::make_unique<EOFStage>(expCtx.get()), nullptr, policy, nss); } if (!parsedDelete->hasParsedQuery()) { @@ -822,7 +822,7 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDelete( collection, idHackStage.release()); return PlanExecutor::make( - opCtx, std::move(ws), std::move(root), collection, policy); + expCtx, std::move(ws), std::move(root), collection, policy); } } @@ -946,7 +946,7 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorUpdate( "nss_ns"_attr = nss.ns(), "request_getQuery"_attr = redact(request->getQuery())); return PlanExecutor::make( - opCtx, std::move(ws), std::make_unique<EOFStage>(expCtx.get()), nullptr, policy, nss); + expCtx, std::move(ws), std::make_unique<EOFStage>(expCtx.get()), nullptr, policy, nss); } // Pass index information to the update driver, so that it can determine for us whether the @@ -1228,7 +1228,8 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorCount( // this case we put a CountStage on top of an EOFStage. unique_ptr<PlanStage> root = std::make_unique<CountStage>( expCtx.get(), collection, limit, skip, ws.get(), new EOFStage(expCtx.get())); - return PlanExecutor::make(opCtx, std::move(ws), std::move(root), nullptr, yieldPolicy, nss); + return PlanExecutor::make( + expCtx, std::move(ws), std::move(root), nullptr, yieldPolicy, nss); } // If the query is empty, then we can determine the count by just asking the collection @@ -1243,7 +1244,8 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorCount( if (useRecordStoreCount) { unique_ptr<PlanStage> root = std::make_unique<RecordStoreFastCountStage>(expCtx.get(), collection, skip, limit); - return PlanExecutor::make(opCtx, std::move(ws), std::move(root), nullptr, yieldPolicy, nss); + return PlanExecutor::make( + expCtx, std::move(ws), std::move(root), nullptr, yieldPolicy, nss); } size_t plannerOptions = QueryPlannerParams::IS_COUNT; diff --git a/src/mongo/db/query/internal_plans.cpp b/src/mongo/db/query/internal_plans.cpp index 238f6636e0f..ed03783f598 100644 --- a/src/mongo/db/query/internal_plans.cpp +++ b/src/mongo/db/query/internal_plans.cpp @@ -62,7 +62,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::collection auto eof = std::make_unique<EOFStage>(expCtx.get()); // Takes ownership of 'ws' and 'eof'. auto statusWithPlanExecutor = PlanExecutor::make( - opCtx, std::move(ws), std::move(eof), nullptr, yieldPolicy, NamespaceString(ns)); + expCtx, std::move(ws), std::move(eof), nullptr, yieldPolicy, NamespaceString(ns)); invariant(statusWithPlanExecutor.isOK()); return std::move(statusWithPlanExecutor.getValue()); } @@ -73,7 +73,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::collection // Takes ownership of 'ws' and 'cs'. auto statusWithPlanExecutor = - PlanExecutor::make(opCtx, std::move(ws), std::move(cs), collection, yieldPolicy); + PlanExecutor::make(expCtx, std::move(ws), std::move(cs), collection, yieldPolicy); invariant(statusWithPlanExecutor.isOK()); return std::move(statusWithPlanExecutor.getValue()); } @@ -96,7 +96,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::deleteWith expCtx.get(), std::move(params), ws.get(), collection, root.release()); auto executor = - PlanExecutor::make(opCtx, std::move(ws), std::move(root), collection, yieldPolicy); + PlanExecutor::make(expCtx, std::move(ws), std::move(root), collection, yieldPolicy); invariant(executor.getStatus()); return std::move(executor.getValue()); } @@ -128,7 +128,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::indexScan( options); auto executor = - PlanExecutor::make(opCtx, std::move(ws), std::move(root), collection, yieldPolicy); + PlanExecutor::make(expCtx, std::move(ws), std::move(root), collection, yieldPolicy); invariant(executor.getStatus()); return std::move(executor.getValue()); } @@ -163,7 +163,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::deleteWith expCtx.get(), std::move(params), ws.get(), collection, root.release()); auto executor = - PlanExecutor::make(opCtx, std::move(ws), std::move(root), collection, yieldPolicy); + PlanExecutor::make(expCtx, std::move(ws), std::move(root), collection, yieldPolicy); invariant(executor.getStatus()); return std::move(executor.getValue()); } @@ -190,7 +190,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::updateWith expCtx.get(), params, ws.get(), collection, idHackStage.release())); auto executor = - PlanExecutor::make(opCtx, std::move(ws), std::move(root), collection, yieldPolicy); + PlanExecutor::make(expCtx, std::move(ws), std::move(root), collection, yieldPolicy); invariant(executor.getStatus()); return std::move(executor.getValue()); } diff --git a/src/mongo/db/query/plan_executor.h b/src/mongo/db/query/plan_executor.h index ffb54ee7c90..bef0a4d4d27 100644 --- a/src/mongo/db/query/plan_executor.h +++ b/src/mongo/db/query/plan_executor.h @@ -287,19 +287,6 @@ public: std::unique_ptr<QuerySolution> qs = nullptr); /** - * This overload is provided for executors that do not have a CanonicalQuery or an - * ExpressionContext, such as an aggregation command with a $listCollections stage. - */ - static StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make( - OperationContext* opCtx, - std::unique_ptr<WorkingSet> ws, - std::unique_ptr<PlanStage> rt, - const Collection* collection, - YieldPolicy yieldPolicy, - NamespaceString nss = NamespaceString(), - std::unique_ptr<QuerySolution> qs = nullptr); - - /** * A PlanExecutor must be disposed before destruction. In most cases, this will happen * automatically through a PlanExecutor::Deleter or a ClientCursor. */ diff --git a/src/mongo/db/query/plan_executor_impl.cpp b/src/mongo/db/query/plan_executor_impl.cpp index 8da7932a3d5..ed0744fcdd2 100644 --- a/src/mongo/db/query/plan_executor_impl.cpp +++ b/src/mongo/db/query/plan_executor_impl.cpp @@ -165,25 +165,6 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> PlanExecutor::make( yieldPolicy); } -StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> PlanExecutor::make( - OperationContext* opCtx, - std::unique_ptr<WorkingSet> ws, - std::unique_ptr<PlanStage> rt, - const Collection* collection, - YieldPolicy yieldPolicy, - NamespaceString nss, - std::unique_ptr<QuerySolution> qs) { - return PlanExecutorImpl::make(opCtx, - std::move(ws), - std::move(rt), - std::move(qs), - nullptr, - nullptr, - collection, - nss, - yieldPolicy); -} - StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> PlanExecutorImpl::make( OperationContext* opCtx, unique_ptr<WorkingSet> ws, diff --git a/src/mongo/db/query/plan_summary_stats.h b/src/mongo/db/query/plan_summary_stats.h index a5ff98266d2..4660c097795 100644 --- a/src/mongo/db/query/plan_summary_stats.h +++ b/src/mongo/db/query/plan_summary_stats.h @@ -47,9 +47,6 @@ struct PlanSummaryStats { // The total number of documents examined by the plan. size_t totalDocsExamined = 0U; - // The number of milliseconds spent inside the root stage's work() method. - long long executionTimeMillis = 0; - // The number of collection scans that occur during execution. Note that more than one // collection scan may happen during execution (e.g. for $lookup execution). long long collectionScans = 0; diff --git a/src/mongo/dbtests/cursor_manager_test.cpp b/src/mongo/dbtests/cursor_manager_test.cpp index 99e8b00495c..9f3a1ad96de 100644 --- a/src/mongo/dbtests/cursor_manager_test.cpp +++ b/src/mongo/dbtests/cursor_manager_test.cpp @@ -75,7 +75,7 @@ public: auto workingSet = std::make_unique<WorkingSet>(); auto queuedDataStage = std::make_unique<QueuedDataStage>(expCtx.get(), workingSet.get()); - return unittest::assertGet(PlanExecutor::make(opCtx, + return unittest::assertGet(PlanExecutor::make(expCtx, std::move(workingSet), std::move(queuedDataStage), nullptr, diff --git a/src/mongo/dbtests/documentsourcetests.cpp b/src/mongo/dbtests/documentsourcetests.cpp index 84738eb6e17..2f6e421e159 100644 --- a/src/mongo/dbtests/documentsourcetests.cpp +++ b/src/mongo/dbtests/documentsourcetests.cpp @@ -228,8 +228,8 @@ TEST_F(DocumentSourceCursorTest, SerializationNoExplainLevel) { TEST_F(DocumentSourceCursorTest, SerializationQueryPlannerExplainLevel) { auto verb = ExplainOptions::Verbosity::kQueryPlanner; - createSource(); ctx()->explain = verb; + createSource(); auto explainResult = source()->serialize(verb); ASSERT_FALSE(explainResult["$cursor"]["queryPlanner"].missing()); @@ -240,8 +240,8 @@ TEST_F(DocumentSourceCursorTest, SerializationQueryPlannerExplainLevel) { TEST_F(DocumentSourceCursorTest, SerializationExecStatsExplainLevel) { auto verb = ExplainOptions::Verbosity::kExecStats; - createSource(); ctx()->explain = verb; + createSource(); // Execute the plan so that the source populates its internal execution stats. exhaustCursor(); @@ -256,8 +256,8 @@ TEST_F(DocumentSourceCursorTest, SerializationExecStatsExplainLevel) { TEST_F(DocumentSourceCursorTest, SerializationExecAllPlansExplainLevel) { auto verb = ExplainOptions::Verbosity::kExecAllPlans; - createSource(); ctx()->explain = verb; + createSource(); // Execute the plan so that the source populates its internal executionStats. exhaustCursor(); @@ -273,8 +273,8 @@ TEST_F(DocumentSourceCursorTest, SerializationExecAllPlansExplainLevel) { TEST_F(DocumentSourceCursorTest, ExpressionContextAndSerializeVerbosityMismatch) { const auto verb1 = ExplainOptions::Verbosity::kExecAllPlans; const auto verb2 = ExplainOptions::Verbosity::kQueryPlanner; - createSource(); ctx()->explain = verb1; + createSource(); // Execute the plan so that the source populates its internal executionStats. exhaustCursor(); diff --git a/src/mongo/dbtests/query_plan_executor.cpp b/src/mongo/dbtests/query_plan_executor.cpp index 25182aa327b..fd7b3f6a111 100644 --- a/src/mongo/dbtests/query_plan_executor.cpp +++ b/src/mongo/dbtests/query_plan_executor.cpp @@ -224,7 +224,7 @@ TEST_F(PlanExecutorTest, DropIndexScanAgg) { auto proxy = std::make_unique<PipelineProxyStage>(_expCtx.get(), std::move(pipeline), ws.get()); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(proxy), collection, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(proxy), collection, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto outerExec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/dbtests/query_stage_collscan.cpp b/src/mongo/dbtests/query_stage_collscan.cpp index 9040569a58c..f17052e3e03 100644 --- a/src/mongo/dbtests/query_stage_collscan.cpp +++ b/src/mongo/dbtests/query_stage_collscan.cpp @@ -105,7 +105,7 @@ public: _expCtx.get(), collection, params, ws.get(), filterExpr.get()); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(ps), collection, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(ps), collection, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -195,7 +195,7 @@ TEST_F(QueryStageCollectionScanTest, QueryStageCollscanObjectsInOrderForward) { std::make_unique<CollectionScan>(_expCtx.get(), collection, params, ws.get(), nullptr); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(ps), collection, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(ps), collection, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -224,7 +224,7 @@ TEST_F(QueryStageCollectionScanTest, QueryStageCollscanObjectsInOrderBackward) { std::make_unique<CollectionScan>(_expCtx.get(), collection, params, ws.get(), nullptr); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(ps), collection, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(ps), collection, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -377,7 +377,7 @@ TEST_F(QueryStageCollectionScanTest, QueryTestCollscanResumeAfterRecordIdSeekSuc // Run the rest of the scan and verify the results. auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(ps), collection, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(ps), collection, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/dbtests/query_stage_merge_sort.cpp b/src/mongo/dbtests/query_stage_merge_sort.cpp index b6b1fa9e87e..74b6d6d1843 100644 --- a/src/mongo/dbtests/query_stage_merge_sort.cpp +++ b/src/mongo/dbtests/query_stage_merge_sort.cpp @@ -187,7 +187,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(ms), nullptr, coll); // Must fetch if we want to easily pull out an obj. auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -252,7 +252,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(ms), nullptr, coll); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -317,7 +317,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(ms), nullptr, coll); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -388,7 +388,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(ms), nullptr, coll); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -455,7 +455,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(ms), nullptr, coll); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -508,7 +508,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(ms), nullptr, coll); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -797,7 +797,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(ms), nullptr, coll); // Must fetch if we want to easily pull out an obj. auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -866,7 +866,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(ms), nullptr, coll); // Must fetch if we want to easily pull out an obj. auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp index 38d44b1d8f2..59520a3b3aa 100644 --- a/src/mongo/dbtests/query_stage_multiplan.cpp +++ b/src/mongo/dbtests/query_stage_multiplan.cpp @@ -492,7 +492,7 @@ TEST_F(QueryStageMultiPlanTest, MPSExplainAllPlans) { // Making a PlanExecutor chooses the best plan. auto exec = uassertStatusOK(PlanExecutor::make( - _opCtx.get(), std::move(ws), std::move(mps), ctx.getCollection(), PlanExecutor::NO_YIELD)); + _expCtx, std::move(ws), std::move(mps), ctx.getCollection(), PlanExecutor::NO_YIELD)); auto root = static_cast<MultiPlanStage*>(exec->getRootStage()); ASSERT_TRUE(root->bestPlanChosen()); diff --git a/src/mongo/dbtests/query_stage_sort.cpp b/src/mongo/dbtests/query_stage_sort.cpp index 1d6833337bc..a81702662d8 100644 --- a/src/mongo/dbtests/query_stage_sort.cpp +++ b/src/mongo/dbtests/query_stage_sort.cpp @@ -131,7 +131,7 @@ public: // The PlanExecutor will be automatically registered on construction due to the auto // yield policy, so it can receive invalidations when we remove documents later. auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(ss), coll, PlanExecutor::YIELD_AUTO); + _expCtx, std::move(ws), std::move(ss), coll, PlanExecutor::YIELD_AUTO); invariant(statusWithPlanExecutor.isOK()); return std::move(statusWithPlanExecutor.getValue()); } @@ -174,7 +174,7 @@ public: // Must fetch so we can look at the doc as a BSONObj. auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -590,7 +590,7 @@ public: // We don't get results back since we're sorting some parallel arrays. auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(fetchStage), coll, PlanExecutor::NO_YIELD); auto exec = std::move(statusWithPlanExecutor.getValue()); PlanExecutor::ExecState runnerState = diff --git a/src/mongo/dbtests/query_stage_tests.cpp b/src/mongo/dbtests/query_stage_tests.cpp index e86d851c7a4..b3003d56213 100644 --- a/src/mongo/dbtests/query_stage_tests.cpp +++ b/src/mongo/dbtests/query_stage_tests.cpp @@ -93,7 +93,7 @@ public: std::make_unique<IndexScan>(_expCtx.get(), params, ws.get(), filterExpr.get()); auto statusWithPlanExecutor = PlanExecutor::make( - &_opCtx, std::move(ws), std::move(ix), ctx.getCollection(), PlanExecutor::NO_YIELD); + _expCtx, std::move(ws), std::move(ix), ctx.getCollection(), PlanExecutor::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/s/commands/cluster_map_reduce_agg.cpp b/src/mongo/s/commands/cluster_map_reduce_agg.cpp index 6c6365500f4..0223ac3e07c 100644 --- a/src/mongo/s/commands/cluster_map_reduce_agg.cpp +++ b/src/mongo/s/commands/cluster_map_reduce_agg.cpp @@ -101,7 +101,9 @@ auto makeExpressionContext(OperationContext* opCtx, std::make_shared<MongosProcessInterface>( Grid::get(opCtx)->getExecutorPool()->getArbitraryExecutor()), std::move(resolvedNamespaces), - boost::none); // uuid + boost::none, // uuid + false // mayDbProfile: false because mongos has no profile collection. + ); expCtx->inMongos = true; return expCtx; } |