diff options
Diffstat (limited to 'src/mongo/dbtests')
-rw-r--r-- | src/mongo/dbtests/cursor_manager_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/dbtests/deferred_writer.cpp | 2 | ||||
-rw-r--r-- | src/mongo/dbtests/documentsourcetests.cpp | 19 | ||||
-rw-r--r-- | src/mongo/dbtests/plan_executor_invalidation_test.cpp | 48 | ||||
-rw-r--r-- | src/mongo/dbtests/query_plan_executor.cpp | 24 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_and.cpp | 8 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_cached_plan.cpp | 6 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_collscan.cpp | 12 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_count.cpp | 11 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_count_scan.cpp | 12 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_delete.cpp | 2 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_ixscan.cpp | 12 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_merge_sort.cpp | 20 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_multiplan.cpp | 6 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_sort.cpp | 6 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_subplan.cpp | 16 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_tests.cpp | 2 | ||||
-rw-r--r-- | src/mongo/dbtests/query_stage_update.cpp | 4 |
18 files changed, 110 insertions, 102 deletions
diff --git a/src/mongo/dbtests/cursor_manager_test.cpp b/src/mongo/dbtests/cursor_manager_test.cpp index 1465e0428b2..a5065dc13f7 100644 --- a/src/mongo/dbtests/cursor_manager_test.cpp +++ b/src/mongo/dbtests/cursor_manager_test.cpp @@ -79,7 +79,7 @@ public: plan_executor_factory::make(expCtx, std::move(workingSet), std::move(queuedDataStage), - nullptr, + &CollectionPtr::null, PlanYieldPolicy::YieldPolicy::NO_YIELD, kTestNss)); } diff --git a/src/mongo/dbtests/deferred_writer.cpp b/src/mongo/dbtests/deferred_writer.cpp index 07ae48ebd2c..d45d9bedaa2 100644 --- a/src/mongo/dbtests/deferred_writer.cpp +++ b/src/mongo/dbtests/deferred_writer.cpp @@ -119,7 +119,7 @@ public: auto plan = InternalPlanner::collectionScan(_opCtx.get(), kTestNamespace.ns(), - agc.getCollection(), + &agc.getCollection(), PlanYieldPolicy::YieldPolicy::NO_YIELD); std::vector<BSONObj> result; diff --git a/src/mongo/dbtests/documentsourcetests.cpp b/src/mongo/dbtests/documentsourcetests.cpp index 71e5ac4927d..cb49a3c3c63 100644 --- a/src/mongo/dbtests/documentsourcetests.cpp +++ b/src/mongo/dbtests/documentsourcetests.cpp @@ -90,6 +90,7 @@ protected: _source.reset(); dbtests::WriteContextForTests ctx(opCtx(), nss.ns()); + _coll = ctx.getCollection(); auto qr = std::make_unique<QueryRequest>(nss); if (hint) { @@ -97,15 +98,12 @@ protected: } auto cq = uassertStatusOK(CanonicalQuery::canonicalize(opCtx(), std::move(qr))); - auto exec = uassertStatusOK(getExecutor(opCtx(), - ctx.getCollection(), - std::move(cq), - PlanYieldPolicy::YieldPolicy::NO_YIELD, - 0)); + auto exec = uassertStatusOK( + getExecutor(opCtx(), &_coll, std::move(cq), PlanYieldPolicy::YieldPolicy::NO_YIELD, 0)); exec->saveState(); _source = DocumentSourceCursor::create( - ctx.getCollection(), std::move(exec), _ctx, DocumentSourceCursor::CursorType::kRegular); + _coll, std::move(exec), _ctx, DocumentSourceCursor::CursorType::kRegular); } intrusive_ptr<ExpressionContextForTest> ctx() { @@ -134,6 +132,7 @@ private: // It is important that these are ordered to ensure correct destruction order. intrusive_ptr<ExpressionContextForTest> _ctx; intrusive_ptr<DocumentSourceCursor> _source; + CollectionPtr _coll; }; /** Create a DocumentSourceCursor. */ @@ -318,7 +317,7 @@ TEST_F(DocumentSourceCursorTest, TailableAwaitDataCursorShouldErrorAfterTimeout) uassertStatusOK(plan_executor_factory::make(std::move(canonicalQuery), std::move(workingSet), std::move(collectionScan), - readLock.getCollection(), + &readLock.getCollection(), PlanYieldPolicy::YieldPolicy::ALWAYS_TIME_OUT)); // Make a DocumentSourceCursor. @@ -359,7 +358,7 @@ TEST_F(DocumentSourceCursorTest, NonAwaitDataCursorShouldErrorAfterTimeout) { uassertStatusOK(plan_executor_factory::make(std::move(canonicalQuery), std::move(workingSet), std::move(collectionScan), - readLock.getCollection(), + &readLock.getCollection(), PlanYieldPolicy::YieldPolicy::ALWAYS_TIME_OUT)); // Make a DocumentSourceCursor. @@ -409,7 +408,7 @@ TEST_F(DocumentSourceCursorTest, TailableAwaitDataCursorShouldErrorAfterBeingKil plan_executor_factory::make(std::move(canonicalQuery), std::move(workingSet), std::move(collectionScan), - readLock.getCollection(), + &readLock.getCollection(), PlanYieldPolicy::YieldPolicy::ALWAYS_MARK_KILLED)); // Make a DocumentSourceCursor. @@ -449,7 +448,7 @@ TEST_F(DocumentSourceCursorTest, NormalCursorShouldErrorAfterBeingKilled) { plan_executor_factory::make(std::move(canonicalQuery), std::move(workingSet), std::move(collectionScan), - readLock.getCollection(), + &readLock.getCollection(), PlanYieldPolicy::YieldPolicy::ALWAYS_MARK_KILLED)); // Make a DocumentSourceCursor. diff --git a/src/mongo/dbtests/plan_executor_invalidation_test.cpp b/src/mongo/dbtests/plan_executor_invalidation_test.cpp index 8a5369ba36c..7d52881cc51 100644 --- a/src/mongo/dbtests/plan_executor_invalidation_test.cpp +++ b/src/mongo/dbtests/plan_executor_invalidation_test.cpp @@ -87,12 +87,12 @@ public: std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); // Takes ownership of 'ws', 'scan', and 'cq'. - auto statusWithPlanExecutor = plan_executor_factory::make( - std::move(cq), - std::move(ws), - std::move(scan), - CollectionCatalog::get(&_opCtx).lookupCollectionByNamespace(&_opCtx, nss), - PlanYieldPolicy::YieldPolicy::YIELD_MANUAL); + auto statusWithPlanExecutor = + plan_executor_factory::make(std::move(cq), + std::move(ws), + std::move(scan), + &collection(), + PlanYieldPolicy::YieldPolicy::YIELD_MANUAL); ASSERT_OK(statusWithPlanExecutor.getStatus()); return std::move(statusWithPlanExecutor.getValue()); @@ -105,7 +105,7 @@ public: &_opCtx, keyPattern, _makeMinimalIndexSpec(keyPattern)); ASSERT(indexDescriptor); return InternalPlanner::indexScan(&_opCtx, - collection(), + &collection(), indexDescriptor, startKey, endKey, @@ -117,8 +117,9 @@ public: return 50; } - CollectionPtr collection() const { - return CollectionCatalog::get(&_opCtx).lookupCollectionByNamespace(&_opCtx, nss); + const CollectionPtr& collection() const { + _coll = CollectionCatalog::get(&_opCtx).lookupCollectionByNamespace(&_opCtx, nss); + return _coll; } void truncateCollection() const { @@ -135,6 +136,7 @@ public: OperationContext& _opCtx = *_opCtxPtr; unique_ptr<dbtests::WriteContextForTests> _ctx; DBDirectClient _client; + mutable CollectionPtr _coll; boost::intrusive_ptr<ExpressionContext> _expCtx; @@ -162,7 +164,7 @@ TEST_F(PlanExecutorInvalidationTest, ExecutorToleratesDeletedDocumentsDuringYiel _client.remove(nss.ns(), BSON("foo" << 10)); _client.remove(nss.ns(), BSON("foo" << 11)); - exec->restoreState(nullptr); + exec->restoreState(&collection()); // Make sure that the PlanExecutor moved forward over the deleted data. We don't see foo==10 or // foo==11. @@ -189,7 +191,7 @@ TEST_F(PlanExecutorInvalidationTest, PlanExecutorThrowsOnRestoreWhenCollectionIs // Drop a collection that's not ours. _client.dropCollection("unittests.someboguscollection"); - exec->restoreState(nullptr); + exec->restoreState(&collection()); ASSERT_EQUALS(PlanExecutor::ADVANCED, exec->getNext(&obj, nullptr)); ASSERT_EQUALS(10, obj["foo"].numberInt()); @@ -198,7 +200,7 @@ TEST_F(PlanExecutorInvalidationTest, PlanExecutorThrowsOnRestoreWhenCollectionIs _client.dropCollection(nss.ns()); - ASSERT_THROWS_CODE(exec->restoreState(nullptr), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(exec->restoreState(&collection()), DBException, ErrorCodes::QueryPlanKilled); } TEST_F(PlanExecutorInvalidationTest, CollScanExecutorDoesNotDieWhenAllIndicesDropped) { @@ -215,7 +217,7 @@ TEST_F(PlanExecutorInvalidationTest, CollScanExecutorDoesNotDieWhenAllIndicesDro exec->saveState(); _client.dropIndexes(nss.ns()); - exec->restoreState(nullptr); + exec->restoreState(&collection()); // Read the rest of the collection. for (int i = 10; i < N(); ++i) { @@ -238,7 +240,7 @@ TEST_F(PlanExecutorInvalidationTest, CollScanExecutorDoesNotDieWhenOneIndexDropp exec->saveState(); _client.dropIndex(nss.ns(), BSON("foo" << 1)); - exec->restoreState(nullptr); + exec->restoreState(&collection()); // Read the rest of the collection. for (int i = 10; i < N(); ++i) { @@ -268,7 +270,7 @@ TEST_F(PlanExecutorInvalidationTest, IxscanExecutorDiesWhenAllIndexesDropped) { _client.dropIndexes(nss.ns()); // Restoring the executor should throw. - ASSERT_THROWS_CODE(exec->restoreState(nullptr), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(exec->restoreState(&collection()), DBException, ErrorCodes::QueryPlanKilled); } TEST_F(PlanExecutorInvalidationTest, IxscanExecutorDiesWhenIndexBeingScannedIsDropped) { @@ -289,7 +291,7 @@ TEST_F(PlanExecutorInvalidationTest, IxscanExecutorDiesWhenIndexBeingScannedIsDr _client.dropIndex(nss.ns(), keyPattern); // Restoring the executor should throw. - ASSERT_THROWS_CODE(exec->restoreState(nullptr), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(exec->restoreState(&collection()), DBException, ErrorCodes::QueryPlanKilled); } TEST_F(PlanExecutorInvalidationTest, IxscanExecutorSurvivesWhenUnrelatedIndexIsDropped) { @@ -311,7 +313,7 @@ TEST_F(PlanExecutorInvalidationTest, IxscanExecutorSurvivesWhenUnrelatedIndexIsD // state. exec->saveState(); _client.dropIndex(nss.ns(), keyPatternBar); - exec->restoreState(nullptr); + exec->restoreState(&collection()); // Scan the rest of the index. for (int i = 10; i < N(); ++i) { @@ -337,7 +339,7 @@ TEST_F(PlanExecutorInvalidationTest, ExecutorThrowsOnRestoreWhenDatabaseIsDroppe _ctx.reset(); _client.dropDatabase("somesillydb"); _ctx.reset(new dbtests::WriteContextForTests(&_opCtx, nss.ns())); - exec->restoreState(nullptr); + exec->restoreState(&collection()); ASSERT_EQUALS(PlanExecutor::ADVANCED, exec->getNext(&obj, nullptr)); ASSERT_EQUALS(10, obj["foo"].numberInt()); @@ -348,7 +350,7 @@ TEST_F(PlanExecutorInvalidationTest, ExecutorThrowsOnRestoreWhenDatabaseIsDroppe _ctx.reset(); _client.dropDatabase("unittests"); _ctx.reset(new dbtests::WriteContextForTests(&_opCtx, nss.ns())); - ASSERT_THROWS_CODE(exec->restoreState(nullptr), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(exec->restoreState(&collection()), DBException, ErrorCodes::QueryPlanKilled); } // TODO SERVER-31695: Allow PlanExecutors to remain valid after collection rename. @@ -371,7 +373,7 @@ TEST_F(PlanExecutorInvalidationTest, CollScanDiesOnCollectionRenameWithinDatabas << "dropTarget" << true), info)); - ASSERT_THROWS_CODE(exec->restoreState(nullptr), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(exec->restoreState(&collection()), DBException, ErrorCodes::QueryPlanKilled); } // TODO SERVER-31695: Allow PlanExecutors to remain valid after collection rename. @@ -397,7 +399,7 @@ TEST_F(PlanExecutorInvalidationTest, IxscanDiesOnCollectionRenameWithinDatabase) << "dropTarget" << true), info)); - ASSERT_THROWS_CODE(exec->restoreState(nullptr), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(exec->restoreState(&collection()), DBException, ErrorCodes::QueryPlanKilled); } TEST_F(PlanExecutorInvalidationTest, IxscanDiesWhenTruncateCollectionDropsAllIndices) { @@ -417,7 +419,7 @@ TEST_F(PlanExecutorInvalidationTest, IxscanDiesWhenTruncateCollectionDropsAllInd // expected error code. exec->saveState(); truncateCollection(); - ASSERT_THROWS_CODE(exec->restoreState(nullptr), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(exec->restoreState(&collection()), DBException, ErrorCodes::QueryPlanKilled); } TEST_F(PlanExecutorInvalidationTest, CollScanExecutorSurvivesCollectionTruncate) { @@ -434,7 +436,7 @@ TEST_F(PlanExecutorInvalidationTest, CollScanExecutorSurvivesCollectionTruncate) // successfully. exec->saveState(); truncateCollection(); - exec->restoreState(nullptr); + exec->restoreState(&collection()); // Since all documents in the collection have been deleted, the PlanExecutor should issue EOF. ASSERT_EQUALS(PlanExecutor::IS_EOF, exec->getNext(&obj, nullptr)); diff --git a/src/mongo/dbtests/query_plan_executor.cpp b/src/mongo/dbtests/query_plan_executor.cpp index 491755db37e..83fbe89282b 100644 --- a/src/mongo/dbtests/query_plan_executor.cpp +++ b/src/mongo/dbtests/query_plan_executor.cpp @@ -120,7 +120,7 @@ public: // Hand the plan off to the executor. auto statusWithPlanExecutor = plan_executor_factory::make( - std::move(cq), std::move(ws), std::move(root), coll, yieldPolicy); + std::move(cq), std::move(ws), std::move(root), &coll, yieldPolicy); ASSERT_OK(statusWithPlanExecutor.getStatus()); return std::move(statusWithPlanExecutor.getValue()); } @@ -136,10 +136,8 @@ public: * Returns a PlanExecutor capable of executing an index scan * over the specified index with the specified bounds. */ - unique_ptr<PlanExecutor, PlanExecutor::Deleter> makeIndexScanExec(Database* db, - BSONObj& indexSpec, - int start, - int end) { + unique_ptr<PlanExecutor, PlanExecutor::Deleter> makeIndexScanExec( + Database* db, const CollectionPtr& coll, BSONObj& indexSpec, int start, int end) { // Build the index scan stage. auto descriptor = getIndex(db, indexSpec); IndexScanParams ixparams(&_opCtx, descriptor); @@ -148,10 +146,6 @@ public: ixparams.bounds.endKey = BSON("" << end); ixparams.bounds.boundInclusion = BoundInclusion::kIncludeBothStartAndEndKeys; - const CollectionPtr& coll = - CollectionCatalog::get(&_opCtx).lookupCollectionByNamespace(&_opCtx, nss); - - unique_ptr<WorkingSet> ws(new WorkingSet()); auto ixscan = std::make_unique<IndexScan>(_expCtx.get(), coll, ixparams, ws.get(), nullptr); unique_ptr<PlanStage> root = @@ -168,7 +162,7 @@ public: plan_executor_factory::make(std::move(cq), std::move(ws), std::move(root), - coll, + &coll, PlanYieldPolicy::YieldPolicy::YIELD_MANUAL); ASSERT_OK(statusWithPlanExecutor.getStatus()); return std::move(statusWithPlanExecutor.getValue()); @@ -214,7 +208,7 @@ TEST_F(PlanExecutorTest, DropIndexScanAgg) { // Create an "inner" plan executor and register it with the cursor manager so that it can // get notified when the collection is dropped. unique_ptr<PlanExecutor, PlanExecutor::Deleter> innerExec( - makeIndexScanExec(ctx.db(), indexSpec, 7, 10)); + makeIndexScanExec(ctx.db(), collection, indexSpec, 7, 10)); // Wrap the "inner" plan executor in a DocumentSourceCursor and add it as the first source // in the pipeline. @@ -311,12 +305,14 @@ TEST_F(PlanExecutorTest, ShouldReportErrorIfKilledDuringYield) { class PlanExecutorSnapshotTest : public PlanExecutorTest { protected: - void setupCollection() { + CollectionPtr setupCollection() { insert(BSON("_id" << 1 << "a" << 1)); insert(BSON("_id" << 2 << "a" << 2 << "payload" << "x")); insert(BSON("_id" << 3 << "a" << 3)); insert(BSON("_id" << 4 << "a" << 4)); + + return CollectionCatalog::get(&_opCtx).lookupCollectionByNamespace(&_opCtx, nss); } /** @@ -384,12 +380,12 @@ TEST_F(PlanExecutorSnapshotTest, SnapshotControl) { */ TEST_F(PlanExecutorSnapshotTest, SnapshotTest) { dbtests::WriteContextForTests ctx(&_opCtx, nss.ns()); - setupCollection(); + auto coll = setupCollection(); BSONObj indexSpec = BSON("_id" << 1); addIndex(indexSpec); BSONObj filterObj = fromjson("{a: {$gte: 2}}"); - auto exec = makeIndexScanExec(ctx.db(), indexSpec, 2, 5); + auto exec = makeIndexScanExec(ctx.db(), coll, indexSpec, 2, 5); BSONObj objOut; ASSERT_EQUALS(PlanExecutor::ADVANCED, exec->getNext(&objOut, nullptr)); diff --git a/src/mongo/dbtests/query_stage_and.cpp b/src/mongo/dbtests/query_stage_and.cpp index 4a1bfa748ce..064f2a59236 100644 --- a/src/mongo/dbtests/query_stage_and.cpp +++ b/src/mongo/dbtests/query_stage_and.cpp @@ -226,7 +226,7 @@ public: } } size_t memUsageAfter = ah->getMemUsage(); - ah->restoreState(); + ah->restoreState(&coll); // The deleted result should still be buffered inside the AND_HASH stage, so there should be // no change in memory consumption. @@ -319,7 +319,7 @@ public: size_t memUsageAfter = ah->getMemUsage(); ASSERT_EQUALS(memUsageBefore, memUsageAfter); - ah->restoreState(); + ah->restoreState(&coll); // We expect that the deleted document doers not appear in our result set. int count = 0; @@ -963,7 +963,7 @@ public: // very first insert, which should be the very first thing in data. Delete it. ah->saveState(); remove(coll->docFor(&_opCtx, *data.begin()).value()); - ah->restoreState(); + ah->restoreState(&coll); auto it = data.begin(); @@ -995,7 +995,7 @@ public: // Remove a result that's coming up. ah->saveState(); remove(coll->docFor(&_opCtx, *it).value()); - ah->restoreState(); + ah->restoreState(&coll); // Get all results aside from the two we deleted. while (!ah->isEOF()) { diff --git a/src/mongo/dbtests/query_stage_cached_plan.cpp b/src/mongo/dbtests/query_stage_cached_plan.cpp index 8bf13d8f2c6..4625bd6ebf9 100644 --- a/src/mongo/dbtests/query_stage_cached_plan.cpp +++ b/src/mongo/dbtests/query_stage_cached_plan.cpp @@ -476,7 +476,9 @@ TEST_F(QueryStageCachedPlan, ThrowsOnYieldRecoveryWhenIndexIsDroppedBeforePlanSe readLock.reset(); dropIndex(keyPattern); readLock.emplace(&_opCtx, nss); - ASSERT_THROWS_CODE(cachedPlanStage.restoreState(), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(cachedPlanStage.restoreState(&readLock->getCollection()), + DBException, + ErrorCodes::QueryPlanKilled); } TEST_F(QueryStageCachedPlan, DoesNotThrowOnYieldRecoveryWhenIndexIsDroppedAferPlanSelection) { @@ -521,7 +523,7 @@ TEST_F(QueryStageCachedPlan, DoesNotThrowOnYieldRecoveryWhenIndexIsDroppedAferPl readLock.reset(); dropIndex(keyPattern); readLock.emplace(&_opCtx, nss); - cachedPlanStage.restoreState(); + cachedPlanStage.restoreState(&readLock->getCollection()); } } // namespace QueryStageCachedPlan diff --git a/src/mongo/dbtests/query_stage_collscan.cpp b/src/mongo/dbtests/query_stage_collscan.cpp index 53aa2e78483..4b09cd82750 100644 --- a/src/mongo/dbtests/query_stage_collscan.cpp +++ b/src/mongo/dbtests/query_stage_collscan.cpp @@ -107,7 +107,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(ps), - collection.getCollection(), + &collection.getCollection(), PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -200,7 +200,7 @@ TEST_F(QueryStageCollectionScanTest, QueryStageCollscanObjectsInOrderForward) { plan_executor_factory::make(_expCtx, std::move(ws), std::move(ps), - collection.getCollection(), + &collection.getCollection(), PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -232,7 +232,7 @@ TEST_F(QueryStageCollectionScanTest, QueryStageCollscanObjectsInOrderBackward) { plan_executor_factory::make(_expCtx, std::move(ws), std::move(ps), - collection.getCollection(), + &collection.getCollection(), PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -281,7 +281,7 @@ TEST_F(QueryStageCollectionScanTest, QueryStageCollscanDeleteUpcomingObject) { // Remove recordIds[count]. scan->saveState(); remove(coll->docFor(&_opCtx, recordIds[count]).value()); - scan->restoreState(); + scan->restoreState(&coll); // Skip over recordIds[count]. ++count; @@ -334,7 +334,7 @@ TEST_F(QueryStageCollectionScanTest, QueryStageCollscanDeleteUpcomingObjectBackw // Remove recordIds[count]. scan->saveState(); remove(coll->docFor(&_opCtx, recordIds[count]).value()); - scan->restoreState(); + scan->restoreState(&coll); // Skip over recordIds[count]. ++count; @@ -388,7 +388,7 @@ TEST_F(QueryStageCollectionScanTest, QueryTestCollscanResumeAfterRecordIdSeekSuc plan_executor_factory::make(_expCtx, std::move(ws), std::move(ps), - collection.getCollection(), + &collection.getCollection(), PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/dbtests/query_stage_count.cpp b/src/mongo/dbtests/query_stage_count.cpp index a43346e849b..008d7fbff8f 100644 --- a/src/mongo/dbtests/query_stage_count.cpp +++ b/src/mongo/dbtests/query_stage_count.cpp @@ -71,14 +71,15 @@ public: WriteUnitOfWork wunit(&_opCtx); _ctx.db()->dropCollection(&_opCtx, nss()).transitional_ignore(); - _coll = _ctx.db()->createCollection(&_opCtx, nss()); + auto coll = _ctx.db()->createCollection(&_opCtx, nss()); - _coll->getIndexCatalog() + coll->getIndexCatalog() ->createIndexOnEmptyCollection(&_opCtx, BSON("key" << BSON("x" << 1) << "name" << "x_1" << "v" << 1)) .status_with_transitional_ignore(); + _coll = coll; for (int i = 0; i < kDocuments; i++) { insert(BSON(GENOID << "x" << i)); @@ -190,14 +191,14 @@ public: } // Resume from yield. - countStage.restoreState(); + countStage.restoreState(&_coll); } return static_cast<const CountStats*>(countStage.getSpecificStats()); } IndexScan* createIndexScan(MatchExpression* expr, WorkingSet* ws) { - IndexCatalog* catalog = _coll->getIndexCatalog(); + const IndexCatalog* catalog = _coll->getIndexCatalog(); std::vector<const IndexDescriptor*> indexes; catalog->findIndexesByKeyPattern(&_opCtx, BSON("x" << 1), false, &indexes); ASSERT_EQ(indexes.size(), 1U); @@ -237,7 +238,7 @@ protected: Lock::DBLock _dbLock; OldClientContext _ctx; boost::intrusive_ptr<ExpressionContext> _expCtx; - Collection* _coll; + CollectionPtr _coll; }; class QueryStageCountNoChangeDuringYield : public CountStageTest { diff --git a/src/mongo/dbtests/query_stage_count_scan.cpp b/src/mongo/dbtests/query_stage_count_scan.cpp index cf6f4005405..91f0d847ad4 100644 --- a/src/mongo/dbtests/query_stage_count_scan.cpp +++ b/src/mongo/dbtests/query_stage_count_scan.cpp @@ -336,7 +336,8 @@ public: static_cast<PlanStage*>(&count)->saveState(); // Recover from yield - static_cast<PlanStage*>(&count)->restoreState(); + auto coll = getCollection(); + static_cast<PlanStage*>(&count)->restoreState(&coll); // finish counting while (PlanStage::IS_EOF != countState) { @@ -391,7 +392,8 @@ public: remove(BSON("a" << GTE << 5)); // Recover from yield - static_cast<PlanStage*>(&count)->restoreState(); + auto coll = getCollection(); + static_cast<PlanStage*>(&count)->restoreState(&coll); // finish counting while (PlanStage::IS_EOF != countState) { @@ -449,7 +451,8 @@ public: insert(BSON("a" << 6.5)); // Recover from yield - static_cast<PlanStage*>(&count)->restoreState(); + auto coll = getCollection(); + static_cast<PlanStage*>(&count)->restoreState(&coll); // finish counting while (PlanStage::IS_EOF != countState) { @@ -569,7 +572,8 @@ public: remove(BSON("a" << 1 << "b" << 5)); // Recover from yield - static_cast<PlanStage*>(&count)->restoreState(); + auto coll = getCollection(); + static_cast<PlanStage*>(&count)->restoreState(&coll); // finish counting while (PlanStage::IS_EOF != countState) { diff --git a/src/mongo/dbtests/query_stage_delete.cpp b/src/mongo/dbtests/query_stage_delete.cpp index 7bdd12bb81e..03b7834e079 100644 --- a/src/mongo/dbtests/query_stage_delete.cpp +++ b/src/mongo/dbtests/query_stage_delete.cpp @@ -172,7 +172,7 @@ public: BSONObj targetDoc = coll->docFor(&_opCtx, recordIds[targetDocIndex]).value(); ASSERT(!targetDoc.isEmpty()); remove(targetDoc); - static_cast<PlanStage*>(&deleteStage)->restoreState(); + static_cast<PlanStage*>(&deleteStage)->restoreState(&coll); // Remove the rest. while (!deleteStage.isEOF()) { diff --git a/src/mongo/dbtests/query_stage_ixscan.cpp b/src/mongo/dbtests/query_stage_ixscan.cpp index d74a212b865..4aa7462de72 100644 --- a/src/mongo/dbtests/query_stage_ixscan.cpp +++ b/src/mongo/dbtests/query_stage_ixscan.cpp @@ -59,6 +59,7 @@ public: _ctx.db()->dropCollection(&_opCtx, nss()).transitional_ignore(); _coll = _ctx.db()->createCollection(&_opCtx, nss()); + _collPtr = _coll; ASSERT_OK(_coll->getIndexCatalog()->createIndexOnEmptyCollection( &_opCtx, @@ -108,7 +109,7 @@ public: // This child stage gets owned and freed by the caller. MatchExpression* filter = nullptr; - return new IndexScan(_expCtx.get(), _coll, params, &_ws, filter); + return new IndexScan(_expCtx.get(), _collPtr, params, &_ws, filter); } IndexScan* createIndexScan(BSONObj startKey, @@ -149,6 +150,7 @@ protected: Lock::DBLock _dbLock; OldClientContext _ctx; Collection* _coll; + CollectionPtr _collPtr; WorkingSet _ws; @@ -201,7 +203,7 @@ public: static_cast<PlanStage*>(ixscan.get())->saveState(); insert(fromjson("{_id: 4, x: 10}")); insert(fromjson("{_id: 5, x: 11}")); - static_cast<PlanStage*>(ixscan.get())->restoreState(); + static_cast<PlanStage*>(ixscan.get())->restoreState(&_collPtr); member = getNext(ixscan.get()); ASSERT_EQ(WorkingSetMember::RID_AND_IDX, member->getState()); @@ -234,7 +236,7 @@ public: // Save state and insert an indexed doc. static_cast<PlanStage*>(ixscan.get())->saveState(); insert(fromjson("{_id: 4, x: 7}")); - static_cast<PlanStage*>(ixscan.get())->restoreState(); + static_cast<PlanStage*>(ixscan.get())->restoreState(&_collPtr); member = getNext(ixscan.get()); ASSERT_EQ(WorkingSetMember::RID_AND_IDX, member->getState()); @@ -267,7 +269,7 @@ public: // Save state and insert an indexed doc. static_cast<PlanStage*>(ixscan.get())->saveState(); insert(fromjson("{_id: 4, x: 10}")); - static_cast<PlanStage*>(ixscan.get())->restoreState(); + static_cast<PlanStage*>(ixscan.get())->restoreState(&_collPtr); // Ensure that we're EOF and we don't erroneously return {'': 12}. WorkingSetID id; @@ -301,7 +303,7 @@ public: static_cast<PlanStage*>(ixscan.get())->saveState(); insert(fromjson("{_id: 4, x: 6}")); insert(fromjson("{_id: 5, x: 9}")); - static_cast<PlanStage*>(ixscan.get())->restoreState(); + static_cast<PlanStage*>(ixscan.get())->restoreState(&_collPtr); // Ensure that we don't erroneously return {'': 9} or {'':3}. member = getNext(ixscan.get()); diff --git a/src/mongo/dbtests/query_stage_merge_sort.cpp b/src/mongo/dbtests/query_stage_merge_sort.cpp index 4b1c76f1ef6..1bb4df5d87e 100644 --- a/src/mongo/dbtests/query_stage_merge_sort.cpp +++ b/src/mongo/dbtests/query_stage_merge_sort.cpp @@ -190,7 +190,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -259,7 +259,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -328,7 +328,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -403,7 +403,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -474,7 +474,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -532,7 +532,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -615,7 +615,7 @@ public: // stage, and therefore should still be returned. ms->saveState(); remove(BSON(std::string(1u, 'a' + count) << 1)); - ms->restoreState(); + ms->restoreState(&coll); // Make sure recordIds[11] is returned as expected. We expect the corresponding working set // member to remain in RID_AND_IDX state. It should have been marked as "suspicious", since @@ -740,7 +740,7 @@ public: // Update doc {a: 5} such that the postimage will no longer match the query. ms->saveState(); update(BSON("a" << 5), BSON("$set" << BSON("a" << 15))); - ms->restoreState(); + ms->restoreState(&coll); // Invalidated doc {a: 5} should still get returned. We expect an RID_AND_OBJ working set // member with an owned BSONObj. @@ -825,7 +825,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -900,7 +900,7 @@ public: make_unique<FetchStage>(_expCtx.get(), ws.get(), std::move(idxScan), nullptr, coll)); auto statusWithPlanExecutor = plan_executor_factory::make( - _expCtx, std::move(ws), std::move(ms), coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); + _expCtx, std::move(ws), std::move(ms), &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp index 6765130f36c..2ac93c0e04d 100644 --- a/src/mongo/dbtests/query_stage_multiplan.cpp +++ b/src/mongo/dbtests/query_stage_multiplan.cpp @@ -260,7 +260,7 @@ TEST_F(QueryStageMultiPlanTest, MPSCollectionScanVsHighlySelectiveIXScan) { plan_executor_factory::make(std::move(cq), std::move(sharedWs), std::move(mps), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -500,7 +500,7 @@ TEST_F(QueryStageMultiPlanTest, MPSExplainAllPlans) { uassertStatusOK(plan_executor_factory::make(_expCtx, std::move(ws), std::move(mps), - ctx.getCollection(), + &ctx.getCollection(), PlanYieldPolicy::YieldPolicy::NO_YIELD)); auto execImpl = dynamic_cast<PlanExecutorImpl*>(exec.get()); @@ -553,7 +553,7 @@ TEST_F(QueryStageMultiPlanTest, MPSSummaryStats) { qr->setFilter(BSON("foo" << BSON("$gte" << 0))); auto cq = uassertStatusOK(CanonicalQuery::canonicalize(opCtx(), std::move(qr))); auto exec = uassertStatusOK( - getExecutor(opCtx(), coll, std::move(cq), PlanYieldPolicy::YieldPolicy::NO_YIELD, 0)); + getExecutor(opCtx(), &coll, std::move(cq), PlanYieldPolicy::YieldPolicy::NO_YIELD, 0)); auto execImpl = dynamic_cast<PlanExecutorImpl*>(exec.get()); ASSERT(execImpl); diff --git a/src/mongo/dbtests/query_stage_sort.cpp b/src/mongo/dbtests/query_stage_sort.cpp index 16640fb9e5e..c35511ab247 100644 --- a/src/mongo/dbtests/query_stage_sort.cpp +++ b/src/mongo/dbtests/query_stage_sort.cpp @@ -133,7 +133,7 @@ public: // The PlanExecutor will be automatically registered on construction due to the auto // yield policy, so it can receive invalidations when we remove documents later. auto statusWithPlanExecutor = plan_executor_factory::make( - _expCtx, std::move(ws), std::move(ss), coll, PlanYieldPolicy::YieldPolicy::YIELD_AUTO); + _expCtx, std::move(ws), std::move(ss), &coll, PlanYieldPolicy::YieldPolicy::YIELD_AUTO); invariant(statusWithPlanExecutor.isOK()); return std::move(statusWithPlanExecutor.getValue()); } @@ -179,7 +179,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); @@ -610,7 +610,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(fetchStage), - coll, + &coll, PlanYieldPolicy::YieldPolicy::NO_YIELD); auto exec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/dbtests/query_stage_subplan.cpp b/src/mongo/dbtests/query_stage_subplan.cpp index facd2746bbe..8609b3f8af7 100644 --- a/src/mongo/dbtests/query_stage_subplan.cpp +++ b/src/mongo/dbtests/query_stage_subplan.cpp @@ -538,8 +538,8 @@ TEST_F(QueryStageSubplanTest, ShouldReportErrorIfExceedsTimeLimitDuringPlanning) // Create the SubplanStage. WorkingSet workingSet; - SubplanStage subplanStage( - _expCtx.get(), ctx.getCollection(), &workingSet, params, canonicalQuery.get()); + auto coll = ctx.getCollection(); + SubplanStage subplanStage(_expCtx.get(), coll, &workingSet, params, canonicalQuery.get()); AlwaysTimeOutYieldPolicy alwaysTimeOutPolicy(serviceContext()->getFastClockSource()); ASSERT_EQ(ErrorCodes::ExceededTimeLimit, subplanStage.pickBestPlan(&alwaysTimeOutPolicy)); @@ -563,8 +563,8 @@ TEST_F(QueryStageSubplanTest, ShouldReportErrorIfKilledDuringPlanning) { // Create the SubplanStage. WorkingSet workingSet; - SubplanStage subplanStage( - _expCtx.get(), ctx.getCollection(), &workingSet, params, canonicalQuery.get()); + auto coll = ctx.getCollection(); + SubplanStage subplanStage(_expCtx.get(), coll, &workingSet, params, canonicalQuery.get()); AlwaysPlanKilledYieldPolicy alwaysPlanKilledYieldPolicy(serviceContext()->getFastClockSource()); ASSERT_EQ(ErrorCodes::QueryPlanKilled, subplanStage.pickBestPlan(&alwaysPlanKilledYieldPolicy)); @@ -611,11 +611,13 @@ TEST_F(QueryStageSubplanTest, ShouldThrowOnRestoreIfIndexDroppedBeforePlanSelect // Attempt to restore state. This should throw due the index drop. As a future improvement, we // may wish to make the subplan stage tolerate drops of indices it is not using. collLock.emplace(opCtx(), nss); - ASSERT_THROWS_CODE(subplanStage.restoreState(), DBException, ErrorCodes::QueryPlanKilled); + ASSERT_THROWS_CODE(subplanStage.restoreState(&collLock->getCollection()), + DBException, + ErrorCodes::QueryPlanKilled); } TEST_F(QueryStageSubplanTest, ShouldNotThrowOnRestoreIfIndexDroppedAfterPlanSelection) { - CollectionPtr collection = nullptr; + CollectionPtr collection; { dbtests::WriteContextForTests ctx{opCtx(), nss.ns()}; addIndex(BSON("p1" << 1 << "opt1" << 1)); @@ -658,7 +660,7 @@ TEST_F(QueryStageSubplanTest, ShouldNotThrowOnRestoreIfIndexDroppedAfterPlanSele // Restoring state should succeed, since the plan selected by pickBestPlan() does not use the // index {irrelevant: 1}. collLock.emplace(opCtx(), nss); - subplanStage.restoreState(); + subplanStage.restoreState(&collLock->getCollection()); } } // namespace diff --git a/src/mongo/dbtests/query_stage_tests.cpp b/src/mongo/dbtests/query_stage_tests.cpp index 50948a6cf32..4690bc67c57 100644 --- a/src/mongo/dbtests/query_stage_tests.cpp +++ b/src/mongo/dbtests/query_stage_tests.cpp @@ -96,7 +96,7 @@ public: plan_executor_factory::make(_expCtx, std::move(ws), std::move(ix), - ctx.getCollection(), + &ctx.getCollection(), PlanYieldPolicy::YieldPolicy::NO_YIELD); ASSERT_OK(statusWithPlanExecutor.getStatus()); auto exec = std::move(statusWithPlanExecutor.getValue()); diff --git a/src/mongo/dbtests/query_stage_update.cpp b/src/mongo/dbtests/query_stage_update.cpp index 084012ca61c..93fb705f8ea 100644 --- a/src/mongo/dbtests/query_stage_update.cpp +++ b/src/mongo/dbtests/query_stage_update.cpp @@ -275,7 +275,7 @@ public: CurOp& curOp = *CurOp::get(_opCtx); OpDebug* opDebug = &curOp.debug(); UpdateDriver driver(_expCtx); - const CollectionPtr& coll = + CollectionPtr coll = CollectionCatalog::get(&_opCtx).lookupCollectionByNamespace(&_opCtx, nss); ASSERT(coll); @@ -335,7 +335,7 @@ public: BSONObj targetDoc = coll->docFor(&_opCtx, recordIds[targetDocIndex]).value(); ASSERT(!targetDoc.isEmpty()); remove(targetDoc); - static_cast<PlanStage*>(updateStage.get())->restoreState(); + static_cast<PlanStage*>(updateStage.get())->restoreState(&coll); // Do the remaining updates. while (!updateStage->isEOF()) { |