diff options
author | Drew Paroski <drew.paroski@mongodb.com> | 2020-11-27 03:28:49 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-12-10 00:20:45 +0000 |
commit | e7697afed598f3faa1173cd92c06919432a8b2c2 (patch) | |
tree | 25a977b0869de9e59fbb3f2197c6b699518eefc7 /src | |
parent | e835e702ef549d926b7d2cf72397eea29b29af71 (diff) | |
download | mongo-e7697afed598f3faa1173cd92c06919432a8b2c2.tar.gz |
SERVER-53090 [SBE] Fix crash when running "bestbuy_agg_query_comparison.js"
Diffstat (limited to 'src')
26 files changed, 127 insertions, 141 deletions
diff --git a/src/mongo/db/exec/sbe/parser/parser.cpp b/src/mongo/db/exec/sbe/parser/parser.cpp index f11f89beba2..49bd40b3cbc 100644 --- a/src/mongo/db/exec/sbe/parser/parser.cpp +++ b/src/mongo/db/exec/sbe/parser/parser.cpp @@ -574,7 +574,6 @@ void Parser::walkScan(AstQuery& ast) { boost::none, forward, nullptr, - nullptr, getCurrentPlanNodeId()); } @@ -643,7 +642,6 @@ void Parser::walkSeek(AstQuery& ast) { lookupSlot(ast.nodes[0]->identifier), true /* forward */, nullptr, - nullptr, getCurrentPlanNodeId()); } @@ -694,7 +692,6 @@ void Parser::walkIndexScan(AstQuery& ast) { boost::none, boost::none, nullptr, - nullptr, getCurrentPlanNodeId()); } @@ -745,7 +742,6 @@ void Parser::walkIndexSeek(AstQuery& ast) { lookupSlot(ast.nodes[0]->identifier), lookupSlot(ast.nodes[1]->identifier), nullptr, - nullptr, getCurrentPlanNodeId()); } @@ -785,7 +781,6 @@ void Parser::walkSort(AstQuery& ast) { std::numeric_limits<std::size_t>::max(), std::numeric_limits<std::size_t>::max(), true /* allowDiskUse */, - nullptr, getCurrentPlanNodeId()); } diff --git a/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp b/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp index ef0bc49822e..e83469da524 100644 --- a/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp @@ -53,7 +53,7 @@ PlanStageTestFixture::generateVirtualScanMulti(int32_t numSlots, const BSONArray void PlanStageTestFixture::prepareTree(CompileCtx* ctx, PlanStage* root) { root->prepare(*ctx); - root->attachFromOperationContext(opCtx()); + root->attachToOperationContext(opCtx()); root->open(false); } diff --git a/src/mongo/db/exec/sbe/sbe_sort_test.cpp b/src/mongo/db/exec/sbe/sbe_sort_test.cpp index d471d37f413..1d4574f2d50 100644 --- a/src/mongo/db/exec/sbe/sbe_sort_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_sort_test.cpp @@ -59,7 +59,6 @@ TEST_F(SortStageTest, SortNumbersTest) { std::numeric_limits<std::size_t>::max(), 204857600, false, - nullptr, kEmptyPlanNodeId); return std::make_pair(scanSlots, std::move(sortStage)); diff --git a/src/mongo/db/exec/sbe/stages/exchange.cpp b/src/mongo/db/exec/sbe/stages/exchange.cpp index a2e932d3553..ed52a7ead43 100644 --- a/src/mongo/db/exec/sbe/stages/exchange.cpp +++ b/src/mongo/db/exec/sbe/stages/exchange.cpp @@ -456,7 +456,7 @@ void ExchangeProducer::start(OperationContext* opCtx, std::unique_ptr<PlanStage> producer) { ExchangeProducer* p = static_cast<ExchangeProducer*>(producer.get()); - p->attachFromOperationContext(opCtx); + p->attachToOperationContext(opCtx); try { p->prepare(ctx); diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.cpp b/src/mongo/db/exec/sbe/stages/ix_scan.cpp index 1453ed0b8c3..a1d4fb3fc97 100644 --- a/src/mongo/db/exec/sbe/stages/ix_scan.cpp +++ b/src/mongo/db/exec/sbe/stages/ix_scan.cpp @@ -34,6 +34,7 @@ #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/exec/sbe/expressions/expression.h" #include "mongo/db/exec/sbe/values/bson.h" +#include "mongo/db/exec/trial_run_tracker.h" #include "mongo/db/index/index_access_method.h" #include "mongo/db/repl/replication_coordinator.h" @@ -48,7 +49,6 @@ IndexScanStage::IndexScanStage(const NamespaceStringOrUUID& name, boost::optional<value::SlotId> seekKeySlotLow, boost::optional<value::SlotId> seekKeySlotHigh, PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker, PlanNodeId nodeId) : PlanStage(seekKeySlotLow ? "ixseek"_sd : "ixscan"_sd, yieldPolicy, nodeId), _name(name), @@ -59,8 +59,7 @@ IndexScanStage::IndexScanStage(const NamespaceStringOrUUID& name, _indexKeysToInclude(indexKeysToInclude), _vars(std::move(vars)), _seekKeySlotLow(seekKeySlotLow), - _seekKeySlotHigh(seekKeySlotHigh), - _tracker(tracker) { + _seekKeySlotHigh(seekKeySlotHigh) { // The valid state is when both boundaries, or none is set, or only low key is set. invariant((_seekKeySlotLow && _seekKeySlotHigh) || (!_seekKeySlotLow && !_seekKeySlotHigh) || (_seekKeySlotLow && !_seekKeySlotHigh)); @@ -79,7 +78,6 @@ std::unique_ptr<PlanStage> IndexScanStage::clone() const { _seekKeySlotLow, _seekKeySlotHigh, _yieldPolicy, - _tracker, _commonStats.nodeId); } @@ -129,6 +127,7 @@ void IndexScanStage::doSaveState() { _coll.reset(); } + void IndexScanStage::doRestoreState() { invariant(_opCtx); invariant(!_coll); @@ -153,12 +152,21 @@ void IndexScanStage::doDetachFromOperationContext() { _cursor->detachFromOperationContext(); } } -void IndexScanStage::doAttachFromOperationContext(OperationContext* opCtx) { + +void IndexScanStage::doAttachToOperationContext(OperationContext* opCtx) { if (_cursor) { _cursor->reattachToOperationContext(opCtx); } } +void IndexScanStage::doDetachFromTrialRunTracker() { + _tracker = nullptr; +} + +void IndexScanStage::doAttachToTrialRunTracker(TrialRunTracker* tracker) { + _tracker = tracker; +} + void IndexScanStage::open(bool reOpen) { _commonStats.opens++; @@ -284,7 +292,7 @@ PlanState IndexScanStage::getNext() { _nextRecord->keyString, *_ordering, &_valuesBuffer, &_accessors, _indexKeysToInclude); } - if (_tracker && _tracker->trackProgress<TrialRunProgressTracker::kNumReads>(1)) { + if (_tracker && _tracker->trackProgress<TrialRunTracker::kNumReads>(1)) { // If we're collecting execution stats during multi-planning and reached the end of the // trial period (trackProgress() will return 'true' in this case), then we can reset the // tracker. Note that a trial period is executed only once per a PlanStge tree, and once diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.h b/src/mongo/db/exec/sbe/stages/ix_scan.h index b08fd2a9440..92279f05132 100644 --- a/src/mongo/db/exec/sbe/stages/ix_scan.h +++ b/src/mongo/db/exec/sbe/stages/ix_scan.h @@ -32,7 +32,6 @@ #include "mongo/bson/ordering.h" #include "mongo/db/db_raii.h" #include "mongo/db/exec/sbe/stages/stages.h" -#include "mongo/db/exec/trial_run_progress_tracker.h" #include "mongo/db/storage/record_store.h" #include "mongo/db/storage/sorted_data_interface.h" @@ -70,7 +69,6 @@ public: boost::optional<value::SlotId> seekKeySlotLow, boost::optional<value::SlotId> seekKeySlotHigh, PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker, PlanNodeId nodeId); std::unique_ptr<PlanStage> clone() const final; @@ -89,7 +87,9 @@ protected: void doSaveState() override; void doRestoreState() override; void doDetachFromOperationContext() override; - void doAttachFromOperationContext(OperationContext* opCtx) override; + void doAttachToOperationContext(OperationContext* opCtx) override; + void doDetachFromTrialRunTracker() override; + void doAttachToTrialRunTracker(TrialRunTracker* tracker) override; private: const NamespaceStringOrUUID _name; @@ -133,6 +133,6 @@ private: // If provided, used during a trial run to accumulate certain execution stats. Once the trial // run is complete, this pointer is reset to nullptr. - TrialRunProgressTracker* _tracker{nullptr}; + TrialRunTracker* _tracker{nullptr}; }; } // namespace mongo::sbe diff --git a/src/mongo/db/exec/sbe/stages/scan.cpp b/src/mongo/db/exec/sbe/stages/scan.cpp index 7556cd8ef4b..2b7b62240d9 100644 --- a/src/mongo/db/exec/sbe/stages/scan.cpp +++ b/src/mongo/db/exec/sbe/stages/scan.cpp @@ -32,6 +32,7 @@ #include "mongo/db/exec/sbe/stages/scan.h" #include "mongo/db/exec/sbe/expressions/expression.h" +#include "mongo/db/exec/trial_run_tracker.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/util/str.h" @@ -45,7 +46,6 @@ ScanStage::ScanStage(const NamespaceStringOrUUID& name, boost::optional<value::SlotId> seekKeySlot, bool forward, PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker, PlanNodeId nodeId, ScanOpenCallback openCallback) : PlanStage(seekKeySlot ? "seek"_sd : "scan"_sd, yieldPolicy, nodeId), @@ -56,7 +56,6 @@ ScanStage::ScanStage(const NamespaceStringOrUUID& name, _vars(std::move(vars)), _seekKeySlot(seekKeySlot), _forward(forward), - _tracker(tracker), _openCallback(openCallback) { invariant(_fields.size() == _vars.size()); invariant(!_seekKeySlot || _forward); @@ -71,7 +70,6 @@ std::unique_ptr<PlanStage> ScanStage::clone() const { _seekKeySlot, _forward, _yieldPolicy, - _tracker, _commonStats.nodeId, _openCallback); } @@ -151,12 +149,20 @@ void ScanStage::doDetachFromOperationContext() { } } -void ScanStage::doAttachFromOperationContext(OperationContext* opCtx) { +void ScanStage::doAttachToOperationContext(OperationContext* opCtx) { if (_cursor) { _cursor->reattachToOperationContext(opCtx); } } +void ScanStage::doDetachFromTrialRunTracker() { + _tracker = nullptr; +} + +void ScanStage::doAttachToTrialRunTracker(TrialRunTracker* tracker) { + _tracker = tracker; +} + void ScanStage::open(bool reOpen) { _commonStats.opens++; invariant(_opCtx); @@ -251,7 +257,7 @@ PlanState ScanStage::getNext() { } } - if (_tracker && _tracker->trackProgress<TrialRunProgressTracker::kNumReads>(1)) { + if (_tracker && _tracker->trackProgress<TrialRunTracker::kNumReads>(1)) { // If we're collecting execution stats during multi-planning and reached the end of the // trial period (trackProgress() will return 'true' in this case), then we can reset the // tracker. Note that a trial period is executed only once per a PlanStge tree, and once @@ -448,7 +454,7 @@ void ParallelScanStage::doDetachFromOperationContext() { } } -void ParallelScanStage::doAttachFromOperationContext(OperationContext* opCtx) { +void ParallelScanStage::doAttachToOperationContext(OperationContext* opCtx) { if (_cursor) { _cursor->reattachToOperationContext(opCtx); } diff --git a/src/mongo/db/exec/sbe/stages/scan.h b/src/mongo/db/exec/sbe/stages/scan.h index 30dc58edded..935366c7da7 100644 --- a/src/mongo/db/exec/sbe/stages/scan.h +++ b/src/mongo/db/exec/sbe/stages/scan.h @@ -32,7 +32,6 @@ #include "mongo/db/db_raii.h" #include "mongo/db/exec/sbe/stages/stages.h" #include "mongo/db/exec/sbe/values/bson.h" -#include "mongo/db/exec/trial_run_progress_tracker.h" #include "mongo/db/storage/record_store.h" namespace mongo { @@ -49,7 +48,6 @@ public: boost::optional<value::SlotId> seekKeySlot, bool forward, PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker, PlanNodeId nodeId, ScanOpenCallback openCallback = {}); @@ -69,7 +67,9 @@ protected: void doSaveState() override; void doRestoreState() override; void doDetachFromOperationContext() override; - void doAttachFromOperationContext(OperationContext* opCtx) override; + void doAttachToOperationContext(OperationContext* opCtx) override; + void doDetachFromTrialRunTracker() override; + void doAttachToTrialRunTracker(TrialRunTracker* tracker) override; private: const NamespaceStringOrUUID _name; @@ -82,7 +82,7 @@ private: // If provided, used during a trial run to accumulate certain execution stats. Once the trial // run is complete, this pointer is reset to nullptr. - TrialRunProgressTracker* _tracker{nullptr}; + TrialRunTracker* _tracker{nullptr}; ScanOpenCallback _openCallback; @@ -148,7 +148,7 @@ protected: void doSaveState() final; void doRestoreState() final; void doDetachFromOperationContext() final; - void doAttachFromOperationContext(OperationContext* opCtx) final; + void doAttachToOperationContext(OperationContext* opCtx) final; private: boost::optional<Record> nextRange(); diff --git a/src/mongo/db/exec/sbe/stages/sort.cpp b/src/mongo/db/exec/sbe/stages/sort.cpp index a37b30da60b..150b91b1f53 100644 --- a/src/mongo/db/exec/sbe/stages/sort.cpp +++ b/src/mongo/db/exec/sbe/stages/sort.cpp @@ -32,6 +32,7 @@ #include "mongo/db/exec/sbe/stages/sort.h" #include "mongo/db/exec/sbe/expressions/expression.h" +#include "mongo/db/exec/trial_run_tracker.h" #include "mongo/util/str.h" namespace { @@ -52,15 +53,13 @@ SortStage::SortStage(std::unique_ptr<PlanStage> input, size_t limit, size_t memoryLimit, bool allowDiskUse, - TrialRunProgressTracker* tracker, PlanNodeId planNodeId) : PlanStage("sort"_sd, planNodeId), _obs(std::move(obs)), _dirs(std::move(dirs)), _vals(std::move(vals)), _allowDiskUse(allowDiskUse), - _mergeData({0, 0}), - _tracker(tracker) { + _mergeData({0, 0}) { _children.emplace_back(std::move(input)); invariant(_obs.size() == _dirs.size()); @@ -69,7 +68,7 @@ SortStage::SortStage(std::unique_ptr<PlanStage> input, _specificStats.maxMemoryUsageBytes = memoryLimit; } -SortStage ::~SortStage() {} +SortStage::~SortStage() {} std::unique_ptr<PlanStage> SortStage::clone() const { return std::make_unique<SortStage>(_children[0]->clone(), @@ -79,7 +78,6 @@ std::unique_ptr<PlanStage> SortStage::clone() const { _specificStats.limit, _specificStats.maxMemoryUsageBytes, _allowDiskUse, - _tracker, _commonStats.nodeId); } @@ -149,6 +147,14 @@ void SortStage::makeSorter() { _mergeIt.reset(); } +void SortStage::doDetachFromTrialRunTracker() { + _tracker = nullptr; +} + +void SortStage::doAttachToTrialRunTracker(TrialRunTracker* tracker) { + _tracker = tracker; +} + void SortStage::open(bool reOpen) { _commonStats.opens++; _children[0]->open(reOpen); @@ -174,7 +180,7 @@ void SortStage::open(bool reOpen) { // TODO SERVER-51815: count total mem usage for specificStats. _sorter->emplace(std::move(keys), std::move(vals)); - if (_tracker && _tracker->trackProgress<TrialRunProgressTracker::kNumResults>(1)) { + if (_tracker && _tracker->trackProgress<TrialRunTracker::kNumResults>(1)) { // If we either hit the maximum number of document to return during the trial run, or // if we've performed enough physical reads, stop populating the sort heap and bail out // from the trial run by raising a special exception to signal a runtime planner that diff --git a/src/mongo/db/exec/sbe/stages/sort.h b/src/mongo/db/exec/sbe/stages/sort.h index acb90a69050..fbe92d7e4ed 100644 --- a/src/mongo/db/exec/sbe/stages/sort.h +++ b/src/mongo/db/exec/sbe/stages/sort.h @@ -30,7 +30,6 @@ #pragma once #include "mongo/db/exec/sbe/stages/stages.h" -#include "mongo/db/exec/trial_run_progress_tracker.h" namespace mongo { template <typename Key, typename Value> @@ -49,7 +48,6 @@ public: size_t limit, size_t memoryLimit, bool allowDiskUse, - TrialRunProgressTracker* tracker, PlanNodeId planNodeId); ~SortStage(); @@ -66,6 +64,10 @@ public: const SpecificStats* getSpecificStats() const final; std::vector<DebugPrinter::Block> debugPrint() const final; +protected: + void doDetachFromTrialRunTracker() override; + void doAttachToTrialRunTracker(TrialRunTracker* tracker) override; + private: void makeSorter(); @@ -90,6 +92,6 @@ private: // If provided, used during a trial run to accumulate certain execution stats. Once the trial // run is complete, this pointer is reset to nullptr. - TrialRunProgressTracker* _tracker{nullptr}; + TrialRunTracker* _tracker{nullptr}; }; } // namespace mongo::sbe diff --git a/src/mongo/db/exec/sbe/stages/stages.h b/src/mongo/db/exec/sbe/stages/stages.h index 9b84ef87bb8..3b2fb96ab2e 100644 --- a/src/mongo/db/exec/sbe/stages/stages.h +++ b/src/mongo/db/exec/sbe/stages/stages.h @@ -34,6 +34,7 @@ #include "mongo/db/exec/sbe/values/slot.h" #include "mongo/db/exec/sbe/values/value.h" #include "mongo/db/exec/scoped_timer.h" +#include "mongo/db/exec/trial_run_tracker.h" #include "mongo/db/operation_context.h" #include "mongo/db/query/plan_yield_policy.h" #include "mongo/util/str.h" @@ -86,17 +87,17 @@ public: * * Propagates to all children, then calls doReattachToOperationContext(). */ - void attachFromOperationContext(OperationContext* opCtx) { + void attachToOperationContext(OperationContext* opCtx) { invariant(opCtx); invariant(!_opCtx); auto stage = static_cast<T*>(this); for (auto&& child : stage->_children) { - child->attachFromOperationContext(opCtx); + child->attachToOperationContext(opCtx); } _opCtx = opCtx; - stage->doAttachFromOperationContext(opCtx); + stage->doAttachToOperationContext(opCtx); } protected: @@ -214,6 +215,24 @@ public: } } + void detachFromTrialRunTracker() { + auto stage = static_cast<T*>(this); + for (auto&& child : stage->_children) { + child->detachFromTrialRunTracker(); + } + + stage->doDetachFromTrialRunTracker(); + } + + void attachToTrialRunTracker(TrialRunTracker* tracker) { + auto stage = static_cast<T*>(this); + for (auto&& child : stage->_children) { + child->attachToTrialRunTracker(tracker); + } + + stage->doAttachToTrialRunTracker(tracker); + } + protected: PlanState trackPlanState(PlanState state) { if (state == PlanState::IS_EOF) { @@ -336,7 +355,9 @@ protected: virtual void doSaveState() {} virtual void doRestoreState() {} virtual void doDetachFromOperationContext() {} - virtual void doAttachFromOperationContext(OperationContext* opCtx) {} + virtual void doAttachToOperationContext(OperationContext* opCtx) {} + virtual void doDetachFromTrialRunTracker() {} + virtual void doAttachToTrialRunTracker(TrialRunTracker* tracker) {} std::vector<std::unique_ptr<PlanStage>> _children; }; diff --git a/src/mongo/db/exec/trial_run_progress_tracker.h b/src/mongo/db/exec/trial_run_tracker.h index a9bf9110e24..45a1f137e77 100644 --- a/src/mongo/db/exec/trial_run_progress_tracker.h +++ b/src/mongo/db/exec/trial_run_tracker.h @@ -40,7 +40,7 @@ namespace mongo { * processed, or the number of physical reads performed, and the tracker will use it to check if * the execution plan has progressed enough. */ -class TrialRunProgressTracker final { +class TrialRunTracker final { public: /** * The type of metric which can be collected and tracked during a trial run. @@ -57,7 +57,7 @@ public: template <typename... MaxMetrics, std::enable_if_t<sizeof...(MaxMetrics) == TrialRunMetric::kLastElem, int> = 0> - TrialRunProgressTracker(MaxMetrics... maxMetrics) : _maxMetrics{maxMetrics...} {} + TrialRunTracker(MaxMetrics... maxMetrics) : _maxMetrics{maxMetrics...} {} /** * Increments the trial run metric specified as a template parameter 'metric' by the diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp index fa90e211989..2e9d425424f 100644 --- a/src/mongo/db/query/get_executor.cpp +++ b/src/mongo/db/query/get_executor.cpp @@ -901,7 +901,8 @@ public: protected: std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData> buildExecutableTree( const QuerySolution& solution) const final { - return buildExecutableTree(solution, false); + return stage_builder::buildSlotBasedExecutableTree( + _opCtx, _collection, *_cq, solution, _yieldPolicy); } std::unique_ptr<SlotBasedPrepareExecutionResult> buildIdHackPlan( @@ -920,7 +921,7 @@ protected: const QueryPlannerParams& plannerParams, size_t decisionWorks) final { auto result = makeResult(); - auto execTree = buildExecutableTree(*solution, true); + auto execTree = buildExecutableTree(*solution); result->emplace(std::move(execTree), std::move(solution)); result->setDecisionWorks(decisionWorks); return result; @@ -943,18 +944,11 @@ protected: solutions[ix]->cacheData->indexFilterApplied = plannerParams.indexFiltersApplied; } - auto execTree = buildExecutableTree(*solutions[ix], true); + auto execTree = buildExecutableTree(*solutions[ix]); result->emplace(std::move(execTree), std::move(solutions[ix])); } return result; } - -private: - std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData> buildExecutableTree( - const QuerySolution& solution, bool needsTrialRunProgressTracker) const { - return stage_builder::buildSlotBasedExecutableTree( - _opCtx, _collection, *_cq, solution, _yieldPolicy, needsTrialRunProgressTracker); - } }; StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getClassicExecutor( diff --git a/src/mongo/db/query/plan_executor_sbe.cpp b/src/mongo/db/query/plan_executor_sbe.cpp index 7f2b41ea598..cf87c410051 100644 --- a/src/mongo/db/query/plan_executor_sbe.cpp +++ b/src/mongo/db/query/plan_executor_sbe.cpp @@ -131,7 +131,7 @@ void PlanExecutorSBE::detachFromOperationContext() { void PlanExecutorSBE::reattachToOperationContext(OperationContext* opCtx) { invariant(!_opCtx); invariant(_root); - _root->attachFromOperationContext(opCtx); + _root->attachToOperationContext(opCtx); _opCtx = opCtx; } diff --git a/src/mongo/db/query/sbe_cached_solution_planner.cpp b/src/mongo/db/query/sbe_cached_solution_planner.cpp index 80214e99d06..aece175a58f 100644 --- a/src/mongo/db/query/sbe_cached_solution_planner.cpp +++ b/src/mongo/db/query/sbe_cached_solution_planner.cpp @@ -120,7 +120,7 @@ CandidatePlans CachedSolutionPlanner::replan(bool shouldCache) const { if (solutions.size() == 1) { // Only one possible plan. Build the stages from the solution. auto&& [root, data] = stage_builder::buildSlotBasedExecutableTree( - _opCtx, _collection, _cq, *solutions[0], _yieldPolicy, true); + _opCtx, _collection, _cq, *solutions[0], _yieldPolicy); prepareExecutionPlan(root.get(), &data); auto explainer = plan_explainer_factory::make(root.get(), solutions[0].get()); @@ -145,7 +145,7 @@ CandidatePlans CachedSolutionPlanner::replan(bool shouldCache) const { } roots.push_back(stage_builder::buildSlotBasedExecutableTree( - _opCtx, _collection, _cq, *solution, _yieldPolicy, true)); + _opCtx, _collection, _cq, *solution, _yieldPolicy)); } const auto cachingMode = diff --git a/src/mongo/db/query/sbe_runtime_planner.cpp b/src/mongo/db/query/sbe_runtime_planner.cpp index 2b81f7abaf5..ace0f3df706 100644 --- a/src/mongo/db/query/sbe_runtime_planner.cpp +++ b/src/mongo/db/query/sbe_runtime_planner.cpp @@ -33,13 +33,14 @@ #include "mongo/db/catalog/collection.h" #include "mongo/db/exec/sbe/expressions/expression.h" #include "mongo/db/exec/trial_period_utils.h" +#include "mongo/db/exec/trial_run_tracker.h" #include "mongo/db/query/plan_executor_sbe.h" namespace mongo::sbe { namespace { /** * Fetches a next document form the given plan stage tree and returns 'true' if the plan stage - * returns EOF, or throws 'TrialRunProgressTracker::EarlyExitException' exception. Otherwise, the + * returns EOF, or throws 'TrialRunTracker::EarlyExitException' exception. Otherwise, the * loaded document is placed into the candidate's plan result queue. * * If the plan stage throws a 'QueryExceededMemoryLimitNoDiskUseAllowed', it will be caught and the @@ -116,9 +117,19 @@ std::vector<plan_ranker::CandidatePlan> BaseRuntimePlanner::collectExecutionStat std::vector<plan_ranker::CandidatePlan> candidates; std::vector<std::pair<sbe::value::SlotAccessor*, sbe::value::SlotAccessor*>> slots; + std::vector<std::unique_ptr<TrialRunTracker>> trialRunTrackers; + + const auto maxNumResults{trial_period::getTrialPeriodNumToReturn(_cq)}; + const auto maxNumReads{trial_period::getTrialPeriodMaxWorks(_opCtx, _collection)}; for (size_t ix = 0; ix < roots.size(); ++ix) { auto&& [root, data] = roots[ix]; + + // Attach a unique TrialRunTracker to each SBE plan. + auto tracker = std::make_unique<TrialRunTracker>(maxNumResults, maxNumReads); + root->attachToTrialRunTracker(tracker.get()); + trialRunTrackers.emplace_back(std::move(tracker)); + auto [resultSlot, recordIdSlot, exitedEarly] = prepareExecutionPlan(root.get(), &data); candidates.push_back( @@ -128,7 +139,6 @@ std::vector<plan_ranker::CandidatePlan> BaseRuntimePlanner::collectExecutionStat auto done{false}; size_t numFailures{0}; - const auto maxNumResults{trial_period::getTrialPeriodNumToReturn(_cq)}; for (size_t it = 0; it < maxNumResults && !done; ++it) { for (size_t ix = 0; ix < candidates.size(); ++ix) { // Even if we had a candidate plan that exited early, we still want continue the trial @@ -146,6 +156,11 @@ std::vector<plan_ranker::CandidatePlan> BaseRuntimePlanner::collectExecutionStat } } + // Detach each SBE plan's TrialRunTracker. + for (size_t ix = 0; ix < candidates.size(); ++ix) { + candidates[ix].root->detachFromTrialRunTracker(); + } + // Make sure we have at least one plan which hasn't failed. uassert(4822873, "Runtime planner encountered a failure while collecting execution stats", diff --git a/src/mongo/db/query/sbe_stage_builder.cpp b/src/mongo/db/query/sbe_stage_builder.cpp index 320e8289c1d..32ac09989f4 100644 --- a/src/mongo/db/query/sbe_stage_builder.cpp +++ b/src/mongo/db/query/sbe_stage_builder.cpp @@ -121,20 +121,11 @@ SlotBasedStageBuilder::SlotBasedStageBuilder(OperationContext* opCtx, const CanonicalQuery& cq, const QuerySolution& solution, PlanYieldPolicySBE* yieldPolicy, - bool needsTrialRunProgressTracker, ShardFiltererFactoryInterface* shardFiltererFactory) : StageBuilder(opCtx, collection, cq, solution), _yieldPolicy(yieldPolicy), _data(makeRuntimeEnvironment(_opCtx, &_slotIdGenerator)), _shardFiltererFactory(shardFiltererFactory) { - - if (needsTrialRunProgressTracker) { - const auto maxNumResults{trial_period::getTrialPeriodNumToReturn(_cq)}; - const auto maxNumReads{trial_period::getTrialPeriodMaxWorks(_opCtx, _collection)}; - _data.trialRunProgressTracker = - std::make_unique<TrialRunProgressTracker>(maxNumResults, maxNumReads); - } - // SERVER-52803: In the future if we need to gather more information from the QuerySolutionNode // tree, rather than doing one-off scans for each piece of information, we should add a formal // analysis pass here. @@ -193,8 +184,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> SlotBasedStageBuilder &_frameIdGenerator, _yieldPolicy, _data.env, - reqs.getIsTailableCollScanResumeBranch(), - _data.trialRunProgressTracker.get()); + reqs.getIsTailableCollScanResumeBranch()); if (reqs.has(kReturnKey)) { // Assign the 'returnKeySlot' to be the empty object. @@ -255,14 +245,8 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> SlotBasedStageBuilder // Index scans cannot produce an oplogTsSlot, so assert that the caller doesn't need it. invariant(!reqs.has(kOplogTs)); - return generateIndexScan(_opCtx, - _collection, - ixn, - reqs, - &_slotIdGenerator, - &_spoolIdGenerator, - _yieldPolicy, - _data.trialRunProgressTracker.get()); + return generateIndexScan( + _opCtx, _collection, ixn, reqs, &_slotIdGenerator, &_spoolIdGenerator, _yieldPolicy); } std::tuple<sbe::value::SlotId, sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> @@ -283,7 +267,6 @@ SlotBasedStageBuilder::makeLoopJoinForFetch(std::unique_ptr<sbe::PlanStage> inpu seekKeySlot, true, nullptr, - _data.trialRunProgressTracker.get(), planNodeId); // Get the recordIdSlot from the outer side (e.g., IXSCAN) and feed it to the inner side, @@ -493,7 +476,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> SlotBasedStageBuilder sn->limit ? sn->limit : std::numeric_limits<std::size_t>::max(), sn->maxMemoryUsageBytes, _cq.getExpCtx()->allowDiskUse, - _data.trialRunProgressTracker.get(), root->nodeId()); return {std::move(inputStage), std::move(outputs)}; @@ -844,7 +826,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> SlotBasedStageBuilder boost::none, // recordSlot &_slotIdGenerator, _yieldPolicy, - _data.trialRunProgressTracker.get(), root->nodeId()); indexScanList.push_back(std::move(ixscan)); ixscanOutputSlots.push_back(sbe::makeSV(recordIdSlot)); diff --git a/src/mongo/db/query/sbe_stage_builder.h b/src/mongo/db/query/sbe_stage_builder.h index ee13f494280..61b728f5d9b 100644 --- a/src/mongo/db/query/sbe_stage_builder.h +++ b/src/mongo/db/query/sbe_stage_builder.h @@ -33,7 +33,6 @@ #include "mongo/db/exec/sbe/values/slot.h" #include "mongo/db/exec/sbe/values/value.h" #include "mongo/db/exec/trial_period_utils.h" -#include "mongo/db/exec/trial_run_progress_tracker.h" #include "mongo/db/query/plan_yield_policy_sbe.h" #include "mongo/db/query/shard_filterer_factory_interface.h" #include "mongo/db/query/stage_builder.h" @@ -231,11 +230,6 @@ struct PlanStageData { sbe::RuntimeEnvironment* env{nullptr}; sbe::CompileCtx ctx; - // Used during the trial run of the runtime planner to track progress of the work done so far. - // Some PlanStages hold pointers to the TrialRunProgressTracker object and call methods on it - // when the SBE plan is executed. - std::unique_ptr<TrialRunProgressTracker> trialRunProgressTracker; - bool shouldTrackLatestOplogTimestamp{false}; bool shouldTrackResumeToken{false}; bool shouldUseTailableScan{false}; @@ -256,7 +250,6 @@ public: const CanonicalQuery& cq, const QuerySolution& solution, PlanYieldPolicySBE* yieldPolicy, - bool needsTrialRunProgressTracker, ShardFiltererFactoryInterface* shardFilterer); std::unique_ptr<sbe::PlanStage> build(const QuerySolutionNode* root) final; diff --git a/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp b/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp index de9fa564a32..ef882219f37 100644 --- a/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp +++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp @@ -122,8 +122,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateOptimizedOplo sbe::value::FrameIdGenerator* frameIdGenerator, PlanYieldPolicy* yieldPolicy, sbe::RuntimeEnvironment* env, - bool isTailableResumeBranch, - TrialRunProgressTracker* tracker) { + bool isTailableResumeBranch) { invariant(collection->ns().isOplog()); // The minTs and maxTs optimizations are not compatible with resumeAfterRecordId and can only // be done for a forward scan. @@ -174,7 +173,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateOptimizedOplo seekRecordIdSlot, true /* forward */, yieldPolicy, - tracker, csn->nodeId(), makeOpenCallbackIfNeeded(collection, csn)); @@ -278,7 +276,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateOptimizedOplo seekRecordIdSlot, true /* forward */, yieldPolicy, - tracker, csn->nodeId()), sbe::makeSV(), sbe::makeSV(*seekRecordIdSlot), @@ -314,8 +311,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateGenericCollSc sbe::value::FrameIdGenerator* frameIdGenerator, PlanYieldPolicy* yieldPolicy, sbe::RuntimeEnvironment* env, - bool isTailableResumeBranch, - TrialRunProgressTracker* tracker) { + bool isTailableResumeBranch) { const auto forward = csn->direction == CollectionScanParams::FORWARD; invariant(!csn->shouldTrackLatestOplogTimestamp || collection->ns().isOplog()); @@ -348,7 +344,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateGenericCollSc seekRecordIdSlot, forward, yieldPolicy, - tracker, csn->nodeId(), makeOpenCallbackIfNeeded(collection, csn)); @@ -381,7 +376,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateGenericCollSc seekSlot, forward, yieldPolicy, - tracker, csn->nodeId()), sbe::makeSV(seekSlot), @@ -467,8 +461,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateCollScan( sbe::value::FrameIdGenerator* frameIdGenerator, PlanYieldPolicy* yieldPolicy, sbe::RuntimeEnvironment* env, - bool isTailableResumeBranch, - TrialRunProgressTracker* tracker) { + bool isTailableResumeBranch) { if (csn->minTs || csn->maxTs) { return generateOptimizedOplogScan(opCtx, collection, @@ -477,8 +470,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateCollScan( frameIdGenerator, yieldPolicy, env, - isTailableResumeBranch, - tracker); + isTailableResumeBranch); } else { return generateGenericCollScan(opCtx, collection, @@ -487,8 +479,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateCollScan( frameIdGenerator, yieldPolicy, env, - isTailableResumeBranch, - tracker); + isTailableResumeBranch); } } } // namespace mongo::stage_builder diff --git a/src/mongo/db/query/sbe_stage_builder_coll_scan.h b/src/mongo/db/query/sbe_stage_builder_coll_scan.h index 86c56fd6154..1a1683d986f 100644 --- a/src/mongo/db/query/sbe_stage_builder_coll_scan.h +++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.h @@ -32,7 +32,6 @@ #include "mongo/db/exec/sbe/expressions/expression.h" #include "mongo/db/exec/sbe/stages/stages.h" #include "mongo/db/exec/sbe/values/value.h" -#include "mongo/db/exec/trial_run_progress_tracker.h" #include "mongo/db/query/query_solution.h" namespace mongo::stage_builder { @@ -59,7 +58,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateCollScan( sbe::value::FrameIdGenerator* frameIdGenerator, PlanYieldPolicy* yieldPolicy, sbe::RuntimeEnvironment* env, - bool isTailableResumeBranch, - TrialRunProgressTracker* tracker); + bool isTailableResumeBranch); } // namespace mongo::stage_builder diff --git a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp index df303b661b0..3512a24296f 100644 --- a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp +++ b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp @@ -277,7 +277,6 @@ generateOptimizedMultiIntervalIndexScan( sbe::value::SlotVector indexKeySlots, sbe::value::SlotIdGenerator* slotIdGenerator, PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker, PlanNodeId planNodeId) { using namespace std::literals; @@ -345,7 +344,6 @@ generateOptimizedMultiIntervalIndexScan( lowKeySlot, highKeySlot, yieldPolicy, - tracker, planNodeId); // Finally, get the keys from the outer side and feed them to the inner side (ixscan). @@ -399,7 +397,6 @@ makeRecursiveBranchForGenericIndexScan(const CollectionPtr& collection, sbe::value::SlotVector savedIndexKeySlots, sbe::value::SlotIdGenerator* slotIdGenerator, PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker, PlanNodeId planNodeId) { auto resultSlot = slotIdGenerator->generate(); @@ -428,7 +425,6 @@ makeRecursiveBranchForGenericIndexScan(const CollectionPtr& collection, lowKeySlot, boost::none, yieldPolicy, - tracker, planNodeId); // Get the low key from the outer side and feed it to the inner side (ixscan). @@ -526,8 +522,7 @@ generateGenericMultiIntervalIndexScan(const CollectionPtr& collection, sbe::value::SlotVector indexKeySlots, sbe::value::SlotIdGenerator* slotIdGenerator, sbe::value::SpoolIdGenerator* spoolIdGenerator, - PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker) { + PlanYieldPolicy* yieldPolicy) { using namespace std::literals; @@ -577,7 +572,6 @@ generateGenericMultiIntervalIndexScan(const CollectionPtr& collection, savedIndexKeySlots, slotIdGenerator, yieldPolicy, - tracker, ixn->nodeId()); // Construct a union stage from the two branches. @@ -630,7 +624,6 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleInt boost::optional<sbe::value::SlotId> recordSlot, sbe::value::SlotIdGenerator* slotIdGenerator, PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker, PlanNodeId planNodeId) { auto recordIdSlot = slotIdGenerator->generate(); auto lowKeySlot = slotIdGenerator->generate(); @@ -663,7 +656,6 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleInt lowKeySlot, highKeySlot, yieldPolicy, - tracker, planNodeId); // Finally, get the keys from the outer side and feed them to the inner side. @@ -683,8 +675,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan( PlanStageReqs reqs, sbe::value::SlotIdGenerator* slotIdGenerator, sbe::value::SpoolIdGenerator* spoolIdGenerator, - PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker) { + PlanYieldPolicy* yieldPolicy) { uassert(4822864, "Index scans with a filter are not supported in SBE", !ixn->filter); auto descriptor = @@ -746,7 +737,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan( boost::none, // recordSlot slotIdGenerator, yieldPolicy, - tracker, ixn->nodeId()); outputs.set(PlanStageSlots::kRecordId, recordIdSlot); @@ -763,7 +753,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan( indexKeySlots, slotIdGenerator, yieldPolicy, - tracker, ixn->nodeId()); outputs.set(PlanStageSlots::kRecordId, recordIdSlot); @@ -779,8 +768,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan( indexKeySlots, slotIdGenerator, spoolIdGenerator, - yieldPolicy, - tracker); + yieldPolicy); outputs.set(PlanStageSlots::kRecordId, recordIdSlot); } diff --git a/src/mongo/db/query/sbe_stage_builder_index_scan.h b/src/mongo/db/query/sbe_stage_builder_index_scan.h index 31d6187b632..ab54dfa02cf 100644 --- a/src/mongo/db/query/sbe_stage_builder_index_scan.h +++ b/src/mongo/db/query/sbe_stage_builder_index_scan.h @@ -31,7 +31,6 @@ #include "mongo/db/exec/sbe/stages/stages.h" #include "mongo/db/exec/sbe/values/value.h" -#include "mongo/db/exec/trial_run_progress_tracker.h" #include "mongo/db/query/query_solution.h" namespace mongo::stage_builder { @@ -56,8 +55,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan( PlanStageReqs reqs, sbe::value::SlotIdGenerator* slotIdGenerator, sbe::value::SpoolIdGenerator* spoolIdGenerator, - PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker); + PlanYieldPolicy* yieldPolicy); /** * Constructs the most simple version of an index scan from the single interval index bounds. The @@ -88,7 +86,6 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleInt boost::optional<sbe::value::SlotId> recordSlot, sbe::value::SlotIdGenerator* slotIdGenerator, PlanYieldPolicy* yieldPolicy, - TrialRunProgressTracker* tracker, PlanNodeId nodeId); } // namespace mongo::stage_builder diff --git a/src/mongo/db/query/sbe_stage_builder_test_fixture.cpp b/src/mongo/db/query/sbe_stage_builder_test_fixture.cpp index 97dc4ffcd79..efb6c08639f 100644 --- a/src/mongo/db/query/sbe_stage_builder_test_fixture.cpp +++ b/src/mongo/db/query/sbe_stage_builder_test_fixture.cpp @@ -59,7 +59,6 @@ SbeStageBuilderTestFixture::buildPlanStage( *statusWithCQ.getValue(), *querySolution, nullptr /* YieldPolicy */, - false, shardFiltererInterface.get()}; auto stage = builder.build(querySolution->root()); diff --git a/src/mongo/db/query/sbe_sub_planner.cpp b/src/mongo/db/query/sbe_sub_planner.cpp index ad3ed1daed5..e9350108bd9 100644 --- a/src/mongo/db/query/sbe_sub_planner.cpp +++ b/src/mongo/db/query/sbe_sub_planner.cpp @@ -57,7 +57,7 @@ CandidatePlans SubPlanner::plan( std::vector<std::pair<std::unique_ptr<PlanStage>, stage_builder::PlanStageData>> roots; for (auto&& solution : solutions) { roots.push_back(stage_builder::buildSlotBasedExecutableTree( - _opCtx, _collection, *cq, *solution, _yieldPolicy, true)); + _opCtx, _collection, *cq, *solution, _yieldPolicy)); } // Ensure that no previous plans are registered to yield while we multi plan each branch. @@ -93,7 +93,7 @@ CandidatePlans SubPlanner::plan( // Build a plan stage tree from a composite solution. auto compositeSolution = std::move(subplanSelectStat.getValue()); auto&& [root, data] = stage_builder::buildSlotBasedExecutableTree( - _opCtx, _collection, _cq, *compositeSolution, _yieldPolicy, false); + _opCtx, _collection, _cq, *compositeSolution, _yieldPolicy); prepareExecutionPlan(root.get(), &data); return {makeVector<plan_ranker::CandidatePlan>(plan_ranker::CandidatePlan{ std::move(compositeSolution), std::move(root), std::move(data)}), @@ -107,7 +107,7 @@ CandidatePlans SubPlanner::planWholeQuery() const { // Only one possible plan. Build the stages from the solution. if (solutions.size() == 1) { auto&& [root, data] = stage_builder::buildSlotBasedExecutableTree( - _opCtx, _collection, _cq, *solutions[0], _yieldPolicy, false); + _opCtx, _collection, _cq, *solutions[0], _yieldPolicy); prepareExecutionPlan(root.get(), &data); return {makeVector<plan_ranker::CandidatePlan>(plan_ranker::CandidatePlan{ std::move(solutions[0]), std::move(root), std::move(data)}), @@ -119,7 +119,7 @@ CandidatePlans SubPlanner::planWholeQuery() const { std::vector<std::pair<std::unique_ptr<PlanStage>, stage_builder::PlanStageData>> roots; for (auto&& solution : solutions) { roots.push_back(stage_builder::buildSlotBasedExecutableTree( - _opCtx, _collection, _cq, *solution, _yieldPolicy, true)); + _opCtx, _collection, _cq, *solution, _yieldPolicy)); } MultiPlanner multiPlanner{_opCtx, _collection, _cq, PlanCachingMode::AlwaysCache, _yieldPolicy}; diff --git a/src/mongo/db/query/stage_builder_util.cpp b/src/mongo/db/query/stage_builder_util.cpp index f318bb127eb..c3af8b207a9 100644 --- a/src/mongo/db/query/stage_builder_util.cpp +++ b/src/mongo/db/query/stage_builder_util.cpp @@ -58,8 +58,7 @@ buildSlotBasedExecutableTree(OperationContext* opCtx, const CollectionPtr& collection, const CanonicalQuery& cq, const QuerySolution& solution, - PlanYieldPolicy* yieldPolicy, - bool needsTrialRunProgressTracker) { + PlanYieldPolicy* yieldPolicy) { // Only QuerySolutions derived from queries parsed with context, or QuerySolutions derived from // queries that disallow extensions, can be properly executed. If the query does not have // $text/$where context (and $text/$where are allowed), then no attempt should be made to @@ -72,17 +71,12 @@ buildSlotBasedExecutableTree(OperationContext* opCtx, auto shardFilterer = std::make_unique<ShardFiltererFactoryImpl>(collection); - auto builder = std::make_unique<SlotBasedStageBuilder>(opCtx, - collection, - cq, - solution, - sbeYieldPolicy, - needsTrialRunProgressTracker, - shardFilterer.get()); + auto builder = std::make_unique<SlotBasedStageBuilder>( + opCtx, collection, cq, solution, sbeYieldPolicy, shardFilterer.get()); auto root = builder->build(solution.root()); auto data = builder->getPlanStageData(); - root->attachFromOperationContext(opCtx); + root->attachToOperationContext(opCtx); // Register this plan to yield according to the configured policy. sbeYieldPolicy->registerPlan(root.get()); diff --git a/src/mongo/db/query/stage_builder_util.h b/src/mongo/db/query/stage_builder_util.h index cd1f77594eb..b04e533a20e 100644 --- a/src/mongo/db/query/stage_builder_util.h +++ b/src/mongo/db/query/stage_builder_util.h @@ -55,7 +55,6 @@ buildSlotBasedExecutableTree(OperationContext* opCtx, const CollectionPtr& collection, const CanonicalQuery& cq, const QuerySolution& solution, - PlanYieldPolicy* yieldPolicy, - bool needsTrialRunProgressTracker); + PlanYieldPolicy* yieldPolicy); } // namespace mongo::stage_builder |