diff options
| author | Ian Boros <87138302+borosaurus@users.noreply.github.com> | 2024-06-11 14:56:11 -0400 |
|---|---|---|
| committer | MongoDB Bot <mongo-bot@mongodb.com> | 2024-06-11 19:52:50 +0000 |
| commit | 11f921e1a5f6d4251ace1956fe7a500e545afec1 (patch) | |
| tree | 42358061cf5005a810d529bb3ca6e58513e03d4b | |
| parent | 30e2a108c784c55f39f969c8e7ea73ac8e818e50 (diff) | |
SERVER-91230 Change SBE SubPlanner to write 'reads' instead of 'works' when planning entire query (#23326)r8.0.0-rc8
GitOrigin-RevId: 65f60f3a43b5c3c65d64402ae66ffe80e8fb2e68
| -rw-r--r-- | jstests/noPassthrough/sbe_subplanning.js | 106 | ||||
| -rw-r--r-- | src/mongo/db/exec/cached_plan.cpp | 3 | ||||
| -rw-r--r-- | src/mongo/db/exec/multi_plan.cpp | 2 | ||||
| -rw-r--r-- | src/mongo/db/exec/multi_plan.h | 1 | ||||
| -rw-r--r-- | src/mongo/db/exec/plan_cache_util.cpp | 32 | ||||
| -rw-r--r-- | src/mongo/db/exec/plan_cache_util.h | 28 | ||||
| -rw-r--r-- | src/mongo/db/query/classic_runtime_planner/multi_planner.cpp | 4 | ||||
| -rw-r--r-- | src/mongo/db/query/classic_runtime_planner/sub_planner.cpp | 7 | ||||
| -rw-r--r-- | src/mongo/db/query/classic_runtime_planner_for_sbe/multi_planner.cpp | 10 | ||||
| -rw-r--r-- | src/mongo/db/query/classic_runtime_planner_for_sbe/planner_interface.h | 1 | ||||
| -rw-r--r-- | src/mongo/db/query/classic_runtime_planner_for_sbe/sub_planner.cpp | 15 | ||||
| -rw-r--r-- | src/mongo/dbtests/plan_ranking.cpp | 14 | ||||
| -rw-r--r-- | src/mongo/dbtests/query_stage_multiplan.cpp | 25 | ||||
| -rw-r--r-- | src/mongo/dbtests/query_stage_subplan.cpp | 4 |
14 files changed, 203 insertions, 49 deletions
diff --git a/jstests/noPassthrough/sbe_subplanning.js b/jstests/noPassthrough/sbe_subplanning.js index 15b7728bfdd..2fe1aaa2bb5 100644 --- a/jstests/noPassthrough/sbe_subplanning.js +++ b/jstests/noPassthrough/sbe_subplanning.js @@ -256,4 +256,110 @@ for (let pipe of [subQuery1, subQuery2]) { }); } +jsTestLog("Running test which forces SubPlanner to plan the entire query"); + +// Now we run a query where the planner attempts to use subplanning, but ends up planning the whole +// query as one. +{ + coll.dropIndexes() + assert.commandWorked(coll.createIndex({a: 1})); + assert.commandWorked(coll.createIndex({b: 1})); + assert.commandWorked(coll.createIndex({x: 1})); + + function checkProfilerAndCache({isActive, isPinned, fromPlanCache, worksType}) { + const profileObj = + getLatestProfilerEntry(db, {op: {$in: ["command", "query"]}, ns: coll.getFullName()}); + + if (fromPlanCache) { + assert.eq(profileObj.fromPlanCache, true, profileObj); + } else { + // x:1 index was used. + assert.eq(/x: 1/g.test(profileObj.planSummary), true); + assert(!("fromPlanCache" in profileObj)); + } + + const engineUsed = profileObj.queryFramework; + + const cacheEntries = + coll.aggregate([{$planCacheStats: {}}, {$match: {queryHash: profileObj.queryHash}}]) + .toArray(); + assert.eq(cacheEntries.length, 1); + const cacheEntry = cacheEntries[0]; + + if (engineUsed == "sbe") { + assert.eq(cacheEntry.queryHash, profileObj.queryHash); + assert.eq(cacheEntry.planCacheKey, profileObj.planCacheKey); + assert.eq(cacheEntry.isActive, isActive); + + // It must be tracking reads if the query ran in SBE. + if (isPinned) { + assert(!("worksType" in cacheEntry)); + } else { + assert.eq(cacheEntry.worksType, "reads"); + } + + if (sbePlanCacheEnabled) { + assert.eq(cacheEntry.version, "2"); + } else { + assert.eq(cacheEntry.version, "1"); + } + } else { + // There should be a cache entry tracking 'works'. + assert.eq(cacheEntry.version, "1"); + assert.eq(cacheEntry.worksType, "works"); + } + } + + const kFilter = {$or: [{a: 1}, {b: 1}]}; + + // First run the query as a simple find command. + { + // First run. + assert.eq(coll.find(kFilter).sort({x: 1}).itcount(), 100); + checkProfilerAndCache({ + // When the SBE plan cache is used, the entry will be pinned and enabled immediately. + isActive: sbePlanCacheEnabled, + isPinned: sbePlanCacheEnabled, + fromPlanCache: false + }); + + // Second run. + assert.eq(coll.find(kFilter).sort({x: 1}).itcount(), 100); + checkProfilerAndCache( + {isActive: true, isPinned: sbePlanCacheEnabled, fromPlanCache: sbePlanCacheEnabled}); + + // Third run. + assert.eq(coll.find(kFilter).sort({x: 1}).itcount(), 100); + checkProfilerAndCache({isActive: true, isPinned: sbePlanCacheEnabled, fromPlanCache: true}); + } + + coll.getPlanCache().clear(); + + // Now run the same series of tests, but using an SBE-eligible aggregation pipeline. + { + const pipe = [ + {$match: kFilter}, + {$sort: {x: 1}}, + // We use an order-sensitive accumulator so that the $sort cannot be removed. + {$group: {_id: "$b", max: {$push: "$unknownField"}}} + ]; + + // First run. + assert.eq(coll.aggregate(pipe).itcount(), 100); + checkProfilerAndCache({ + // When the SBE plan cache is used, the entry will be pinned and enabled immediately. + isActive: sbePlanCacheEnabled, + isPinned: sbePlanCacheEnabled, + fromPlanCache: false + }); + + assert.eq(coll.aggregate(pipe).itcount(), 100); + checkProfilerAndCache( + {isActive: true, isPinned: sbePlanCacheEnabled, fromPlanCache: sbePlanCacheEnabled}); + + assert.eq(coll.aggregate(pipe).itcount(), 100); + checkProfilerAndCache({isActive: true, isPinned: sbePlanCacheEnabled, fromPlanCache: true}); + } +} + MongoRunner.stopMongod(conn); diff --git a/src/mongo/db/exec/cached_plan.cpp b/src/mongo/db/exec/cached_plan.cpp index 16b7d89c413..e98f8b47a26 100644 --- a/src/mongo/db/exec/cached_plan.cpp +++ b/src/mongo/db/exec/cached_plan.cpp @@ -270,7 +270,8 @@ Status CachedPlanStage::replan(const QueryPlannerParams& plannerParams, plan_cache_util::ConditionalClassicPlanCacheWriter{ plan_cache_util::ConditionalClassicPlanCacheWriter::alwaysOrNeverCacheMode(shouldCache), opCtx(), - collection()}, + collection(), + false /* executeInSbe */}, _specificStats.replanReason)); MultiPlanStage* multiPlanStage = static_cast<MultiPlanStage*>(child().get()); diff --git a/src/mongo/db/exec/multi_plan.cpp b/src/mongo/db/exec/multi_plan.cpp index 7946e7604ca..28cf26e41a4 100644 --- a/src/mongo/db/exec/multi_plan.cpp +++ b/src/mongo/db/exec/multi_plan.cpp @@ -301,7 +301,7 @@ Status MultiPlanStage::pickBestPlan(PlanYieldPolicy* yieldPolicy) { // Invoke the callback provided on construction, passing 'ranking' and '_candidates' to describe // the results of plan selection. - _onPickBestPlan(*_query, std::move(ranking), _candidates); + _onPickBestPlan(*_query, *this, std::move(ranking), _candidates); removeRejectedPlans(); diff --git a/src/mongo/db/exec/multi_plan.h b/src/mongo/db/exec/multi_plan.h index 2868303f110..5bace75ecb3 100644 --- a/src/mongo/db/exec/multi_plan.h +++ b/src/mongo/db/exec/multi_plan.h @@ -74,6 +74,7 @@ public: * vector of candidate plans describe the outcome of multi-planning. */ using OnPickBestPlan = std::function<void(const CanonicalQuery&, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision>, std::vector<plan_ranker::CandidatePlan>&)>; diff --git a/src/mongo/db/exec/plan_cache_util.cpp b/src/mongo/db/exec/plan_cache_util.cpp index 51ebc875e6b..870ad31732f 100644 --- a/src/mongo/db/exec/plan_cache_util.cpp +++ b/src/mongo/db/exec/plan_cache_util.cpp @@ -39,6 +39,7 @@ #include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/basic_types_gen.h" +#include "mongo/db/exec/multi_plan.h" #include "mongo/db/query/canonical_query_encoder.h" #include "mongo/db/query/classic_plan_cache.h" #include "mongo/db/query/collation/collator_interface.h" @@ -47,6 +48,7 @@ #include "mongo/db/query/plan_cache_callbacks.h" #include "mongo/db/query/plan_cache_key_factory.h" #include "mongo/db/query/plan_explainer_factory.h" +#include "mongo/db/query/plan_explainer_impl.h" #include "mongo/db/query/sbe_plan_cache.h" #include "mongo/db/query/stage_builder_util.h" #include "mongo/db/query/stage_types.h" @@ -429,19 +431,31 @@ plan_cache_debug_info::DebugInfoSBE buildDebugInfo(const QuerySolution* solution } void ClassicPlanCacheWriter::operator()(const CanonicalQuery& cq, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision> ranking, std::vector<plan_ranker::CandidatePlan>& candidates) const { - updateClassicPlanCacheFromClassicCandidatesForClassicExecution( - _opCtx, _collection.getCollectionPtr(), cq, std::move(ranking), candidates); + // Note this function is also called by ConditionalClassicPlanCacheWriter. + + if (_executeInSbe) { + auto stats = mps.getStats(); + auto nReads = computeNumReadsFromWorks(*stats, *ranking); + + updateClassicPlanCacheFromClassicCandidatesForSbeExecution( + _opCtx, _collection.getCollectionPtr(), cq, nReads, std::move(ranking), candidates); + } else { + // We've been asked to write a works value, for classic execution. + updateClassicPlanCacheFromClassicCandidatesForClassicExecution( + _opCtx, _collection.getCollectionPtr(), cq, std::move(ranking), candidates); + } } void ConditionalClassicPlanCacheWriter::operator()( const CanonicalQuery& cq, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision> ranking, std::vector<plan_ranker::CandidatePlan>& candidates) const { if (shouldCacheBasedOnCachingMode(cq, *ranking, candidates)) { - updateClassicPlanCacheFromClassicCandidatesForClassicExecution( - _opCtx, _collection.getCollectionPtr(), cq, std::move(ranking), candidates); + ClassicPlanCacheWriter::operator()(cq, mps, std::move(ranking), candidates); } } @@ -505,5 +519,15 @@ bool ConditionalClassicPlanCacheWriter::shouldCacheBasedOnCachingMode( MONGO_UNREACHABLE; } +NumReads computeNumReadsFromWorks(const PlanStageStats& stats, + const plan_ranker::PlanRankingDecision& ranking) { + auto winnerIdx = ranking.candidateOrder[0]; + auto summary = collectExecutionStatsSummary(&stats, winnerIdx); + tassert(8523807, + "Expected StatsDetails in classic runtime planner ranking decision.", + std::holds_alternative<plan_ranker::StatsDetails>(ranking.stats)); + return NumReads{summary.totalKeysExamined + summary.totalDocsExamined}; +} + } // namespace plan_cache_util } // namespace mongo diff --git a/src/mongo/db/exec/plan_cache_util.h b/src/mongo/db/exec/plan_cache_util.h index 47e06ba9598..d0610a0f935 100644 --- a/src/mongo/db/exec/plan_cache_util.h +++ b/src/mongo/db/exec/plan_cache_util.h @@ -52,6 +52,10 @@ #include "mongo/db/query/sbe_plan_ranker.h" #include "mongo/db/query/sbe_stage_builder_plan_data.h" +namespace mongo { +class MultiPlanStage; +} + namespace mongo::plan_cache_util { /** @@ -142,6 +146,7 @@ void updateSbePlanCacheWithPinnedEntry(OperationContext* opCtx, */ struct NoopPlanCacheWriter { void operator()(const CanonicalQuery&, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision>, std::vector<plan_ranker::CandidatePlan>&) const {} }; @@ -154,16 +159,19 @@ struct NoopPlanCacheWriter { */ struct ClassicPlanCacheWriter { ClassicPlanCacheWriter(OperationContext* opCtx, - const VariantCollectionPtrOrAcquisition& collection) - : _opCtx(opCtx), _collection(collection) {} + const VariantCollectionPtrOrAcquisition& collection, + bool executeInSbe) + : _opCtx(opCtx), _collection(collection), _executeInSbe(executeInSbe) {} void operator()(const CanonicalQuery& cq, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision> ranking, std::vector<plan_ranker::CandidatePlan>& candidates) const; -private: +protected: OperationContext* _opCtx; VariantCollectionPtrOrAcquisition _collection; + bool _executeInSbe; }; /** @@ -174,7 +182,7 @@ private: * - The 'Mode' configured by the caller. This 'Mode' configuration is what distinguishes this * class from the simpler 'ClassicPlanCacheWriter' above. */ -class ConditionalClassicPlanCacheWriter { +class ConditionalClassicPlanCacheWriter : public ClassicPlanCacheWriter { public: enum class Mode { // Always write a cache entry for the winning plan to the plan cache, overwriting any @@ -197,10 +205,13 @@ public: ConditionalClassicPlanCacheWriter(Mode planCachingMode, OperationContext* opCtx, - const VariantCollectionPtrOrAcquisition& collection) - : _planCachingMode{planCachingMode}, _opCtx{opCtx}, _collection{collection} {} + const VariantCollectionPtrOrAcquisition& collection, + bool executeInSbe) + : ClassicPlanCacheWriter(opCtx, collection, executeInSbe), + _planCachingMode{planCachingMode} {} void operator()(const CanonicalQuery& cq, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision> ranking, std::vector<plan_ranker::CandidatePlan>& candidates) const; @@ -211,7 +222,8 @@ protected: const std::vector<plan_ranker::CandidatePlan>& candidates) const; const Mode _planCachingMode; - OperationContext* _opCtx; - VariantCollectionPtrOrAcquisition _collection; }; + +NumReads computeNumReadsFromWorks(const PlanStageStats& stats, + const plan_ranker::PlanRankingDecision& ranking); } // namespace mongo::plan_cache_util diff --git a/src/mongo/db/query/classic_runtime_planner/multi_planner.cpp b/src/mongo/db/query/classic_runtime_planner/multi_planner.cpp index b4952d9c7c8..b832f3db122 100644 --- a/src/mongo/db/query/classic_runtime_planner/multi_planner.cpp +++ b/src/mongo/db/query/classic_runtime_planner/multi_planner.cpp @@ -38,8 +38,8 @@ MultiPlanner::MultiPlanner(PlannerData plannerData, cq()->getExpCtxRaw(), collections().getMainCollectionPtrOrAcquisition(), cq(), - plan_cache_util::ClassicPlanCacheWriter{opCtx(), - collections().getMainCollectionPtrOrAcquisition()}); + plan_cache_util::ClassicPlanCacheWriter{ + opCtx(), collections().getMainCollectionPtrOrAcquisition(), false /* executeInSbe */}); _multiplanStage = stage.get(); for (auto&& solution : solutions) { solution->indexFilterApplied = plannerParams().indexFiltersApplied; diff --git a/src/mongo/db/query/classic_runtime_planner/sub_planner.cpp b/src/mongo/db/query/classic_runtime_planner/sub_planner.cpp index be527e1f02e..982714ff66c 100644 --- a/src/mongo/db/query/classic_runtime_planner/sub_planner.cpp +++ b/src/mongo/db/query/classic_runtime_planner/sub_planner.cpp @@ -43,11 +43,14 @@ SubPlanner::SubPlanner(PlannerData plannerData) : ClassicPlannerInterface(std::m plan_cache_util::ConditionalClassicPlanCacheWriter{ plan_cache_util::ConditionalClassicPlanCacheWriter::Mode::SometimesCache, opCtx(), - collections().getMainCollectionPtrOrAcquisition()}, + collections().getMainCollectionPtrOrAcquisition(), + false /* executeInSbe */}, .onPickPlanWholeQuery = plan_cache_util::ClassicPlanCacheWriter{ - opCtx(), collections().getMainCollectionPtrOrAcquisition()}, + opCtx(), + collections().getMainCollectionPtrOrAcquisition(), + false /* executeInSbe */}, }; auto root = std::make_unique<SubplanStage>(cq()->getExpCtxRaw(), diff --git a/src/mongo/db/query/classic_runtime_planner_for_sbe/multi_planner.cpp b/src/mongo/db/query/classic_runtime_planner_for_sbe/multi_planner.cpp index 62df83d0b68..945169ee625 100644 --- a/src/mongo/db/query/classic_runtime_planner_for_sbe/multi_planner.cpp +++ b/src/mongo/db/query/classic_runtime_planner_for_sbe/multi_planner.cpp @@ -32,7 +32,6 @@ #include <absl/functional/bind_front.h> #include "mongo/db/query/plan_executor_factory.h" -#include "mongo/db/query/plan_explainer_impl.h" #include "mongo/db/query/plan_yield_policy_impl.h" #include "mongo/db/query/stage_builder_util.h" #include "mongo/logv2/log.h" @@ -126,6 +125,7 @@ bool MultiPlanner::_shouldUseEofOptimization() const { void MultiPlanner::_buildSbePlanAndMaybeCache( const CanonicalQuery& queryToCache, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision> ranking, std::vector<plan_ranker::CandidatePlan>& candidates) { invariant(queryToCache.isSbeCompatible()); @@ -136,14 +136,8 @@ void MultiPlanner::_buildSbePlanAndMaybeCache( boost::optional<NumReads> numReads; if (_shouldWriteToPlanCache) { - // Compute 'numReads'. auto stats = _multiPlanStage->getStats(); - auto winnerIdx = ranking->candidateOrder[0]; - auto summary = collectExecutionStatsSummary(stats.get(), winnerIdx); - tassert(8523807, - "Expected StatsDetails in classic runtime planner ranking decision.", - std::holds_alternative<plan_ranker::StatsDetails>(ranking->stats)); - numReads = NumReads{summary.totalKeysExamined + summary.totalDocsExamined}; + numReads = plan_cache_util::computeNumReadsFromWorks(*stats, *ranking); } // If classic plan cache is enabled, write to it. We need to do this before we extend the QSN diff --git a/src/mongo/db/query/classic_runtime_planner_for_sbe/planner_interface.h b/src/mongo/db/query/classic_runtime_planner_for_sbe/planner_interface.h index 061f80bd284..638eef09b60 100644 --- a/src/mongo/db/query/classic_runtime_planner_for_sbe/planner_interface.h +++ b/src/mongo/db/query/classic_runtime_planner_for_sbe/planner_interface.h @@ -209,6 +209,7 @@ private: // dealing with the possibility of a pushed-down agg pipeline. If '_shouldWriteToPlanCache' is // true, writes the resulting SBE plan to the SBE plan cache. void _buildSbePlanAndMaybeCache(const CanonicalQuery&, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision>, std::vector<plan_ranker::CandidatePlan>&); diff --git a/src/mongo/db/query/classic_runtime_planner_for_sbe/sub_planner.cpp b/src/mongo/db/query/classic_runtime_planner_for_sbe/sub_planner.cpp index b589060fbf6..eac2fa5191e 100644 --- a/src/mongo/db/query/classic_runtime_planner_for_sbe/sub_planner.cpp +++ b/src/mongo/db/query/classic_runtime_planner_for_sbe/sub_planner.cpp @@ -89,6 +89,7 @@ SubplanStage::PlanSelectionCallbacks SubPlanner::makeCallbacks() { return SubplanStage::PlanSelectionCallbacks{ .onPickPlanForBranch = [this](const CanonicalQuery&, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision>, std::vector<plan_ranker::CandidatePlan>&) { ++_numPerBranchMultiplans; }, .onPickPlanWholeQuery = plan_cache_util::NoopPlanCacheWriter{}, @@ -103,16 +104,22 @@ SubplanStage::PlanSelectionCallbacks SubPlanner::makeCallbacks() { plan_cache_util::ConditionalClassicPlanCacheWriter perBranchWriter{ plan_cache_util::ConditionalClassicPlanCacheWriter::Mode::SometimesCache, opCtx(), - collections().getMainCollectionPtrOrAcquisition()}; + collections().getMainCollectionPtrOrAcquisition(), + false /* executeInSbe. We set this to false because the cache entry created by this + callback is only used by the SubPlanner. It is not used for constructing a + final execution plan. This is marked by a special byte in the plan cache key + which indicates that the entry is used for subplanning only. + */}; // Wrap the conditional classic plan cache writer function object so that we can count the // number of times that multi-planning gets invoked for an $or branch. auto perBranchCallback = [this, capturedPerBranchWriter = std::move(perBranchWriter)]( const CanonicalQuery& cq, + MultiPlanStage& mps, std::unique_ptr<plan_ranker::PlanRankingDecision> ranking, std::vector<plan_ranker::CandidatePlan>& candidates) { ++_numPerBranchMultiplans; - capturedPerBranchWriter(cq, std::move(ranking), candidates); + capturedPerBranchWriter(cq, mps, std::move(ranking), candidates); }; // The query will run in SBE but we are using the classic plan cache. Use callbacks to write @@ -121,7 +128,9 @@ SubplanStage::PlanSelectionCallbacks SubPlanner::makeCallbacks() { .onPickPlanForBranch = std::move(perBranchCallback), .onPickPlanWholeQuery = plan_cache_util::ClassicPlanCacheWriter{ - opCtx(), collections().getMainCollectionPtrOrAcquisition()}, + opCtx(), + collections().getMainCollectionPtrOrAcquisition(), + true /* executeInSbe */}, }; } } diff --git a/src/mongo/dbtests/plan_ranking.cpp b/src/mongo/dbtests/plan_ranking.cpp index 2def653952e..a1d8fd7f7d2 100644 --- a/src/mongo/dbtests/plan_ranking.cpp +++ b/src/mongo/dbtests/plan_ranking.cpp @@ -153,13 +153,13 @@ public: ASSERT_GREATER_THAN_OR_EQUALS(solutions.size(), 1U); - _mps = std::make_unique<MultiPlanStage>(_expCtx.get(), - &collection.getCollection(), - cq, - plan_cache_util::ClassicPlanCacheWriter{ - opCtx(), - &collection.getCollection(), - }); + _mps = std::make_unique<MultiPlanStage>( + _expCtx.get(), + &collection.getCollection(), + cq, + plan_cache_util::ClassicPlanCacheWriter{ + opCtx(), &collection.getCollection(), false /* executeInSbe */ + }); std::unique_ptr<WorkingSet> ws(new WorkingSet()); // Put each solution from the planner into the 'MultiPlanStage'. for (size_t i = 0; i < solutions.size(); ++i) { diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp index a5393c77be4..95e22fbd133 100644 --- a/src/mongo/dbtests/query_stage_multiplan.cpp +++ b/src/mongo/dbtests/query_stage_multiplan.cpp @@ -271,7 +271,10 @@ std::unique_ptr<MultiPlanStage> runMultiPlanner(ExpressionContext* expCtx, auto cq = makeCanonicalQuery(expCtx->opCtx, nss, BSON("foo" << desiredFooValue)); unique_ptr<MultiPlanStage> mps = std::make_unique<MultiPlanStage>( - expCtx, &coll, cq.get(), plan_cache_util::ClassicPlanCacheWriter{expCtx->opCtx, &coll}); + expCtx, + &coll, + cq.get(), + plan_cache_util::ClassicPlanCacheWriter{expCtx->opCtx, &coll, false /* executeInSbe */}); mps->addPlan(createQuerySolution(), std::move(ixScanRoot), sharedWs.get()); mps->addPlan(createQuerySolution(), std::move(collScanRoot), sharedWs.get()); @@ -328,7 +331,8 @@ TEST_F(QueryStageMultiPlanTest, MPSCollectionScanVsHighlySelectiveIXScan) { _expCtx.get(), &ctx.getCollection(), cq.get(), - plan_cache_util::ClassicPlanCacheWriter{opCtx(), &ctx.getCollection()}); + plan_cache_util::ClassicPlanCacheWriter{ + opCtx(), &ctx.getCollection(), false /* executeInSbe */}); mps->addPlan(createQuerySolution(), std::move(ixScanRoot), sharedWs.get()); mps->addPlan(createQuerySolution(), std::move(collScanRoot), sharedWs.get()); @@ -488,13 +492,13 @@ TEST_F(QueryStageMultiPlanTest, MPSBackupPlan) { ASSERT_EQUALS(solutions.size(), 3U); // Fill out the MultiPlanStage. - auto mps = std::make_unique<MultiPlanStage>(_expCtx.get(), - &collection.getCollection(), - cq.get(), - plan_cache_util::ClassicPlanCacheWriter{ - opCtx(), - &collection.getCollection(), - }); + auto mps = std::make_unique<MultiPlanStage>( + _expCtx.get(), + &collection.getCollection(), + cq.get(), + plan_cache_util::ClassicPlanCacheWriter{ + opCtx(), &collection.getCollection(), false /* executeInSbe */ + }); unique_ptr<WorkingSet> ws(new WorkingSet()); // Put each solution from the planner into the MPR. for (size_t i = 0; i < solutions.size(); ++i) { @@ -591,8 +595,7 @@ TEST_F(QueryStageMultiPlanTest, MPSExplainAllPlans) { &ctx.getCollection(), cq.get(), plan_cache_util::ClassicPlanCacheWriter{ - opCtx(), - &ctx.getCollection(), + opCtx(), &ctx.getCollection(), false /* executeInSbe */ }); // Put each plan into the MultiPlanStage. Takes ownership of 'firstPlan' and 'secondPlan'. diff --git a/src/mongo/dbtests/query_stage_subplan.cpp b/src/mongo/dbtests/query_stage_subplan.cpp index 7cc54315ba0..640ab1f8541 100644 --- a/src/mongo/dbtests/query_stage_subplan.cpp +++ b/src/mongo/dbtests/query_stage_subplan.cpp @@ -134,11 +134,11 @@ public: plan_cache_util::ConditionalClassicPlanCacheWriter::Mode::SometimesCache, opCtx(), &coll, + false /* executeInSbe */ }, .onPickPlanWholeQuery = plan_cache_util::ClassicPlanCacheWriter{ - opCtx(), - &coll, + opCtx(), &coll, false /* executeInSbe */ }, }; |
