summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Noma <gregory.noma@gmail.com>2022-06-22 17:33:39 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-22 18:35:08 +0000
commit41994ed8c080afb448b20c631a66bf782a9834c0 (patch)
tree1684fb4ca6802856fedc50fb9c974c189ca4a1cb
parent5f5f73415d5dd3739e2953181bec05f57bbe8807 (diff)
downloadmongo-41994ed8c080afb448b20c631a66bf782a9834c0.tar.gz
SERVER-67227 Avoid implicit collection creation for `collectionUUID` with insert/update commands
-rw-r--r--jstests/aggregation/collection_uuid_coll_stats_index_stats.js3
-rw-r--r--jstests/core/collection_uuid_coll_mod.js3
-rw-r--r--jstests/core/collection_uuid_drop.js3
-rw-r--r--jstests/core/collection_uuid_find.js4
-rw-r--r--jstests/core/collection_uuid_index_commands.js3
-rw-r--r--jstests/core/collection_uuid_rename_collection.js3
-rw-r--r--jstests/core/collection_uuid_write_commands.js6
-rw-r--r--src/mongo/db/ops/write_ops_exec.cpp19
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 33d1cd596b8..8e02cf04ec7 100644
--- a/src/mongo/db/ops/write_ops_exec.cpp
+++ b/src/mongo/db/ops/write_ops_exec.cpp
@@ -452,8 +452,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());
@@ -499,11 +504,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();
@@ -546,10 +546,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(),
@@ -798,6 +794,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;
}
@@ -862,8 +859,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());