diff options
author | Gregory Noma <gregory.noma@gmail.com> | 2022-06-22 17:33:39 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-07-25 18:14:44 +0000 |
commit | 2765c93e1aa265b19055d6b64e611ec945be3507 (patch) | |
tree | fc835b0ba33509bca0c05f9aaf6caa36e275c69a | |
parent | 1a252eefbe9d27ecb1dce15ac249bb9930229d6a (diff) | |
download | mongo-2765c93e1aa265b19055d6b64e611ec945be3507.tar.gz |
SERVER-67227 Avoid implicit collection creation for `collectionUUID` with insert/update commands
(cherry picked from commit 41994ed8c080afb448b20c631a66bf782a9834c0)
-rw-r--r-- | jstests/aggregation/collection_uuid_coll_stats_index_stats.js | 3 | ||||
-rw-r--r-- | jstests/core/collection_uuid_coll_mod.js | 3 | ||||
-rw-r--r-- | jstests/core/collection_uuid_drop.js | 3 | ||||
-rw-r--r-- | jstests/core/collection_uuid_find.js | 4 | ||||
-rw-r--r-- | jstests/core/collection_uuid_index_commands.js | 3 | ||||
-rw-r--r-- | jstests/core/collection_uuid_rename_collection.js | 3 | ||||
-rw-r--r-- | jstests/core/collection_uuid_write_commands.js | 6 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 19 |
8 files changed, 25 insertions, 19 deletions
diff --git a/jstests/aggregation/collection_uuid_coll_stats_index_stats.js b/jstests/aggregation/collection_uuid_coll_stats_index_stats.js index 5aa92524652..b0779a310f4 100644 --- a/jstests/aggregation/collection_uuid_coll_stats_index_stats.js +++ b/jstests/aggregation/collection_uuid_coll_stats_index_stats.js @@ -49,10 +49,11 @@ const testCommand = function(cmd, cmdObj) { jsTestLog("The command '" + cmd + "' fails when the provided UUID corresponds to a different collection, even if the " + "provided namespace does not exist."); - coll2.drop(); + assert.commandWorked(testDB.runCommand({drop: coll2.getName()})); res = assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch); validateErrorResponse(res, testDB.getName(), uuid, coll2.getName(), coll.getName()); + assert(!testDB.getCollectionNames().includes(coll2.getName())); jsTestLog("The command '" + cmd + "' succeeds on view when no UUID is provided."); const viewName = "view"; diff --git a/jstests/core/collection_uuid_coll_mod.js b/jstests/core/collection_uuid_coll_mod.js index 52da75bb345..2e984d81713 100644 --- a/jstests/core/collection_uuid_coll_mod.js +++ b/jstests/core/collection_uuid_coll_mod.js @@ -57,7 +57,7 @@ assert.eq(res.actualCollection, null); // 5. The command fails when the provided UUID corresponds to a different collection, even if the // provided namespace does not exist. -coll2.drop(); +assert.commandWorked(testDB.runCommand({drop: coll2.getName()})); res = assert.commandFailedWithCode( testDB.runCommand({collMod: coll2.getName(), collectionUUID: uuid}), ErrorCodes.CollectionUUIDMismatch); @@ -65,4 +65,5 @@ assert.eq(res.db, testDB.getName()); assert.eq(res.collectionUUID, uuid); assert.eq(res.expectedCollection, coll2.getName()); assert.eq(res.actualCollection, coll.getName()); +assert(!testDB.getCollectionNames().includes(coll2.getName())); })(); diff --git a/jstests/core/collection_uuid_drop.js b/jstests/core/collection_uuid_drop.js index 276f591afdf..747a4b114ed 100644 --- a/jstests/core/collection_uuid_drop.js +++ b/jstests/core/collection_uuid_drop.js @@ -58,13 +58,14 @@ assert.eq(res.actualCollection, null); // The command fails when the provided UUID corresponds to a different collection, even if the // provided namespace does not exist. -coll2.drop(); +assert.commandWorked(testDB.runCommand({drop: coll2.getName()})); res = assert.commandFailedWithCode(testDB.runCommand({drop: coll2.getName(), collectionUUID: uuid}), ErrorCodes.CollectionUUIDMismatch); assert.eq(res.db, testDB.getName()); assert.eq(res.collectionUUID, uuid); assert.eq(res.expectedCollection, coll2.getName()); assert.eq(res.actualCollection, coll.getName()); +assert(!testDB.getCollectionNames().includes(coll2.getName())); // The command fails when the provided UUID corresponds to a different collection, even if the // provided namespace is a view. diff --git a/jstests/core/collection_uuid_find.js b/jstests/core/collection_uuid_find.js index f3ce69f0e34..93d6d011266 100644 --- a/jstests/core/collection_uuid_find.js +++ b/jstests/core/collection_uuid_find.js @@ -56,13 +56,15 @@ assert.eq(res.actualCollection, null); // The command fails when the provided UUID corresponds to a different collection, even if the // provided namespace does not exist. -coll2.drop(); +assert.commandWorkedOrFailedWithCode(testDB.runCommand({drop: coll2.getName()}), + ErrorCodes.NamespaceNotFound); res = assert.commandFailedWithCode(testDB.runCommand({find: coll2.getName(), collectionUUID: uuid}), ErrorCodes.CollectionUUIDMismatch); assert.eq(res.db, testDB.getName()); assert.eq(res.collectionUUID, uuid); assert.eq(res.expectedCollection, coll2.getName()); assert.eq(res.actualCollection, coll.getName()); +assert(!testDB.getCollectionNames().includes(coll2.getName())); // The command fails when the provided UUID corresponds to a different collection, even if the // provided namespace is a view. diff --git a/jstests/core/collection_uuid_index_commands.js b/jstests/core/collection_uuid_index_commands.js index a323859144c..76ee83d8336 100644 --- a/jstests/core/collection_uuid_index_commands.js +++ b/jstests/core/collection_uuid_index_commands.js @@ -82,10 +82,11 @@ const testCommand = function(cmd, cmdObj) { jsTestLog("The command '" + cmd + "' fails when the provided UUID corresponds to a different collection, even if the " + "provided namespace does not exist."); - coll2.drop(); + assert.commandWorked(testDB.runCommand({drop: coll2.getName()})); res = assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch); validateErrorResponse(res, testDB.getName(), uuid, coll2.getName(), coll.getName()); + assert(!testDB.getCollectionNames().includes(coll2.getName())); jsTestLog("Only collections in the same database are specified by actualCollection."); const otherDB = testDB.getSiblingDB(testDB.getName() + '_2'); diff --git a/jstests/core/collection_uuid_rename_collection.js b/jstests/core/collection_uuid_rename_collection.js index 3dc99fe98ab..85e8507c9d2 100644 --- a/jstests/core/collection_uuid_rename_collection.js +++ b/jstests/core/collection_uuid_rename_collection.js @@ -162,7 +162,7 @@ assert.eq(res.actualCollection, null); // The command fails when the provided UUID corresponds to a different collection, even if the // provided source namespace does not exist. -coll2.drop(); +assert.commandWorked(testDB.runCommand({drop: coll2.getName()})); res = assert.commandFailedWithCode(testDB.adminCommand({ renameCollection: coll2.getFullName(), to: coll3.getFullName(), @@ -174,6 +174,7 @@ assert.eq(res.db, testDB.getName()); assert.eq(res.collectionUUID, uuid(coll)); assert.eq(res.expectedCollection, coll2.getName()); assert.eq(res.actualCollection, coll.getName()); +assert(!testDB.getCollectionNames().includes(coll2.getName())); // The collectionUUID parameter cannot be provided when renaming a collection between databases. const otherDBColl = db.getSiblingDB(jsTestName() + '_2').coll; diff --git a/jstests/core/collection_uuid_write_commands.js b/jstests/core/collection_uuid_write_commands.js index 03bd0b09ae7..0ab9794df6f 100644 --- a/jstests/core/collection_uuid_write_commands.js +++ b/jstests/core/collection_uuid_write_commands.js @@ -57,10 +57,12 @@ var testCommand = function(cmd, cmdObj) { jsTestLog("The command '" + cmd + "' fails when the provided UUID corresponds to a different collection, even if the " + "provided namespace does not exist."); - coll2.drop(); + assert.commandWorkedOrFailedWithCode(testDB.runCommand({drop: coll2.getName()}), + ErrorCodes.NamespaceNotFound); res = assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch); validateErrorResponse(res, testDB.getName(), uuid, coll2.getName(), coll.getName()); + assert(!testDB.getCollectionNames().includes(coll2.getName())); jsTestLog("Only collections in the same database are specified by actualCollection."); const otherDB = testDB.getSiblingDB(testDB.getName() + '_2'); @@ -75,5 +77,7 @@ var testCommand = function(cmd, cmdObj) { testCommand("insert", {insert: "", documents: [{inserted: true}]}); testCommand("update", {update: "", updates: [{q: {_id: 0}, u: {$set: {updated: true}}}]}); +testCommand("update", + {update: "", updates: [{q: {_id: 0}, u: {$set: {updated: true}}, upsert: true}]}); testCommand("delete", {delete: "", deletes: [{q: {_id: 0}, limit: 1}]}); })(); diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index f7fc2a84efd..3d013f8dbef 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -450,8 +450,13 @@ bool insertBatchAndHandleErrors(OperationContext* opCtx, opCtx, wholeOp.getNamespace(), fixLockModeForSystemDotViewsChanges(wholeOp.getNamespace(), MODE_IX)); - if (*collection) + checkCollectionUUIDMismatch(opCtx, + wholeOp.getNamespace(), + collection->getCollection(), + wholeOp.getCollectionUUID()); + if (*collection) { break; + } if (source == OperationSource::kTimeseriesInsert) { assertTimeseriesBucketsCollectionNotFound(wholeOp.getNamespace()); @@ -497,11 +502,6 @@ bool insertBatchAndHandleErrors(OperationContext* opCtx, if (shouldProceedWithBatchInsert) { try { if (!collection->getCollection()->isCapped() && !inTxn && batch.size() > 1) { - checkCollectionUUIDMismatch(opCtx, - wholeOp.getNamespace(), - collection->getCollection(), - wholeOp.getCollectionUUID()); - // First try doing it all together. If all goes well, this is all we need to do. // See Collection::_insertDocuments for why we do all capped inserts one-at-a-time. lastOpFixer->startingOp(); @@ -544,10 +544,6 @@ bool insertBatchAndHandleErrors(OperationContext* opCtx, // Transactions are not allowed to operate on capped collections. uassertStatusOK( checkIfTransactionOnCappedColl(opCtx, collection->getCollection())); - checkCollectionUUIDMismatch(opCtx, - wholeOp.getNamespace(), - collection->getCollection(), - wholeOp.getCollectionUUID()); lastOpFixer->startingOp(); insertDocuments(opCtx, collection->getCollection(), @@ -796,6 +792,7 @@ static SingleWriteResult performSingleUpdateOp(OperationContext* opCtx, boost::optional<AutoGetCollection> collection; while (true) { collection.emplace(opCtx, ns, fixLockModeForSystemDotViewsChanges(ns, MODE_IX)); + checkCollectionUUIDMismatch(opCtx, ns, collection->getCollection(), opCollectionUUID); if (*collection) { break; } @@ -860,8 +857,6 @@ static SingleWriteResult performSingleUpdateOp(OperationContext* opCtx, uassertStatusOK(checkIfTransactionOnCappedColl(opCtx, coll)); } - checkCollectionUUIDMismatch(opCtx, ns, collection->getCollection(), opCollectionUUID); - const ExtensionsCallbackReal extensionsCallback(opCtx, &updateRequest->getNamespaceString()); ParsedUpdate parsedUpdate(opCtx, updateRequest, extensionsCallback, forgoOpCounterIncrements); uassertStatusOK(parsedUpdate.parseRequest()); |