summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/query_stage_multiplan.cpp
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2020-09-17 17:09:19 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-09-26 02:12:49 +0000
commit2b82ab88982566114d1bb7667477b71c883b0799 (patch)
treec152b35ff047fdc42f69aa6cd6b04fee1d811fe4 /src/mongo/dbtests/query_stage_multiplan.cpp
parent08e92a678a1ed288f6a95e7950597e082556ae59 (diff)
downloadmongo-2b82ab88982566114d1bb7667477b71c883b0799.tar.gz
SERVER-50984 Add CollectionPtr to replace usage of const Collection*
It implements a yieldable interface that is used to re-load the Collection pointer from the catalog after a yield that released locks. With lock-free reads and copy-on-write on Collection instances releasing locks without notifying an AutoGetCollection at a higher level may cause its pointers to dangle if a MODE_X writer installs a new Collection instance in the catalog. CollectionPtr should be passed by const reference so a yield can notify all the way up.
Diffstat (limited to 'src/mongo/dbtests/query_stage_multiplan.cpp')
-rw-r--r--src/mongo/dbtests/query_stage_multiplan.cpp44
1 files changed, 22 insertions, 22 deletions
diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp
index 3d77785ac5c..9ee623edb87 100644
--- a/src/mongo/dbtests/query_stage_multiplan.cpp
+++ b/src/mongo/dbtests/query_stage_multiplan.cpp
@@ -138,7 +138,7 @@ std::unique_ptr<CanonicalQuery> makeCanonicalQuery(OperationContext* opCtx,
}
unique_ptr<PlanStage> getIxScanPlan(ExpressionContext* expCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
WorkingSet* sharedWs,
int desiredFooValue) {
std::vector<const IndexDescriptor*> indexes;
@@ -168,7 +168,7 @@ unique_ptr<MatchExpression> makeMatchExpressionFromFilter(ExpressionContext* exp
unique_ptr<PlanStage> getCollScanPlan(ExpressionContext* expCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
WorkingSet* sharedWs,
MatchExpression* matchExpr) {
CollectionScanParams csparams;
@@ -181,7 +181,7 @@ unique_ptr<PlanStage> getCollScanPlan(ExpressionContext* expCtx,
std::unique_ptr<MultiPlanStage> runMultiPlanner(ExpressionContext* expCtx,
const NamespaceString& nss,
- const Collection* coll,
+ const CollectionPtr& coll,
int desiredFooValue) {
// Plan 0: IXScan over foo == desiredFooValue
// Every call to work() returns something so this should clearly win (by current scoring
@@ -227,7 +227,7 @@ TEST_F(QueryStageMultiPlanTest, MPSCollectionScanVsHighlySelectiveIXScan) {
addIndex(BSON("foo" << 1));
AutoGetCollectionForReadCommand ctx(_opCtx.get(), nss);
- const Collection* coll = ctx.getCollection();
+ const CollectionPtr& coll = ctx.getCollection();
// Plan 0: IXScan over foo == 7
// Every call to work() returns something so this should clearly win (by current scoring
@@ -288,7 +288,7 @@ TEST_F(QueryStageMultiPlanTest, MPSDoesNotCreateActiveCacheEntryImmediately) {
addIndex(BSON("foo" << 1));
AutoGetCollectionForReadCommand ctx(_opCtx.get(), nss);
- const Collection* coll = ctx.getCollection();
+ const CollectionPtr& coll = ctx.getCollection();
const auto cq = makeCanonicalQuery(_opCtx.get(), nss, BSON("foo" << 7));
@@ -343,7 +343,7 @@ TEST_F(QueryStageMultiPlanTest, MPSDoesCreatesActiveEntryWhenInactiveEntriesDisa
addIndex(BSON("foo" << 1));
AutoGetCollectionForReadCommand ctx(_opCtx.get(), nss);
- const Collection* coll = ctx.getCollection();
+ const CollectionPtr& coll = ctx.getCollection();
const auto cq = makeCanonicalQuery(_opCtx.get(), nss, BSON("foo" << 7));
@@ -370,8 +370,7 @@ TEST_F(QueryStageMultiPlanTest, MPSBackupPlan) {
addIndex(BSON("a" << 1));
addIndex(BSON("b" << 1));
- AutoGetCollectionForReadCommand ctx(_opCtx.get(), nss);
- const Collection* collection = ctx.getCollection();
+ AutoGetCollectionForReadCommand collection(_opCtx.get(), nss);
// Query for both 'a' and 'b' and sort on 'b'.
auto qr = std::make_unique<QueryRequest>(nss);
@@ -388,7 +387,7 @@ TEST_F(QueryStageMultiPlanTest, MPSBackupPlan) {
// Get planner params.
QueryPlannerParams plannerParams;
- fillOutPlannerParams(_opCtx.get(), collection, cq.get(), &plannerParams);
+ fillOutPlannerParams(_opCtx.get(), collection.getCollection(), cq.get(), &plannerParams);
// Plan.
auto statusWithSolutions = QueryPlanner::plan(*cq, plannerParams);
@@ -400,12 +399,13 @@ TEST_F(QueryStageMultiPlanTest, MPSBackupPlan) {
ASSERT_EQUALS(solutions.size(), 3U);
// Fill out the MultiPlanStage.
- unique_ptr<MultiPlanStage> mps(new MultiPlanStage(_expCtx.get(), collection, cq.get()));
+ unique_ptr<MultiPlanStage> mps(
+ new MultiPlanStage(_expCtx.get(), collection.getCollection(), cq.get()));
unique_ptr<WorkingSet> ws(new WorkingSet());
// Put each solution from the planner into the MPR.
for (size_t i = 0; i < solutions.size(); ++i) {
auto&& root = stage_builder::buildClassicExecutableTree(
- _opCtx.get(), collection, *cq, *solutions[i], ws.get());
+ _opCtx.get(), collection.getCollection(), *cq, *solutions[i], ws.get());
mps->addPlan(std::move(solutions[i]), std::move(root), ws.get());
}
@@ -546,7 +546,7 @@ TEST_F(QueryStageMultiPlanTest, MPSSummaryStats) {
addIndex(BSON("foo" << -1 << "bar" << 1));
AutoGetCollectionForReadCommand ctx(_opCtx.get(), nss);
- const Collection* coll = ctx.getCollection();
+ const CollectionPtr& coll = ctx.getCollection();
// Create the executor (Matching all documents).
auto qr = std::make_unique<QueryRequest>(nss);
@@ -586,20 +586,20 @@ TEST_F(QueryStageMultiPlanTest, ShouldReportErrorIfExceedsTimeLimitDuringPlannin
addIndex(BSON("foo" << 1));
addIndex(BSON("foo" << -1 << "bar" << 1));
- AutoGetCollectionForReadCommand ctx(_opCtx.get(), nss);
- const auto coll = ctx.getCollection();
+ AutoGetCollectionForReadCommand coll(_opCtx.get(), nss);
// Plan 0: IXScan over foo == 7
// Every call to work() returns something so this should clearly win (by current scoring
// at least).
unique_ptr<WorkingSet> sharedWs(new WorkingSet());
- unique_ptr<PlanStage> ixScanRoot = getIxScanPlan(_expCtx.get(), coll, sharedWs.get(), 7);
+ unique_ptr<PlanStage> ixScanRoot =
+ getIxScanPlan(_expCtx.get(), coll.getCollection(), sharedWs.get(), 7);
// Make the filter.
BSONObj filterObj = BSON("foo" << 7);
unique_ptr<MatchExpression> filter = makeMatchExpressionFromFilter(_expCtx.get(), filterObj);
unique_ptr<PlanStage> collScanRoot =
- getCollScanPlan(_expCtx.get(), coll, sharedWs.get(), filter.get());
+ getCollScanPlan(_expCtx.get(), coll.getCollection(), sharedWs.get(), filter.get());
auto queryRequest = std::make_unique<QueryRequest>(nss);
@@ -607,7 +607,7 @@ TEST_F(QueryStageMultiPlanTest, ShouldReportErrorIfExceedsTimeLimitDuringPlannin
auto canonicalQuery =
uassertStatusOK(CanonicalQuery::canonicalize(opCtx(), std::move(queryRequest)));
MultiPlanStage multiPlanStage(
- _expCtx.get(), ctx.getCollection(), canonicalQuery.get(), PlanCachingMode::NeverCache);
+ _expCtx.get(), coll.getCollection(), canonicalQuery.get(), PlanCachingMode::NeverCache);
multiPlanStage.addPlan(createQuerySolution(), std::move(ixScanRoot), sharedWs.get());
multiPlanStage.addPlan(createQuerySolution(), std::move(collScanRoot), sharedWs.get());
@@ -627,27 +627,27 @@ TEST_F(QueryStageMultiPlanTest, ShouldReportErrorIfKilledDuringPlanning) {
addIndex(BSON("foo" << 1));
addIndex(BSON("foo" << -1 << "bar" << 1));
- AutoGetCollectionForReadCommand ctx(_opCtx.get(), nss);
- const auto coll = ctx.getCollection();
+ AutoGetCollectionForReadCommand coll(_opCtx.get(), nss);
// Plan 0: IXScan over foo == 7
// Every call to work() returns something so this should clearly win (by current scoring
// at least).
unique_ptr<WorkingSet> sharedWs(new WorkingSet());
- unique_ptr<PlanStage> ixScanRoot = getIxScanPlan(_expCtx.get(), coll, sharedWs.get(), 7);
+ unique_ptr<PlanStage> ixScanRoot =
+ getIxScanPlan(_expCtx.get(), coll.getCollection(), sharedWs.get(), 7);
// Plan 1: CollScan.
BSONObj filterObj = BSON("foo" << 7);
unique_ptr<MatchExpression> filter = makeMatchExpressionFromFilter(_expCtx.get(), filterObj);
unique_ptr<PlanStage> collScanRoot =
- getCollScanPlan(_expCtx.get(), coll, sharedWs.get(), filter.get());
+ getCollScanPlan(_expCtx.get(), coll.getCollection(), sharedWs.get(), filter.get());
auto queryRequest = std::make_unique<QueryRequest>(nss);
queryRequest->setFilter(BSON("foo" << BSON("$gte" << 0)));
auto canonicalQuery =
uassertStatusOK(CanonicalQuery::canonicalize(opCtx(), std::move(queryRequest)));
MultiPlanStage multiPlanStage(
- _expCtx.get(), ctx.getCollection(), canonicalQuery.get(), PlanCachingMode::NeverCache);
+ _expCtx.get(), coll.getCollection(), canonicalQuery.get(), PlanCachingMode::NeverCache);
multiPlanStage.addPlan(createQuerySolution(), std::move(ixScanRoot), sharedWs.get());
multiPlanStage.addPlan(createQuerySolution(), std::move(collScanRoot), sharedWs.get());