diff options
-rw-r--r-- | src/mongo/db/catalog/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/catalog/database_test.cpp | 23 | ||||
-rw-r--r-- | src/mongo/db/commands/find_cmd.cpp | 17 | ||||
-rw-r--r-- | src/mongo/db/commands/list_indexes.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/commands/parallel_collection_scan.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.cpp | 22 | ||||
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.h | 21 | ||||
-rw-r--r-- | src/mongo/db/db_raii.cpp | 42 | ||||
-rw-r--r-- | src/mongo/db/db_raii.h | 24 | ||||
-rw-r--r-- | src/mongo/db/query/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/query/canonical_query.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/query/query_request.cpp | 32 | ||||
-rw-r--r-- | src/mongo/db/query/query_request.h | 23 | ||||
-rw-r--r-- | src/mongo/s/balancer_configuration_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_test.cpp | 24 | ||||
-rw-r--r-- | src/mongo/s/cluster_identity_loader_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/sharding_test_fixture.cpp | 2 |
17 files changed, 201 insertions, 43 deletions
diff --git a/src/mongo/db/catalog/SConscript b/src/mongo/db/catalog/SConscript index 5f1f5b2704e..9479faf9f4c 100644 --- a/src/mongo/db/catalog/SConscript +++ b/src/mongo/db/catalog/SConscript @@ -125,6 +125,7 @@ env.CppUnitTest( LIBDEPS=[ 'database', 'index_create', + '$BUILD_DIR/mongo/db/concurrency/lock_manager', '$BUILD_DIR/mongo/db/db_raii', '$BUILD_DIR/mongo/db/namespace_string', '$BUILD_DIR/mongo/db/op_observer_d', diff --git a/src/mongo/db/catalog/database_test.cpp b/src/mongo/db/catalog/database_test.cpp index 4ba521f6b65..35c1127bb64 100644 --- a/src/mongo/db/catalog/database_test.cpp +++ b/src/mongo/db/catalog/database_test.cpp @@ -35,6 +35,7 @@ #include "mongo/db/catalog/index_create.h" #include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" +#include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/db_raii.h" #include "mongo/db/jsobj.h" @@ -537,4 +538,26 @@ TEST_F( db->makeUniqueCollectionNamespace(_opCtx.get(), model)); }); } + +TEST_F(DatabaseTest, DBLockCanBePassedToAutoGetDb) { + NamespaceString nss("test", "coll"); + Lock::DBLock lock(_opCtx.get(), nss.db(), MODE_X); + { + AutoGetDb db(_opCtx.get(), nss.db(), std::move(lock)); + ASSERT(_opCtx.get()->lockState()->isDbLockedForMode(nss.db(), MODE_X)); + } + // The moved lock should go out of scope here, so the database should no longer be locked. + ASSERT_FALSE(_opCtx.get()->lockState()->isDbLockedForMode(nss.db(), MODE_X)); +} + +TEST_F(DatabaseTest, DBLockCanBePassedToAutoGetCollectionOrViewForReadCommand) { + NamespaceString nss("test", "coll"); + Lock::DBLock lock(_opCtx.get(), nss.db(), MODE_X); + { + AutoGetCollectionOrViewForReadCommand coll(_opCtx.get(), nss, std::move(lock)); + ASSERT(_opCtx.get()->lockState()->isDbLockedForMode(nss.db(), MODE_X)); + } + // The moved lock should go out of scope here, so the database should no longer be locked. + ASSERT_FALSE(_opCtx.get()->lockState()->isDbLockedForMode(nss.db(), MODE_X)); +} } // namespace diff --git a/src/mongo/db/commands/find_cmd.cpp b/src/mongo/db/commands/find_cmd.cpp index fe1d0940ff9..cbe0ce20d55 100644 --- a/src/mongo/db/commands/find_cmd.cpp +++ b/src/mongo/db/commands/find_cmd.cpp @@ -40,6 +40,7 @@ #include "mongo/db/clientcursor.h" #include "mongo/db/commands.h" #include "mongo/db/commands/run_aggregate.h" +#include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/db_raii.h" #include "mongo/db/exec/working_set_common.h" #include "mongo/db/matcher/extensions_callback_real.h" @@ -228,14 +229,14 @@ public: const std::string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) override { - const NamespaceString nss(parseNsOrUUID(opCtx, dbname, cmdObj)); - // Although it is a command, a find command gets counted as a query. globalOpCounters.gotQuery(); // Parse the command BSON to a QueryRequest. const bool isExplain = false; - auto qrStatus = QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain); + // Pass parseNs to makeFromFindCommand in case cmdObj does not have a UUID. + auto qrStatus = QueryRequest::makeFromFindCommand( + NamespaceString(parseNs(dbname, cmdObj)), cmdObj, isExplain); if (!qrStatus.isOK()) { return appendCommandStatus(result, qrStatus.getStatus()); } @@ -252,6 +253,12 @@ public: } } + // Acquire locks. If the query is on a view, we release our locks and convert the query + // request into an aggregation command. + Lock::DBLock dbSLock(opCtx, dbname, MODE_IS); + const NamespaceString nss(parseNsOrUUID(opCtx, dbname, cmdObj)); + qr->refreshNSS(opCtx); + // Fill out curop information. // // We pass negative values for 'ntoreturn' and 'ntoskip' to indicate that these values @@ -276,9 +283,7 @@ public: } std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); - // Acquire locks. If the query is on a view, we release our locks and convert the query - // request into an aggregation command. - AutoGetCollectionOrViewForReadCommand ctx(opCtx, nss); + AutoGetCollectionOrViewForReadCommand ctx(opCtx, nss, std::move(dbSLock)); Collection* collection = ctx.getCollection(); if (ctx.getView()) { // Relinquish locks. The aggregation command will re-acquire them. diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp index a050e9adfff..74b75cfeffa 100644 --- a/src/mongo/db/commands/list_indexes.cpp +++ b/src/mongo/db/commands/list_indexes.cpp @@ -120,6 +120,7 @@ public: const string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) { + Lock::DBLock dbSLock(opCtx, dbname, MODE_IS); const NamespaceString ns(parseNsOrUUID(opCtx, dbname, cmdObj)); const long long defaultBatchSize = std::numeric_limits<long long>::max(); long long batchSize; @@ -129,7 +130,7 @@ public: return appendCommandStatus(result, parseCursorStatus); } - AutoGetCollectionForReadCommand autoColl(opCtx, ns); + AutoGetCollectionForReadCommand autoColl(opCtx, ns, std::move(dbSLock)); if (!autoColl.getDb()) { return appendCommandStatus( result, diff --git a/src/mongo/db/commands/parallel_collection_scan.cpp b/src/mongo/db/commands/parallel_collection_scan.cpp index 5fbe37b1132..6b84996369c 100644 --- a/src/mongo/db/commands/parallel_collection_scan.cpp +++ b/src/mongo/db/commands/parallel_collection_scan.cpp @@ -89,9 +89,10 @@ public: const string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) { + Lock::DBLock dbSLock(opCtx, dbname, MODE_IS); const NamespaceString ns(parseNsOrUUID(opCtx, dbname, cmdObj)); - AutoGetCollectionForReadCommand ctx(opCtx, ns); + AutoGetCollectionForReadCommand ctx(opCtx, ns, std::move(dbSLock)); Collection* collection = ctx.getCollection(); if (!collection) diff --git a/src/mongo/db/concurrency/d_concurrency.cpp b/src/mongo/db/concurrency/d_concurrency.cpp index 42e7bb96d7f..d5d9fe1684c 100644 --- a/src/mongo/db/concurrency/d_concurrency.cpp +++ b/src/mongo/db/concurrency/d_concurrency.cpp @@ -152,6 +152,15 @@ Lock::GlobalLock::GlobalLock(OperationContext* opCtx, _enqueue(lockMode, timeoutMs); } +Lock::GlobalLock::GlobalLock(GlobalLock&& otherLock) + : _opCtx(otherLock._opCtx), + _result(otherLock._result), + _pbwm(std::move(otherLock._pbwm)), + _isOutermostLock(otherLock._isOutermostLock) { + // Mark as moved so the destructor doesn't invalidate the newly-constructed lock. + otherLock._result = LOCK_INVALID; +} + void Lock::GlobalLock::_enqueue(LockMode lockMode, unsigned timeoutMs) { if (_opCtx->lockState()->shouldConflictWithSecondaryBatchApplication()) { _pbwm.lock(MODE_IS); @@ -200,8 +209,19 @@ Lock::DBLock::DBLock(OperationContext* opCtx, StringData db, LockMode mode) invariant(LOCK_OK == _opCtx->lockState()->lock(_id, _mode)); } +Lock::DBLock::DBLock(DBLock&& otherLock) + : _id(otherLock._id), + _opCtx(otherLock._opCtx), + _mode(otherLock._mode), + _globalLock(std::move(otherLock._globalLock)) { + // Mark as moved so the destructor doesn't invalidate the newly-constructed lock. + otherLock._mode = MODE_NONE; +} + Lock::DBLock::~DBLock() { - _opCtx->lockState()->unlock(_id); + if (_mode != MODE_NONE) { + _opCtx->lockState()->unlock(_id); + } } void Lock::DBLock::relockWithMode(LockMode newMode) { diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h index 479dc84fb2a..44be439d539 100644 --- a/src/mongo/db/concurrency/d_concurrency.h +++ b/src/mongo/db/concurrency/d_concurrency.h @@ -83,8 +83,17 @@ public: lock(mode); } + ResourceLock(ResourceLock&& otherLock) + : _rid(otherLock._rid), _locker(otherLock._locker), _result(otherLock._result) { + // Mark as moved so the destructor doesn't invalidate the newly- + // constructed lock. + otherLock._result = LOCK_INVALID; + } + ~ResourceLock() { - unlock(); + if (isLocked()) { + unlock(); + } } void lock(LockMode mode); @@ -174,6 +183,7 @@ public: class EnqueueOnly {}; GlobalLock(OperationContext* opCtx, LockMode lockMode, unsigned timeoutMs); + GlobalLock(GlobalLock&&); /** * Enqueues lock but does not block on lock acquisition. @@ -188,10 +198,12 @@ public: EnqueueOnly enqueueOnly); ~GlobalLock() { - if (isLocked() && _isOutermostLock) { - _opCtx->recoveryUnit()->abandonSnapshot(); + if (_result != LOCK_INVALID) { + if (isLocked() && _isOutermostLock) { + _opCtx->recoveryUnit()->abandonSnapshot(); + } + _unlock(); } - _unlock(); } /** @@ -268,6 +280,7 @@ public: class DBLock { public: DBLock(OperationContext* opCtx, StringData db, LockMode mode); + DBLock(DBLock&&); ~DBLock(); /** diff --git a/src/mongo/db/db_raii.cpp b/src/mongo/db/db_raii.cpp index bff855fcc5b..018a2591ed3 100644 --- a/src/mongo/db/db_raii.cpp +++ b/src/mongo/db/db_raii.cpp @@ -49,13 +49,23 @@ MONGO_FP_DECLARE(setAutoGetCollectionWait); AutoGetDb::AutoGetDb(OperationContext* opCtx, StringData ns, LockMode mode) : _dbLock(opCtx, ns, mode), _db(dbHolder().get(opCtx, ns)) {} +AutoGetDb::AutoGetDb(OperationContext* opCtx, StringData ns, Lock::DBLock lock) + : _dbLock(std::move(lock)), _db(dbHolder().get(opCtx, ns)) {} + AutoGetCollection::AutoGetCollection(OperationContext* opCtx, const NamespaceString& nss, LockMode modeDB, LockMode modeColl, ViewMode viewMode) + : AutoGetCollection(opCtx, nss, modeColl, viewMode, Lock::DBLock(opCtx, nss.db(), modeDB)) {} + +AutoGetCollection::AutoGetCollection(OperationContext* opCtx, + const NamespaceString& nss, + LockMode modeColl, + ViewMode viewMode, + Lock::DBLock lock) : _viewMode(viewMode), - _autoDb(opCtx, nss.db(), modeDB), + _autoDb(opCtx, nss.db(), std::move(lock)), _collLock(opCtx->lockState(), nss.ns(), modeColl), _coll(_autoDb.getDb() ? _autoDb.getDb()->getCollection(opCtx, nss) : nullptr) { Database* db = _autoDb.getDb(); @@ -132,6 +142,15 @@ AutoGetCollectionForRead::AutoGetCollectionForRead(OperationContext* opCtx, _ensureMajorityCommittedSnapshotIsValid(nss, opCtx); } +AutoGetCollectionForRead::AutoGetCollectionForRead(OperationContext* opCtx, + const NamespaceString& nss, + AutoGetCollection::ViewMode viewMode, + Lock::DBLock lock) { + _autoColl.emplace(opCtx, nss, MODE_IS, viewMode, std::move(lock)); + + // Note: this can yield. + _ensureMajorityCommittedSnapshotIsValid(nss, opCtx); +} void AutoGetCollectionForRead::_ensureMajorityCommittedSnapshotIsValid(const NamespaceString& nss, OperationContext* opCtx) { while (true) { @@ -169,9 +188,11 @@ void AutoGetCollectionForRead::_ensureMajorityCommittedSnapshotIsValid(const Nam } AutoGetCollectionForReadCommand::AutoGetCollectionForReadCommand( - OperationContext* opCtx, const NamespaceString& nss, AutoGetCollection::ViewMode viewMode) { - - _autoCollForRead.emplace(opCtx, nss, viewMode); + OperationContext* opCtx, + const NamespaceString& nss, + AutoGetCollection::ViewMode viewMode, + Lock::DBLock lock) { + _autoCollForRead.emplace(opCtx, nss, viewMode, std::move(lock)); const int doNotChangeProfilingLevel = 0; _statsTracker.emplace(opCtx, nss, @@ -185,6 +206,11 @@ AutoGetCollectionForReadCommand::AutoGetCollectionForReadCommand( css->checkShardVersionOrThrow(opCtx); } +AutoGetCollectionForReadCommand::AutoGetCollectionForReadCommand( + OperationContext* opCtx, const NamespaceString& nss, AutoGetCollection::ViewMode viewMode) + : AutoGetCollectionForReadCommand( + opCtx, nss, viewMode, Lock::DBLock(opCtx, nss.db(), MODE_IS)) {} + AutoGetCollectionOrViewForReadCommand::AutoGetCollectionOrViewForReadCommand( OperationContext* opCtx, const NamespaceString& nss) : AutoGetCollectionForReadCommand(opCtx, nss, AutoGetCollection::ViewMode::kViewsPermitted), @@ -192,6 +218,14 @@ AutoGetCollectionOrViewForReadCommand::AutoGetCollectionOrViewForReadCommand( ? _autoCollForRead->getDb()->getViewCatalog()->lookup(opCtx, nss.ns()) : nullptr) {} +AutoGetCollectionOrViewForReadCommand::AutoGetCollectionOrViewForReadCommand( + OperationContext* opCtx, const NamespaceString& nss, Lock::DBLock lock) + : AutoGetCollectionForReadCommand( + opCtx, nss, AutoGetCollection::ViewMode::kViewsPermitted, std::move(lock)), + _view(_autoCollForRead->getDb() && !getCollection() + ? _autoCollForRead->getDb()->getViewCatalog()->lookup(opCtx, nss.ns()) + : nullptr) {} + void AutoGetCollectionOrViewForReadCommand::releaseLocksForView() noexcept { invariant(_view); _view = nullptr; diff --git a/src/mongo/db/db_raii.h b/src/mongo/db/db_raii.h index 641b64e7988..7ff6b8f1a1d 100644 --- a/src/mongo/db/db_raii.h +++ b/src/mongo/db/db_raii.h @@ -58,6 +58,7 @@ class AutoGetDb { public: AutoGetDb(OperationContext* opCtx, StringData ns, LockMode mode); + AutoGetDb(OperationContext* opCtx, StringData ns, Lock::DBLock lock); Database* getDb() const { return _db; @@ -94,6 +95,11 @@ public: LockMode modeColl) : AutoGetCollection(opCtx, nss, modeDB, modeColl, ViewMode::kViewsForbidden) {} + AutoGetCollection(OperationContext* opCtx, + const NamespaceString& nss, + LockMode modeColl, + ViewMode viewMode, + Lock::DBLock lock); /** * This constructor is intended for internal use and should not be used outside this file. * AutoGetCollectionForReadCommand and AutoGetCollectionOrViewForReadCommand use 'viewMode' to @@ -272,6 +278,10 @@ public: const NamespaceString& nss, AutoGetCollection::ViewMode viewMode); + AutoGetCollectionForRead(OperationContext* opCtx, + const NamespaceString& nss, + AutoGetCollection::ViewMode viewMode, + Lock::DBLock lock); Database* getDb() const { return _autoColl->getDb(); } @@ -309,6 +319,12 @@ public: : AutoGetCollectionForReadCommand( opCtx, nss, AutoGetCollection::ViewMode::kViewsForbidden) {} + AutoGetCollectionForReadCommand(OperationContext* opCtx, + const NamespaceString& nss, + Lock::DBLock lock) + : AutoGetCollectionForReadCommand( + opCtx, nss, AutoGetCollection::ViewMode::kViewsForbidden, std::move(lock)) {} + Database* getDb() const { return _autoCollForRead->getDb(); } @@ -322,6 +338,11 @@ protected: const NamespaceString& nss, AutoGetCollection::ViewMode viewMode); + AutoGetCollectionForReadCommand(OperationContext* opCtx, + const NamespaceString& nss, + AutoGetCollection::ViewMode viewMode, + Lock::DBLock lock); + // '_autoCollForRead' may need to be reset by AutoGetCollectionOrViewForReadCommand, so needs to // be a boost::optional. boost::optional<AutoGetCollectionForRead> _autoCollForRead; @@ -343,6 +364,9 @@ class AutoGetCollectionOrViewForReadCommand final : public AutoGetCollectionForR public: AutoGetCollectionOrViewForReadCommand(OperationContext* opCtx, const NamespaceString& nss); + AutoGetCollectionOrViewForReadCommand(OperationContext* opCtx, + const NamespaceString& nss, + Lock::DBLock lock); ViewDefinition* getView() const { return _view.get(); diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript index 367b285f454..c57bd8f3016 100644 --- a/src/mongo/db/query/SConscript +++ b/src/mongo/db/query/SConscript @@ -246,6 +246,7 @@ env.Library( LIBDEPS=[ "$BUILD_DIR/mongo/base", "$BUILD_DIR/mongo/db/repl/read_concern_args", + "$BUILD_DIR/mongo/db/catalog/uuid_catalog" ], ) diff --git a/src/mongo/db/query/canonical_query.cpp b/src/mongo/db/query/canonical_query.cpp index 17d18c6b798..1df80364b65 100644 --- a/src/mongo/db/query/canonical_query.cpp +++ b/src/mongo/db/query/canonical_query.cpp @@ -536,7 +536,7 @@ Status CanonicalQuery::isValid(MatchExpression* root, const QueryRequest& parsed std::string CanonicalQuery::toString() const { str::stream ss; - ss << "ns=" << _qr->ns(); + ss << "ns=" << _qr->nss().ns(); if (_qr->getBatchSize()) { ss << " batchSize=" << *_qr->getBatchSize(); diff --git a/src/mongo/db/query/query_request.cpp b/src/mongo/db/query/query_request.cpp index 6e4d0745b2a..00a8915c1c4 100644 --- a/src/mongo/db/query/query_request.cpp +++ b/src/mongo/db/query/query_request.cpp @@ -34,6 +34,7 @@ #include "mongo/base/status_with.h" #include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/client/dbclientinterface.h" +#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/commands.h" #include "mongo/db/dbmessage.h" #include "mongo/db/namespace_string.h" @@ -110,12 +111,21 @@ const char QueryRequest::kFindCommandName[] = "find"; const char QueryRequest::kShardVersionField[] = "shardVersion"; QueryRequest::QueryRequest(NamespaceString nss) : _nss(std::move(nss)) {} +QueryRequest::QueryRequest(CollectionUUID uuid) : _uuid(std::move(uuid)) {} + +void QueryRequest::refreshNSS(OperationContext* opCtx) { + UUIDCatalog& catalog = UUIDCatalog::get(opCtx); + if (_uuid) { + invariant(catalog.lookupCollectionByUUID(_uuid.get())); + _nss = catalog.lookupNSSByUUID(_uuid.get()); + } + invariant(!_nss.isEmpty()); +} // static -StatusWith<unique_ptr<QueryRequest>> QueryRequest::makeFromFindCommand(NamespaceString nss, - const BSONObj& cmdObj, - bool isExplain) { - auto qr = stdx::make_unique<QueryRequest>(nss); +StatusWith<unique_ptr<QueryRequest>> QueryRequest::parseFromFindCommand(unique_ptr<QueryRequest> qr, + const BSONObj& cmdObj, + bool isExplain) { qr->_explain = isExplain; // Parse the command BSON by looping through one element at a time. @@ -385,6 +395,20 @@ StatusWith<unique_ptr<QueryRequest>> QueryRequest::makeFromFindCommand(Namespace return std::move(qr); } +StatusWith<unique_ptr<QueryRequest>> QueryRequest::makeFromFindCommand(NamespaceString nss, + const BSONObj& cmdObj, + bool isExplain) { + BSONElement first = cmdObj.firstElement(); + if (first.type() == BinData && first.binDataType() == BinDataType::newUUID) { + auto uuid = uassertStatusOK(UUID::parse(first)); + auto qr = stdx::make_unique<QueryRequest>(uuid); + return parseFromFindCommand(std::move(qr), cmdObj, isExplain); + } else { + auto qr = stdx::make_unique<QueryRequest>(nss); + return parseFromFindCommand(std::move(qr), cmdObj, isExplain); + } +} + BSONObj QueryRequest::asFindCommand() const { BSONObjBuilder bob; asFindCommand(&bob); diff --git a/src/mongo/db/query/query_request.h b/src/mongo/db/query/query_request.h index 620e50d8804..fa0f269b4b5 100644 --- a/src/mongo/db/query/query_request.h +++ b/src/mongo/db/query/query_request.h @@ -31,8 +31,10 @@ #include <boost/optional.hpp> #include <string> +#include "mongo/db/catalog/collection_options.h" #include "mongo/db/jsobj.h" #include "mongo/db/namespace_string.h" +#include "mongo/db/operation_context.h" namespace mongo { @@ -52,6 +54,8 @@ public: QueryRequest(NamespaceString nss); + QueryRequest(CollectionUUID uuid); + /** * Returns a non-OK status if any property of the QR has a bad value (e.g. a negative skip * value) or if there is a bad combination of options (e.g. awaitData is illegal without @@ -61,7 +65,8 @@ public: /** * Parses a find command object, 'cmdObj'. Caller must indicate whether or not this lite - * parsed query is an explained query or not via 'isExplain'. + * parsed query is an explained query or not via 'isExplain'. Accepts a NSS with which + * to initialize the QueryRequest if there is no UUID in cmdObj. * * Returns a heap allocated QueryRequest on success or an error if 'cmdObj' is not well * formed. @@ -71,6 +76,12 @@ public: bool isExplain); /** + * If _uuid exists for this QueryRequest, use it to update the value of _nss via the + * UUIDCatalog associated with opCtx. + */ + void refreshNSS(OperationContext* opCtx); + + /** * Converts this QR into a find command. */ BSONObj asFindCommand() const; @@ -131,13 +142,10 @@ public: static const std::string metaTextScore; const NamespaceString& nss() const { + invariant(!_nss.isEmpty()); return _nss; } - const std::string& ns() const { - return _nss.ns(); - } - const BSONObj& getFilter() const { return _filter; } @@ -412,6 +420,8 @@ public: int queryOptions); private: + static StatusWith<std::unique_ptr<QueryRequest>> parseFromFindCommand( + std::unique_ptr<QueryRequest> qr, const BSONObj& cmdObj, bool isExplain); Status init(int ntoskip, int ntoreturn, int queryOptions, @@ -443,7 +453,8 @@ private: */ void addMetaProjection(); - const NamespaceString _nss; + NamespaceString _nss; + OptionalCollectionUUID _uuid; BSONObj _filter; BSONObj _proj; diff --git a/src/mongo/s/balancer_configuration_test.cpp b/src/mongo/s/balancer_configuration_test.cpp index 834d3d12157..da21e716f18 100644 --- a/src/mongo/s/balancer_configuration_test.cpp +++ b/src/mongo/s/balancer_configuration_test.cpp @@ -74,7 +74,7 @@ protected: auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), "config.settings"); + ASSERT_EQ(query->nss().ns(), "config.settings"); ASSERT_BSONOBJ_EQ(query->getFilter(), BSON("_id" << key)); checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm); diff --git a/src/mongo/s/catalog/sharding_catalog_test.cpp b/src/mongo/s/catalog/sharding_catalog_test.cpp index 425e08473b2..de9aee82029 100644 --- a/src/mongo/s/catalog/sharding_catalog_test.cpp +++ b/src/mongo/s/catalog/sharding_catalog_test.cpp @@ -110,7 +110,7 @@ TEST_F(ShardingCatalogClientTest, GetCollectionExisting) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); // Ensure the query is correct - ASSERT_EQ(query->ns(), CollectionType::ConfigNS); + ASSERT_EQ(query->nss().ns(), CollectionType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), BSON(CollectionType::fullNs(expectedColl.getNs().ns()))); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); @@ -174,7 +174,7 @@ TEST_F(ShardingCatalogClientTest, GetDatabaseExisting) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), DatabaseType::ConfigNS); + ASSERT_EQ(query->nss().ns(), DatabaseType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), BSON(DatabaseType::name(expectedDb.getName()))); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); ASSERT(!query->getLimit()); @@ -294,7 +294,7 @@ TEST_F(ShardingCatalogClientTest, GetAllShardsValid) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), ShardType::ConfigNS); + ASSERT_EQ(query->nss().ns(), ShardType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), BSONObj()); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); ASSERT_FALSE(query->getLimit().is_initialized()); @@ -392,7 +392,7 @@ TEST_F(ShardingCatalogClientTest, GetChunksForNSWithSortAndLimit) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), ChunkType::ConfigNS); + ASSERT_EQ(query->nss().ns(), ChunkType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), chunksQuery); ASSERT_BSONOBJ_EQ(query->getSort(), BSON(ChunkType::lastmod() << -1)); ASSERT_EQ(query->getLimit().get(), 1); @@ -446,7 +446,7 @@ TEST_F(ShardingCatalogClientTest, GetChunksForNSNoSortNoLimit) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), ChunkType::ConfigNS); + ASSERT_EQ(query->nss().ns(), ChunkType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), chunksQuery); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); ASSERT_FALSE(query->getLimit().is_initialized()); @@ -808,7 +808,7 @@ TEST_F(ShardingCatalogClientTest, GetCollectionsValidResultsNoDb) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), CollectionType::ConfigNS); + ASSERT_EQ(query->nss().ns(), CollectionType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), BSONObj()); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); @@ -866,7 +866,7 @@ TEST_F(ShardingCatalogClientTest, GetCollectionsValidResultsWithDb) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), CollectionType::ConfigNS); + ASSERT_EQ(query->nss().ns(), CollectionType::ConfigNS); { BSONObjBuilder b; b.appendRegex(CollectionType::fullNs(), "^test\\."); @@ -915,7 +915,7 @@ TEST_F(ShardingCatalogClientTest, GetCollectionsInvalidCollectionType) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), CollectionType::ConfigNS); + ASSERT_EQ(query->nss().ns(), CollectionType::ConfigNS); { BSONObjBuilder b; b.appendRegex(CollectionType::fullNs(), "^test\\."); @@ -962,7 +962,7 @@ TEST_F(ShardingCatalogClientTest, GetDatabasesForShardValid) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), DatabaseType::ConfigNS); + ASSERT_EQ(query->nss().ns(), DatabaseType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), BSON(DatabaseType::primary(dbt1.getPrimary().toString()))); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); @@ -1038,7 +1038,7 @@ TEST_F(ShardingCatalogClientTest, GetTagsForCollection) { auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), TagsType::ConfigNS); + ASSERT_EQ(query->nss().ns(), TagsType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), BSON(TagsType::ns("TestDB.TestColl"))); ASSERT_BSONOBJ_EQ(query->getSort(), BSON(TagsType::min() << 1)); @@ -1664,7 +1664,7 @@ TEST_F(ShardingCatalogClientTest, GetNewKeys) { fromjson("{purpose: 'none'," "expiresAt: {$gt: {$timestamp: {t: 1234, i: 5678}}}}")); - ASSERT_EQ(KeysCollectionDocument::ConfigNS, query->ns()); + ASSERT_EQ(KeysCollectionDocument::ConfigNS, query->nss().ns()); ASSERT_BSONOBJ_EQ(expectedQuery, query->getFilter()); ASSERT_BSONOBJ_EQ(BSON("expiresAt" << 1), query->getSort()); ASSERT_FALSE(query->getLimit().is_initialized()); @@ -1717,7 +1717,7 @@ TEST_F(ShardingCatalogClientTest, GetNewKeysWithEmptyCollection) { fromjson("{purpose: 'none'," "expiresAt: {$gt: {$timestamp: {t: 1234, i: 5678}}}}")); - ASSERT_EQ(KeysCollectionDocument::ConfigNS, query->ns()); + ASSERT_EQ(KeysCollectionDocument::ConfigNS, query->nss().ns()); ASSERT_BSONOBJ_EQ(expectedQuery, query->getFilter()); ASSERT_BSONOBJ_EQ(BSON("expiresAt" << 1), query->getSort()); ASSERT_FALSE(query->getLimit().is_initialized()); diff --git a/src/mongo/s/cluster_identity_loader_test.cpp b/src/mongo/s/cluster_identity_loader_test.cpp index 24b77c5d8eb..213fec88d7e 100644 --- a/src/mongo/s/cluster_identity_loader_test.cpp +++ b/src/mongo/s/cluster_identity_loader_test.cpp @@ -83,7 +83,7 @@ public: auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->ns(), "config.version"); + ASSERT_EQ(query->nss().ns(), "config.version"); ASSERT_BSONOBJ_EQ(query->getFilter(), BSONObj()); ASSERT_FALSE(query->getLimit().is_initialized()); diff --git a/src/mongo/s/sharding_test_fixture.cpp b/src/mongo/s/sharding_test_fixture.cpp index aad4203cde3..9f4583f485a 100644 --- a/src/mongo/s/sharding_test_fixture.cpp +++ b/src/mongo/s/sharding_test_fixture.cpp @@ -308,7 +308,7 @@ void ShardingTestFixture::expectGetShards(const std::vector<ShardType>& shards) ASSERT_OK(queryResult.getStatus()); const auto& query = queryResult.getValue(); - ASSERT_EQ(query->ns(), ShardType::ConfigNS); + ASSERT_EQ(query->nss().ns(), ShardType::ConfigNS); ASSERT_BSONOBJ_EQ(query->getFilter(), BSONObj()); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); |