summaryrefslogtreecommitdiff
path: root/src/mongo/db/query
diff options
context:
space:
mode:
authorDavid Storch <david.storch@mongodb.com>2021-06-04 16:41:11 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-06-16 20:24:42 +0000
commit10bbd8dd5a0879651f446f66bc633ae0a1966acd (patch)
treefe4f49b66853289889477138f1018581d1b76791 /src/mongo/db/query
parentfc66d558802ecb1cd403d45225d0d77cc47a5d93 (diff)
downloadmongo-10bbd8dd5a0879651f446f66bc633ae0a1966acd.tar.gz
SERVER-57096 Make SBE rely purely on the kExternal lock policy
After this patch, the AutoGet db_raii object is no longer held by the SBE scan/ixscan stages. SBE now assumes that any lock/snapshot acquisition is done at a higher level. (cherry picked from commit 71cfc41653768c29c719689a949a75a0ebbaa941)
Diffstat (limited to 'src/mongo/db/query')
-rw-r--r--src/mongo/db/query/classic_stage_builder_test.cpp2
-rw-r--r--src/mongo/db/query/get_executor.cpp4
-rw-r--r--src/mongo/db/query/plan_cache_test.cpp7
-rw-r--r--src/mongo/db/query/planner_analysis.cpp2
-rw-r--r--src/mongo/db/query/query_planner.cpp3
-rw-r--r--src/mongo/db/query/query_planner_params.h9
-rw-r--r--src/mongo/db/query/query_solution.h14
-rw-r--r--src/mongo/db/query/query_solution_test.cpp2
-rw-r--r--src/mongo/db/query/sbe_stage_builder.cpp31
-rw-r--r--src/mongo/db/query/sbe_stage_builder.h4
-rw-r--r--src/mongo/db/query/sbe_stage_builder_coll_scan.cpp45
-rw-r--r--src/mongo/db/query/sbe_stage_builder_coll_scan.h3
-rw-r--r--src/mongo/db/query/sbe_stage_builder_index_scan.cpp63
-rw-r--r--src/mongo/db/query/sbe_stage_builder_index_scan.h4
-rw-r--r--src/mongo/db/query/sbe_stage_builder_test_fixture.cpp2
-rw-r--r--src/mongo/db/query/sbe_sub_planner.cpp11
16 files changed, 62 insertions, 144 deletions
diff --git a/src/mongo/db/query/classic_stage_builder_test.cpp b/src/mongo/db/query/classic_stage_builder_test.cpp
index 4e8f87140b7..407cd67e426 100644
--- a/src/mongo/db/query/classic_stage_builder_test.cpp
+++ b/src/mongo/db/query/classic_stage_builder_test.cpp
@@ -59,7 +59,7 @@ public:
* Converts a 'QuerySolutionNode' to a 'QuerySolution'.
*/
std::unique_ptr<QuerySolution> makeQuerySolution(std::unique_ptr<QuerySolutionNode> root) {
- auto querySoln = std::make_unique<QuerySolution>(QueryPlannerParams::Options::DEFAULT);
+ auto querySoln = std::make_unique<QuerySolution>();
querySoln->setRoot(std::move(root));
return querySoln;
}
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index 5c8980200f8..b894989ea4d 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -567,7 +567,7 @@ public:
"namespace"_attr = _cq->ns(),
"canonicalQuery"_attr = redact(_cq->toStringShort()));
- auto solution = std::make_unique<QuerySolution>(_plannerOptions);
+ auto solution = std::make_unique<QuerySolution>();
solution->setRoot(std::make_unique<EofNode>());
auto root = buildExecutableTree(*solution);
@@ -974,7 +974,7 @@ protected:
}
}
- auto soln = std::make_unique<QuerySolution>(plannerParams->options);
+ auto soln = std::make_unique<QuerySolution>();
soln->setRoot(std::move(root));
auto execTree = buildExecutableTree(*soln);
diff --git a/src/mongo/db/query/plan_cache_test.cpp b/src/mongo/db/query/plan_cache_test.cpp
index d45befd0b54..70783eec7f7 100644
--- a/src/mongo/db/query/plan_cache_test.cpp
+++ b/src/mongo/db/query/plan_cache_test.cpp
@@ -313,7 +313,7 @@ std::pair<CoreIndexInfo, std::unique_ptr<WildcardProjection>> makeWildcardUpdate
*/
struct GenerateQuerySolution {
QuerySolution* operator()() const {
- unique_ptr<QuerySolution> qs(new QuerySolution(QueryPlannerParams::Options::DEFAULT));
+ auto qs = std::make_unique<QuerySolution>();
qs->cacheData.reset(new SolutionCacheData());
qs->cacheData->solnType = SolutionCacheData::COLLSCAN_SOLN;
qs->cacheData->tree.reset(new PlanCacheIndexTree());
@@ -376,8 +376,7 @@ void assertShouldNotCacheQuery(const char* queryStr) {
}
std::unique_ptr<QuerySolution> getQuerySolutionForCaching() {
- std::unique_ptr<QuerySolution> qs =
- std::make_unique<QuerySolution>(QueryPlannerParams::Options::DEFAULT);
+ std::unique_ptr<QuerySolution> qs = std::make_unique<QuerySolution>();
qs->cacheData = std::make_unique<SolutionCacheData>();
qs->cacheData->tree = std::make_unique<PlanCacheIndexTree>();
return qs;
@@ -1167,7 +1166,7 @@ protected:
// Create a CachedSolution the long way..
// QuerySolution -> PlanCacheEntry -> CachedSolution
- QuerySolution qs{QueryPlannerParams::Options::DEFAULT};
+ QuerySolution qs{};
qs.cacheData = soln.cacheData->clone();
std::vector<QuerySolution*> solutions;
solutions.push_back(&qs);
diff --git a/src/mongo/db/query/planner_analysis.cpp b/src/mongo/db/query/planner_analysis.cpp
index 71892e12b51..dc943fd771c 100644
--- a/src/mongo/db/query/planner_analysis.cpp
+++ b/src/mongo/db/query/planner_analysis.cpp
@@ -913,7 +913,7 @@ std::unique_ptr<QuerySolution> QueryPlannerAnalysis::analyzeDataAccess(
const CanonicalQuery& query,
const QueryPlannerParams& params,
std::unique_ptr<QuerySolutionNode> solnRoot) {
- auto soln = std::make_unique<QuerySolution>(params.options);
+ auto soln = std::make_unique<QuerySolution>();
soln->indexFilterApplied = params.indexFiltersApplied;
solnRoot->computeProperties();
diff --git a/src/mongo/db/query/query_planner.cpp b/src/mongo/db/query/query_planner.cpp
index ab803e03254..0d13c318193 100644
--- a/src/mongo/db/query/query_planner.cpp
+++ b/src/mongo/db/query/query_planner.cpp
@@ -179,9 +179,6 @@ string optionString(size_t options) {
case QueryPlannerParams::ENUMERATE_OR_CHILDREN_LOCKSTEP:
ss << "ENUMERATE_OR_CHILDREN_LOCKSTEP ";
break;
- case QueryPlannerParams::OMIT_REPL_STATE_PERMITS_READS_CHECK:
- ss << "OMIT_REPL_STATE_PERMITS_READS_CHECK";
- break;
case QueryPlannerParams::RETURN_OWNED_DATA:
ss << "RETURN_OWNED_DATA ";
break;
diff --git a/src/mongo/db/query/query_planner_params.h b/src/mongo/db/query/query_planner_params.h
index 5278c94f8e9..deb452eacf6 100644
--- a/src/mongo/db/query/query_planner_params.h
+++ b/src/mongo/db/query/query_planner_params.h
@@ -120,16 +120,9 @@ struct QueryPlannerParams {
// $or use the same fields and have the same indexes available, as in this example.
ENUMERATE_OR_CHILDREN_LOCKSTEP = 1 << 12,
- // Instructs the planner to produce a plan which will *not* check at runtime that the node's
- // replica set member state allows reads. Typically, replica set members will only serve
- // reads to clients if thet are in parimary or secondary state. Client reads are disallowed
- // in other states, e.g. during initial sync. Internal operations, on the other hand, can
- // use this flag to exempt themselves from this repl set note state requirement.
- OMIT_REPL_STATE_PERMITS_READS_CHECK = 1 << 13,
-
// Ensure that any plan generated returns data that is "owned." That is, all BSONObjs are
// in an "owned" state and are not pointing to data that belongs to the storage engine.
- RETURN_OWNED_DATA = 1 << 14,
+ RETURN_OWNED_DATA = 1 << 13,
};
// See Options enum above.
diff --git a/src/mongo/db/query/query_solution.h b/src/mongo/db/query/query_solution.h
index e950d34db67..9d0c8f5f9bf 100644
--- a/src/mongo/db/query/query_solution.h
+++ b/src/mongo/db/query/query_solution.h
@@ -326,7 +326,7 @@ struct QuerySolutionNodeWithSortSet : public QuerySolutionNode {
*/
class QuerySolution {
public:
- explicit QuerySolution(size_t plannerOptions) : plannerOptions(plannerOptions) {}
+ QuerySolution() = default;
/**
* Return true if this solution tree contains a node of the given 'type'.
@@ -362,18 +362,6 @@ public:
*/
void setRoot(std::unique_ptr<QuerySolutionNode> root);
- /**
- * Returns true if the execution plan which is constructed from this QuerySolution should check
- * that the node is eligible to serve reads prior to actually performing any reads.
- */
- bool shouldCheckCanServeReads() const {
- return !(plannerOptions & QueryPlannerParams::OMIT_REPL_STATE_PERMITS_READS_CHECK);
- }
-
- // A bit vector of flags which clients to the QueryPlanner pass to control which plans are
- // generated and their properties.
- const size_t plannerOptions;
-
// There are two known scenarios in which a query solution might potentially block:
//
// Sort stage:
diff --git a/src/mongo/db/query/query_solution_test.cpp b/src/mongo/db/query/query_solution_test.cpp
index 71470e22c50..8763b208fcd 100644
--- a/src/mongo/db/query/query_solution_test.cpp
+++ b/src/mongo/db/query/query_solution_test.cpp
@@ -1061,7 +1061,7 @@ TEST(QuerySolutionTest, NodeIdsAssignedInPostOrderFashionStartingFromOne) {
ASSERT_EQ(orNode->children[0]->nodeId(), 0u);
ASSERT_EQ(orNode->children[1]->nodeId(), 0u);
- auto querySolution = std::make_unique<QuerySolution>(QueryPlannerParams::Options::DEFAULT);
+ auto querySolution = std::make_unique<QuerySolution>();
querySolution->setRoot(std::move(orNode));
auto root = querySolution->root();
diff --git a/src/mongo/db/query/sbe_stage_builder.cpp b/src/mongo/db/query/sbe_stage_builder.cpp
index 50f8afadc4e..47832fa54ba 100644
--- a/src/mongo/db/query/sbe_stage_builder.cpp
+++ b/src/mongo/db/query/sbe_stage_builder.cpp
@@ -457,17 +457,6 @@ const QuerySolutionNode* getLoneNodeByType(const QuerySolutionNode* root, StageT
return result;
}
-sbe::LockAcquisitionCallback makeLockAcquisitionCallback(bool checkNodeCanServeReads) {
- if (!checkNodeCanServeReads) {
- return {};
- }
-
- return [](OperationContext* opCtx, const AutoGetCollectionForReadMaybeLockFree& coll) {
- uassertStatusOK(repl::ReplicationCoordinator::get(opCtx)->checkCanServeReadsFor(
- opCtx, coll.getNss(), true));
- };
-}
-
/**
* Callback function that logs a message and uasserts if it detects a corrupt index key. An index
* key is considered corrupt if it has no corresponding Record.
@@ -646,7 +635,6 @@ SlotBasedStageBuilder::SlotBasedStageBuilder(OperationContext* opCtx,
_yieldPolicy(yieldPolicy),
_data(makeRuntimeEnvironment(_cq, _opCtx, &_slotIdGenerator)),
_shardFiltererFactory(shardFiltererFactory),
- _lockAcquisitionCallback(makeLockAcquisitionCallback(solution.shouldCheckCanServeReads())),
_state(_opCtx,
_data.env,
_cq.getExpCtxRaw()->variables,
@@ -705,12 +693,8 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> SlotBasedStageBuilder
auto csn = static_cast<const CollectionScanNode*>(root);
- auto [stage, outputs] = generateCollScan(_state,
- _collection,
- csn,
- _yieldPolicy,
- reqs.getIsTailableCollScanResumeBranch(),
- _lockAcquisitionCallback);
+ auto [stage, outputs] = generateCollScan(
+ _state, _collection, csn, _yieldPolicy, reqs.getIsTailableCollScanResumeBranch());
if (reqs.has(kReturnKey)) {
// Assign the 'returnKeySlot' to be the empty object.
@@ -822,14 +806,8 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> SlotBasedStageBuilder
iamMap = nullptr;
}
- auto [stage, outputs] = generateIndexScan(_state,
- _collection,
- ixn,
- indexKeyBitset,
- _yieldPolicy,
- _lockAcquisitionCallback,
- iamMap,
- reqs.has(kIndexKeyPattern));
+ auto [stage, outputs] = generateIndexScan(
+ _state, _collection, ixn, indexKeyBitset, _yieldPolicy, iamMap, reqs.has(kIndexKeyPattern));
if (reqs.has(PlanStageSlots::kReturnKey)) {
std::vector<std::unique_ptr<sbe::EExpression>> mkObjArgs;
@@ -885,7 +863,6 @@ SlotBasedStageBuilder::makeLoopJoinForFetch(std::unique_ptr<sbe::PlanStage> inpu
using namespace std::placeholders;
sbe::ScanCallbacks callbacks(
- _lockAcquisitionCallback,
indexKeyCorruptionCheckCallback,
std::bind(indexKeyConsistencyCheckCallback, _1, std::move(iamMap), _2, _3, _4, _5));
// Scan the collection in the range [seekKeySlot, Inf).
diff --git a/src/mongo/db/query/sbe_stage_builder.h b/src/mongo/db/query/sbe_stage_builder.h
index 49534b02f9f..81335f937e0 100644
--- a/src/mongo/db/query/sbe_stage_builder.h
+++ b/src/mongo/db/query/sbe_stage_builder.h
@@ -381,10 +381,6 @@ private:
// A factory to construct shard filters.
ShardFiltererFactoryInterface* _shardFiltererFactory;
- // A callback that should be installed on "scan" and "ixscan" nodes. It will get invoked when
- // these data access stages acquire their AutoGet*.
- const sbe::LockAcquisitionCallback _lockAcquisitionCallback;
-
// Common parameters to SBE stage builder functions.
StageBuilderState _state;
};
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 bd045c33801..740f5e71c36 100644
--- a/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp
@@ -141,8 +141,7 @@ std::unique_ptr<sbe::PlanStage> buildResumeFromRecordIdSubtree(
std::unique_ptr<sbe::EExpression> seekRecordIdExpression,
PlanYieldPolicy* yieldPolicy,
bool isTailableResumeBranch,
- bool resumeAfterRecordId,
- sbe::LockAcquisitionCallback lockAcquisitionCallback) {
+ bool resumeAfterRecordId) {
invariant(seekRecordIdExpression);
const auto forward = csn->direction == CollectionScanParams::FORWARD;
@@ -174,7 +173,7 @@ std::unique_ptr<sbe::PlanStage> buildResumeFromRecordIdSubtree(
forward,
yieldPolicy,
csn->nodeId(),
- lockAcquisitionCallback),
+ sbe::ScanCallbacks{}),
sbe::makeSV(seekSlot),
sbe::makeSV(seekSlot),
nullptr,
@@ -247,8 +246,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateOptimizedOplo
const CollectionPtr& collection,
const CollectionScanNode* csn,
PlanYieldPolicy* yieldPolicy,
- bool isTailableResumeBranch,
- sbe::LockAcquisitionCallback lockAcquisitionCallback) {
+ bool isTailableResumeBranch) {
invariant(collection->ns().isOplog());
// We can apply oplog scan optimizations only when at least one of the following was specified.
invariant(csn->resumeAfterRecordId || csn->minRecord || csn->maxRecord);
@@ -293,8 +291,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateOptimizedOplo
auto&& [fields, slots, tsSlot] = makeOplogTimestampSlotsIfNeeded(
state.env, state.slotIdGenerator, shouldTrackLatestOplogTimestamp);
- sbe::ScanCallbacks callbacks(
- lockAcquisitionCallback, {}, {}, makeOpenCallbackIfNeeded(collection, csn));
+ sbe::ScanCallbacks callbacks({}, {}, makeOpenCallbackIfNeeded(collection, csn));
auto stage = sbe::makeS<sbe::ScanStage>(collection->uuid(),
resultSlot,
recordIdSlot,
@@ -321,8 +318,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateOptimizedOplo
std::move(seekRecordIdExpression),
yieldPolicy,
isTailableResumeBranch,
- csn->resumeAfterRecordId.has_value(),
- lockAcquisitionCallback);
+ csn->resumeAfterRecordId.has_value());
}
// Create a filter which checks the first document to ensure either that its 'ts' is less than
@@ -367,7 +363,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateOptimizedOplo
// the expression does match, then it returns 'false', which causes the filter (and as a
// result, the branch) to EOF immediately. Note that the resultSlot and recordIdSlot
// arguments to the ScanStage are boost::none, as we do not need them.
- sbe::ScanCallbacks branchCallbacks(lockAcquisitionCallback);
+ sbe::ScanCallbacks branchCallbacks{};
auto minTsBranch = sbe::makeS<sbe::FilterStage<false, true>>(
sbe::makeS<sbe::ScanStage>(collection->uuid(),
boost::none /* resultSlot */,
@@ -511,7 +507,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateOptimizedOplo
true /* forward */,
yieldPolicy,
csn->nodeId(),
- std::move(lockAcquisitionCallback)),
+ sbe::ScanCallbacks{}),
sbe::makeSV(),
sbe::makeSV(*seekRecordIdSlot),
nullptr,
@@ -542,8 +538,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateGenericCollSc
const CollectionPtr& collection,
const CollectionScanNode* csn,
PlanYieldPolicy* yieldPolicy,
- bool isTailableResumeBranch,
- sbe::LockAcquisitionCallback lockAcquisitionCallback) {
+ bool isTailableResumeBranch) {
const auto forward = csn->direction == CollectionScanParams::FORWARD;
invariant(!csn->shouldTrackLatestOplogTimestamp || collection->ns().isOplog());
@@ -569,8 +564,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateGenericCollSc
auto&& [fields, slots, tsSlot] = makeOplogTimestampSlotsIfNeeded(
state.env, state.slotIdGenerator, csn->shouldTrackLatestOplogTimestamp);
- sbe::ScanCallbacks callbacks(
- lockAcquisitionCallback, {}, {}, makeOpenCallbackIfNeeded(collection, csn));
+ sbe::ScanCallbacks callbacks({}, {}, makeOpenCallbackIfNeeded(collection, csn));
auto stage = sbe::makeS<sbe::ScanStage>(collection->uuid(),
resultSlot,
recordIdSlot,
@@ -596,8 +590,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateGenericCollSc
std::move(seekRecordIdExpression),
yieldPolicy,
isTailableResumeBranch,
- true, /* resumeAfterRecordId */
- lockAcquisitionCallback);
+ true /* resumeAfterRecordId */);
}
if (csn->filter) {
@@ -629,22 +622,12 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateCollScan(
const CollectionPtr& collection,
const CollectionScanNode* csn,
PlanYieldPolicy* yieldPolicy,
- bool isTailableResumeBranch,
- sbe::LockAcquisitionCallback lockAcquisitionCallback) {
+ bool isTailableResumeBranch) {
if (csn->minRecord || csn->maxRecord || csn->stopApplyingFilterAfterFirstMatch) {
- return generateOptimizedOplogScan(state,
- collection,
- csn,
- yieldPolicy,
- isTailableResumeBranch,
- std::move(lockAcquisitionCallback));
+ return generateOptimizedOplogScan(
+ state, collection, csn, yieldPolicy, isTailableResumeBranch);
} else {
- return generateGenericCollScan(state,
- collection,
- csn,
- yieldPolicy,
- isTailableResumeBranch,
- std::move(lockAcquisitionCallback));
+ return generateGenericCollScan(state, collection, csn, yieldPolicy, 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 58b28a0e1f1..b204c5487a8 100644
--- a/src/mongo/db/query/sbe_stage_builder_coll_scan.h
+++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.h
@@ -57,7 +57,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateCollScan(
const CollectionPtr& collection,
const CollectionScanNode* csn,
PlanYieldPolicy* yieldPolicy,
- bool isTailableResumeBranch,
- sbe::LockAcquisitionCallback lockAcquisitionCallback);
+ 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 b1af7fb38e5..9eeeeab6b30 100644
--- a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
@@ -292,8 +292,7 @@ generateOptimizedMultiIntervalIndexScan(
boost::optional<sbe::value::SlotId> indexKeyPatternSlot,
sbe::value::SlotIdGenerator* slotIdGenerator,
PlanYieldPolicy* yieldPolicy,
- PlanNodeId planNodeId,
- sbe::LockAcquisitionCallback lockAcquisitionCallback) {
+ PlanNodeId planNodeId) {
using namespace std::literals;
auto recordIdSlot = slotIdGenerator->generate();
@@ -376,8 +375,7 @@ generateOptimizedMultiIntervalIndexScan(
lowKeySlot,
highKeySlot,
yieldPolicy,
- planNodeId,
- std::move(lockAcquisitionCallback));
+ planNodeId);
// Add a project on top of the index scan to remember the snapshotId of the most recent index
// key returned by the IndexScan above. Otherwise, the index key's snapshot id would be
@@ -451,8 +449,7 @@ makeRecursiveBranchForGenericIndexScan(const CollectionPtr& collection,
boost::optional<sbe::value::SlotId> indexKeyPatternSlot,
sbe::value::SlotIdGenerator* slotIdGenerator,
PlanYieldPolicy* yieldPolicy,
- PlanNodeId planNodeId,
- sbe::LockAcquisitionCallback lockAcquisitionCallback) {
+ PlanNodeId planNodeId) {
// The IndexScanStage in this branch will always produce a KeyString. As such, we use
// 'indexKeySlot' if is defined and generate a new slot otherwise.
sbe::value::SlotId resultSlot;
@@ -499,8 +496,7 @@ makeRecursiveBranchForGenericIndexScan(const CollectionPtr& collection,
lowKeySlot,
boost::none,
yieldPolicy,
- planNodeId,
- std::move(lockAcquisitionCallback));
+ planNodeId);
// Get the low key from the outer side and feed it to the inner side (ixscan).
sbe::value::SlotVector outerSv = sbe::makeSV();
@@ -631,8 +627,7 @@ generateGenericMultiIntervalIndexScan(const CollectionPtr& collection,
boost::optional<sbe::value::SlotId> indexKeyPatternSlot,
sbe::value::SlotIdGenerator* slotIdGenerator,
sbe::value::SpoolIdGenerator* spoolIdGenerator,
- PlanYieldPolicy* yieldPolicy,
- sbe::LockAcquisitionCallback lockAcquisitionCallback) {
+ PlanYieldPolicy* yieldPolicy) {
using namespace std::literals;
auto resultSlot = slotIdGenerator->generate();
@@ -752,8 +747,7 @@ generateGenericMultiIntervalIndexScan(const CollectionPtr& collection,
savedKeyPattern,
slotIdGenerator,
yieldPolicy,
- ixn->nodeId(),
- std::move(lockAcquisitionCallback));
+ ixn->nodeId());
// Construct a union stage from the two branches.
auto makeSlotVector = [](sbe::value::SlotId headSlot, const sbe::value::SlotVector& varSlots) {
@@ -805,8 +799,7 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleInt
boost::optional<sbe::value::SlotId> indexKeyPatternSlot,
sbe::value::SlotIdGenerator* slotIdGenerator,
PlanYieldPolicy* yieldPolicy,
- PlanNodeId planNodeId,
- sbe::LockAcquisitionCallback lockAcquisitionCallback) {
+ PlanNodeId planNodeId) {
auto recordIdSlot = slotIdGenerator->generate();
auto lowKeySlot = slotIdGenerator->generate();
auto highKeySlot = slotIdGenerator->generate();
@@ -860,8 +853,7 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleInt
lowKeySlot,
highKeySlot,
yieldPolicy,
- planNodeId,
- std::move(lockAcquisitionCallback));
+ planNodeId);
// Add a project on top of the index scan to remember the snapshotId of the most recent index
// key returned by the IndexScan above. Otherwise, the index key's snapshot id would be
@@ -896,7 +888,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan(
const IndexScanNode* ixn,
const sbe::IndexKeysInclusionSet& originalIndexKeyBitset,
PlanYieldPolicy* yieldPolicy,
- sbe::LockAcquisitionCallback lockAcquisitionCallback,
StringMap<const IndexAccessMethod*>* iamMap,
bool needsCorruptionCheck) {
@@ -970,23 +961,21 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan(
auto&& [lowKey, highKey] = intervals[0];
sbe::value::SlotId recordIdSlot;
- std::tie(recordIdSlot, stage) =
- generateSingleIntervalIndexScan(collection,
- indexName,
- keyPattern,
- ixn->direction == 1,
- std::move(lowKey),
- std::move(highKey),
- indexKeyBitset,
- indexKeySlots,
- snapshotIdSlot,
- indexIdSlot,
- indexKeySlot,
- indexKeyPatternSlot,
- state.slotIdGenerator,
- yieldPolicy,
- ixn->nodeId(),
- std::move(lockAcquisitionCallback));
+ std::tie(recordIdSlot, stage) = generateSingleIntervalIndexScan(collection,
+ indexName,
+ keyPattern,
+ ixn->direction == 1,
+ std::move(lowKey),
+ std::move(highKey),
+ indexKeyBitset,
+ indexKeySlots,
+ snapshotIdSlot,
+ indexIdSlot,
+ indexKeySlot,
+ indexKeyPatternSlot,
+ state.slotIdGenerator,
+ yieldPolicy,
+ ixn->nodeId());
outputs.set(PlanStageSlots::kRecordId, recordIdSlot);
} else if (intervals.size() > 1) {
@@ -1007,8 +996,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan(
indexKeyPatternSlot,
state.slotIdGenerator,
yieldPolicy,
- ixn->nodeId(),
- std::move(lockAcquisitionCallback));
+ ixn->nodeId());
outputs.set(PlanStageSlots::kRecordId, recordIdSlot);
} else {
@@ -1027,8 +1015,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan(
indexKeyPatternSlot,
state.slotIdGenerator,
state.spoolIdGenerator,
- yieldPolicy,
- std::move(lockAcquisitionCallback));
+ 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 71a7e0eafe6..846fa7fbbfb 100644
--- a/src/mongo/db/query/sbe_stage_builder_index_scan.h
+++ b/src/mongo/db/query/sbe_stage_builder_index_scan.h
@@ -57,7 +57,6 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> generateIndexScan(
const IndexScanNode* ixn,
const sbe::IndexKeysInclusionSet& indexKeyBitset,
PlanYieldPolicy* yieldPolicy,
- sbe::LockAcquisitionCallback lockAcquisitionCallback,
StringMap<const IndexAccessMethod*>* iamMap,
bool needsCorruptionCheck);
@@ -95,7 +94,6 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleInt
boost::optional<sbe::value::SlotId> keyPatternSlot,
sbe::value::SlotIdGenerator* slotIdGenerator,
PlanYieldPolicy* yieldPolicy,
- PlanNodeId nodeId,
- sbe::LockAcquisitionCallback lockAcquisitionCallback);
+ 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 36fb19ed215..84a471c1841 100644
--- a/src/mongo/db/query/sbe_stage_builder_test_fixture.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_test_fixture.cpp
@@ -39,7 +39,7 @@
namespace mongo {
std::unique_ptr<QuerySolution> SbeStageBuilderTestFixture::makeQuerySolution(
std::unique_ptr<QuerySolutionNode> root) {
- auto querySoln = std::make_unique<QuerySolution>(QueryPlannerParams::Options::DEFAULT);
+ auto querySoln = std::make_unique<QuerySolution>();
querySoln->setRoot(std::move(root));
return querySoln;
}
diff --git a/src/mongo/db/query/sbe_sub_planner.cpp b/src/mongo/db/query/sbe_sub_planner.cpp
index e0d08f10a04..77b40a2121d 100644
--- a/src/mongo/db/query/sbe_sub_planner.cpp
+++ b/src/mongo/db/query/sbe_sub_planner.cpp
@@ -58,15 +58,15 @@ CandidatePlans SubPlanner::plan(
// branch of the OR query. In this case, fail with a 'QueryPlanKilled' error.
_indexExistenceChecker.check();
+ // Ensure that no previous plans are registered to yield while we multi plan each branch.
+ _yieldPolicy->clearRegisteredPlans();
+
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));
}
- // Ensure that no previous plans are registered to yield while we multi plan each branch.
- _yieldPolicy->clearRegisteredPlans();
-
// Clear any plans registered to yield once multiplanning is done for this branch. We don't
// want to leave dangling pointers to the execution plans used in multi planning hanging
// around in the YieldPolicy.
@@ -82,12 +82,13 @@ CandidatePlans SubPlanner::plan(
return std::move(candidates[winnerIdx].solution);
};
+ auto subplanSelectStat = QueryPlanner::choosePlanForSubqueries(
+ _cq, _queryParams, std::move(subplanningStatus.getValue()), multiplanCallback);
+
// One of the indexes in '_queryParams' might have been dropped while planning the final branch
// of the OR query. In this case, fail with a 'QueryPlanKilled' error.
_indexExistenceChecker.check();
- auto subplanSelectStat = QueryPlanner::choosePlanForSubqueries(
- _cq, _queryParams, std::move(subplanningStatus.getValue()), multiplanCallback);
if (!subplanSelectStat.isOK()) {
// Query planning can continue if we failed to find a solution for one of the children.
// Otherwise, it cannot, as it may no longer be safe to access the collection (an index