diff options
author | Irina Yatsenko <irina.yatsenko@mongodb.com> | 2021-11-04 03:33:03 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-11-04 04:13:42 +0000 |
commit | defd15c56456b2348d1c483df977efcc142151f4 (patch) | |
tree | 1a1d134d6fa0af8e54ae3c6522973b63a7ac3111 | |
parent | e201049a0ddd15704c348863e75d7f1473ae0beb (diff) | |
download | mongo-defd15c56456b2348d1c483df977efcc142151f4.tar.gz |
SERVER-58429 Minor cleanup around PlanExecutorSBE
-rw-r--r-- | src/mongo/db/query/get_executor.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/query/plan_executor_sbe.cpp | 11 |
2 files changed, 14 insertions, 15 deletions
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp index 4e10cb9eff6..7e616547934 100644 --- a/src/mongo/db/query/get_executor.cpp +++ b/src/mongo/db/query/get_executor.cpp @@ -1104,24 +1104,26 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getSlotBasedExe extractAndAttachPipelineStages(cq.get()); } + // Analyze the provided query and build the list of candidate plans for it. auto nss = cq->nss(); auto yieldPolicy = makeSbeYieldPolicy(opCtx, requestedYieldPolicy, collection, nss); SlotBasedPrepareExecutionHelper helper{ opCtx, *collection, cq.get(), yieldPolicy.get(), plannerOptions}; - auto executionResult = helper.prepare(); - if (!executionResult.isOK()) { - return executionResult.getStatus(); + auto planningResultWithStatus = helper.prepare(); + if (!planningResultWithStatus.isOK()) { + return planningResultWithStatus.getStatus(); } + auto&& planningResult = planningResultWithStatus.getValue(); + auto&& [roots, solutions] = planningResult->extractResultData(); - auto&& result = executionResult.getValue(); - auto&& [roots, solutions] = result->extractResultData(); - + // In some circumstances (e.g. when have multiple candidate plans or using a cached one), we + // might need to execute the plan(s) to pick the best one or to confirm the choice. if (auto planner = makeRuntimePlannerIfNeeded(opCtx, *collection, cq.get(), solutions.size(), - result->decisionWorks(), - result->needsSubplanning(), + planningResult->decisionWorks(), + planningResult->needsSubplanning(), yieldPolicy.get(), plannerOptions)) { // Do the runtime planning and pick the best candidate plan. diff --git a/src/mongo/db/query/plan_executor_sbe.cpp b/src/mongo/db/query/plan_executor_sbe.cpp index 12c8abd335c..03f3fdf03da 100644 --- a/src/mongo/db/query/plan_executor_sbe.cpp +++ b/src/mongo/db/query/plan_executor_sbe.cpp @@ -60,15 +60,13 @@ PlanExecutorSBE::PlanExecutorSBE(OperationContext* opCtx, _mustReturnOwnedBson(returnOwnedBson), _root{std::move(candidates.winner().root)}, _rootData{std::move(candidates.winner().data)}, + _solution{std::move(candidates.winner().solution)}, + _stash{std::move(candidates.winner().results)}, _cq{std::move(cq)}, _yieldPolicy(std::move(yieldPolicy)) { invariant(!_nss.isEmpty()); invariant(_root); - // NOTE: 'winner.data' has been std::moved() from and is not safe to access. - auto winner = std::move(candidates.plans[candidates.winnerIdx]); - _solution = std::move(winner.solution); - if (auto slot = _rootData.outputs.getIfExists(stage_builder::PlanStageSlots::kResult); slot) { _result = _root->getAccessor(_rootData.ctx, *slot); uassert(4822865, "Query does not have result slot.", _result); @@ -83,12 +81,11 @@ PlanExecutorSBE::PlanExecutorSBE(OperationContext* opCtx, _oplogTs = _rootData.env->getAccessor(_rootData.env->getSlot("oplogTs"_sd)); } - if (winner.data.shouldUseTailableScan) { + if (_rootData.shouldUseTailableScan) { _resumeRecordIdSlot = _rootData.env->getSlot("resumeRecordId"_sd); } - if (!winner.results.empty()) { - _stash = std::move(winner.results); + if (!_stash.empty()) { // The PlanExecutor keeps an extra reference to the last object pulled out of the PlanStage // tree. This is because we want to ensure that the caller of PlanExecutor::getNext() does // not free the object and leave a dangling pointer in the PlanStage tree. |