summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIrina Yatsenko <irina.yatsenko@mongodb.com>2021-11-04 03:33:03 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-11-04 04:13:42 +0000
commitdefd15c56456b2348d1c483df977efcc142151f4 (patch)
tree1a1d134d6fa0af8e54ae3c6522973b63a7ac3111
parente201049a0ddd15704c348863e75d7f1473ae0beb (diff)
downloadmongo-defd15c56456b2348d1c483df977efcc142151f4.tar.gz
SERVER-58429 Minor cleanup around PlanExecutorSBE
-rw-r--r--src/mongo/db/query/get_executor.cpp18
-rw-r--r--src/mongo/db/query/plan_executor_sbe.cpp11
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.