summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Noma <gregory.noma@gmail.com>2022-02-11 14:54:48 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-02-11 15:32:28 +0000
commit037b22172c54d5652298203077c16cc0ee7f26a1 (patch)
treecd6628d5497f93bd74d617b79652593c5e1ca5e8
parent2d92ff7fe9a774746e5e34023256b71a5a95a722 (diff)
downloadmongo-037b22172c54d5652298203077c16cc0ee7f26a1.tar.gz
SERVER-62861 Use `null` instead of empty string for `actualNamespace` in `CollectionUUIDMismatch` error response
-rw-r--r--jstests/aggregation/aggregation_with_uuids.js6
-rw-r--r--jstests/aggregation/collection_uuid_coll_stats_index_stats.js13
-rw-r--r--jstests/core/collection_uuid_coll_mod.js2
-rw-r--r--jstests/core/collection_uuid_drop.js2
-rw-r--r--jstests/core/collection_uuid_find.js2
-rw-r--r--jstests/core/collection_uuid_index_commands.js2
-rw-r--r--jstests/core/collection_uuid_rename_collection.js4
-rw-r--r--jstests/core/collection_uuid_write_commands.js4
-rw-r--r--jstests/sharding/collection_uuid_coll_stats_index_stats.js2
-rw-r--r--jstests/sharding/collection_uuid_refine_collection_shard_key.js2
-rw-r--r--jstests/sharding/collection_uuid_reshard_collection.js2
-rw-r--r--jstests/sharding/collection_uuid_shard_collection.js2
-rw-r--r--src/mongo/db/catalog/collection_uuid_mismatch.cpp7
-rw-r--r--src/mongo/db/catalog/collection_uuid_mismatch_info.cpp23
-rw-r--r--src/mongo/db/catalog/collection_uuid_mismatch_info.h4
-rw-r--r--src/mongo/s/cluster_commands_helpers.cpp6
-rw-r--r--src/mongo/s/query/establish_cursors.cpp2
17 files changed, 46 insertions, 39 deletions
diff --git a/jstests/aggregation/aggregation_with_uuids.js b/jstests/aggregation/aggregation_with_uuids.js
index dbf7833d93f..52bcc99545f 100644
--- a/jstests/aggregation/aggregation_with_uuids.js
+++ b/jstests/aggregation/aggregation_with_uuids.js
@@ -79,7 +79,7 @@ res = assert.commandFailedWithCode(
testDB.runCommand(
{aggregate: collName, collectionUUID: uuid, pipeline: [{$match: {}}], cursor: {}}),
ErrorCodes.CollectionUUIDMismatch);
-validateErrorResponse(res, uuid, testColl.getFullName(), "");
+validateErrorResponse(res, uuid, testColl.getFullName(), null);
// Now recreate the collection.
assert.commandWorked(testColl.insert(docs));
@@ -89,7 +89,7 @@ res = assert.commandFailedWithCode(
testDB.runCommand(
{aggregate: collName, collectionUUID: uuid, pipeline: [{$match: {}}], cursor: {}}),
ErrorCodes.CollectionUUIDMismatch);
-validateErrorResponse(res, uuid, testColl.getFullName(), "");
+validateErrorResponse(res, uuid, testColl.getFullName(), null);
collNameRes = assert.commandWorked(
testDB.runCommand({aggregate: collName, pipeline: [{$match: {}}], cursor: {}}));
@@ -106,7 +106,7 @@ res = assert.commandFailedWithCode(
testDB.runCommand(
{aggregate: "viewCollection", collectionUUID: uuid, pipeline: [{$match: {}}], cursor: {}}),
ErrorCodes.CollectionUUIDMismatch);
-validateErrorResponse(res, uuid, testDB.getName() + '.viewCollection', "");
+validateErrorResponse(res, uuid, testDB.getName() + '.viewCollection', null);
//
// Tests for rejecting invalid collectionUUIDs and cases where collectionUUID is not allowed.
diff --git a/jstests/aggregation/collection_uuid_coll_stats_index_stats.js b/jstests/aggregation/collection_uuid_coll_stats_index_stats.js
index 313fdc34cd2..3ad76a86a5b 100644
--- a/jstests/aggregation/collection_uuid_coll_stats_index_stats.js
+++ b/jstests/aggregation/collection_uuid_coll_stats_index_stats.js
@@ -5,8 +5,9 @@
(function() {
'use strict';
-const validateErrorResponse = function(res, collectionUUID, actualNamespace) {
+const validateErrorResponse = function(res, collectionUUID, expectedNamespace, actualNamespace) {
assert.eq(res.collectionUUID, collectionUUID);
+ assert.eq(res.expectedNamespace, expectedNamespace);
assert.eq(res.actualNamespace, actualNamespace);
};
@@ -31,7 +32,7 @@ const testCommand = function(cmd, cmdObj) {
cmdObj["collectionUUID"] = nonexistentUUID;
let res =
assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch);
- validateErrorResponse(res, nonexistentUUID, "");
+ validateErrorResponse(res, nonexistentUUID, coll.getFullName(), null);
jsTestLog("The command '" + cmd +
"' fails when the provided UUID corresponds to a different collection.");
@@ -41,7 +42,7 @@ const testCommand = function(cmd, cmdObj) {
cmdObj["collectionUUID"] = uuid;
res =
assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch);
- validateErrorResponse(res, uuid, coll.getFullName());
+ validateErrorResponse(res, uuid, coll2.getFullName(), coll.getFullName());
jsTestLog("The command '" + cmd +
"' fails when the provided UUID corresponds to a different collection, even if the " +
@@ -49,7 +50,7 @@ const testCommand = function(cmd, cmdObj) {
coll2.drop();
res =
assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch);
- validateErrorResponse(res, uuid, coll.getFullName());
+ validateErrorResponse(res, uuid, coll2.getFullName(), coll.getFullName());
jsTestLog("The command '" + cmd + "' succeeds on view when no UUID is provided.");
const viewName = "view";
@@ -66,7 +67,7 @@ const testCommand = function(cmd, cmdObj) {
cmdObj["collectionUUID"] = uuid;
res =
assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch);
- validateErrorResponse(res, uuid, coll.getFullName());
+ validateErrorResponse(res, uuid, testDB.getName() + '.' + viewName, coll.getFullName());
assert.commandWorked(testDB.runCommand({drop: viewName, writeConcern: {w: "majority"}}));
jsTestLog("The command '" + cmd +
@@ -84,7 +85,7 @@ const testCommand = function(cmd, cmdObj) {
cmdObj["collectionUUID"] = uuid;
res =
assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch);
- validateErrorResponse(res, uuid, coll.getFullName());
+ validateErrorResponse(res, uuid, testDB.getName() + '.' + tsCollName, coll.getFullName());
assert.commandWorked(testDB.runCommand({drop: tsCollName, writeConcern: {w: "majority"}}));
};
diff --git a/jstests/core/collection_uuid_coll_mod.js b/jstests/core/collection_uuid_coll_mod.js
index c71c0c868c8..176c1e7e7ba 100644
--- a/jstests/core/collection_uuid_coll_mod.js
+++ b/jstests/core/collection_uuid_coll_mod.js
@@ -29,7 +29,7 @@ let res = assert.commandFailedWithCode(
ErrorCodes.CollectionUUIDMismatch);
assert.eq(res.collectionUUID, nonexistentUUID);
assert.eq(res.expectedNamespace, coll.getFullName());
-assert.eq(res.actualNamespace, "");
+assert.eq(res.actualNamespace, null);
// 3. The command fails when the provided UUID corresponds to a different collection.
const coll2 = testDB['coll_2'];
diff --git a/jstests/core/collection_uuid_drop.js b/jstests/core/collection_uuid_drop.js
index b06d0af6bc3..8ecb6eb0e13 100644
--- a/jstests/core/collection_uuid_drop.js
+++ b/jstests/core/collection_uuid_drop.js
@@ -31,7 +31,7 @@ let res = assert.commandFailedWithCode(
ErrorCodes.CollectionUUIDMismatch);
assert.eq(res.collectionUUID, nonexistentUUID);
assert.eq(res.expectedNamespace, coll.getFullName());
-assert.eq(res.actualNamespace, "");
+assert.eq(res.actualNamespace, null);
// The command fails when the provided UUID corresponds to a different collection.
const coll2 = testDB['coll_2'];
diff --git a/jstests/core/collection_uuid_find.js b/jstests/core/collection_uuid_find.js
index 7391994c187..195cb1f3df7 100644
--- a/jstests/core/collection_uuid_find.js
+++ b/jstests/core/collection_uuid_find.js
@@ -29,7 +29,7 @@ let res = assert.commandFailedWithCode(
ErrorCodes.CollectionUUIDMismatch);
assert.eq(res.collectionUUID, nonexistentUUID);
assert.eq(res.expectedNamespace, coll.getFullName());
-assert.eq(res.actualNamespace, "");
+assert.eq(res.actualNamespace, null);
// The command fails when the provided UUID corresponds to a different collection.
const coll2 = testDB['coll_2'];
diff --git a/jstests/core/collection_uuid_index_commands.js b/jstests/core/collection_uuid_index_commands.js
index 76e4cb09f15..8f47b5feb65 100644
--- a/jstests/core/collection_uuid_index_commands.js
+++ b/jstests/core/collection_uuid_index_commands.js
@@ -47,7 +47,7 @@ const testCommand = function(cmd, cmdObj) {
cmdObj["collectionUUID"] = nonexistentUUID;
let res =
assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch);
- validateErrorResponse(res, nonexistentUUID, coll.getFullName(), "");
+ validateErrorResponse(res, nonexistentUUID, coll.getFullName(), null);
jsTestLog("The command '" + cmd +
"' fails when the provided UUID corresponds to a different collection.");
diff --git a/jstests/core/collection_uuid_rename_collection.js b/jstests/core/collection_uuid_rename_collection.js
index 5b0777748b0..c26b8c11670 100644
--- a/jstests/core/collection_uuid_rename_collection.js
+++ b/jstests/core/collection_uuid_rename_collection.js
@@ -70,7 +70,7 @@ let res = assert.commandFailedWithCode(testDB.adminCommand({
ErrorCodes.CollectionUUIDMismatch);
assert.eq(res.collectionUUID, nonexistentUUID);
assert.eq(res.expectedNamespace, coll.getFullName());
-assert.eq(res.actualNamespace, "");
+assert.eq(res.actualNamespace, null);
res = assert.commandFailedWithCode(testDB.adminCommand({
renameCollection: coll2.getFullName(),
@@ -80,7 +80,7 @@ res = assert.commandFailedWithCode(testDB.adminCommand({
ErrorCodes.CollectionUUIDMismatch);
assert.eq(res.collectionUUID, nonexistentUUID);
assert.eq(res.expectedNamespace, coll.getFullName());
-assert.eq(res.actualNamespace, "");
+assert.eq(res.actualNamespace, null);
// The command fails when the provided UUID corresponds to a different collection.
res = assert.commandFailedWithCode(testDB.adminCommand({
diff --git a/jstests/core/collection_uuid_write_commands.js b/jstests/core/collection_uuid_write_commands.js
index fde135815fc..322b492e349 100644
--- a/jstests/core/collection_uuid_write_commands.js
+++ b/jstests/core/collection_uuid_write_commands.js
@@ -10,7 +10,7 @@
(function() {
'use strict';
-var validateErrorResponse = function(res, collectionUUID, expectedNamespace, actualNamespace) {
+const validateErrorResponse = function(res, collectionUUID, expectedNamespace, actualNamespace) {
if (res.writeErrors) {
// Sharded cluster scenario.
res = res.writeErrors[0];
@@ -41,7 +41,7 @@ var testCommand = function(cmd, cmdObj) {
cmdObj["collectionUUID"] = nonexistentUUID;
let res =
assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch);
- validateErrorResponse(res, nonexistentUUID, coll.getFullName(), "");
+ validateErrorResponse(res, nonexistentUUID, coll.getFullName(), null);
jsTestLog("The command '" + cmd +
"' fails when the provided UUID corresponds to a different collection.");
diff --git a/jstests/sharding/collection_uuid_coll_stats_index_stats.js b/jstests/sharding/collection_uuid_coll_stats_index_stats.js
index 21cf74945b6..452af9ac512 100644
--- a/jstests/sharding/collection_uuid_coll_stats_index_stats.js
+++ b/jstests/sharding/collection_uuid_coll_stats_index_stats.js
@@ -84,7 +84,7 @@ const testCommand = function(cmd, cmdObj) {
cmdObj["collectionUUID"] = otherShardUUID;
res =
assert.commandFailedWithCode(testDB.runCommand(cmdObj), ErrorCodes.CollectionUUIDMismatch);
- validateErrorResponse(res, otherShardUUID, sameShardColl.getFullName(), "");
+ validateErrorResponse(res, otherShardUUID, sameShardColl.getFullName(), null);
};
testCommand("aggregate", {aggregate: "", pipeline: [{$collStats: {latencyStats: {}}}], cursor: {}});
diff --git a/jstests/sharding/collection_uuid_refine_collection_shard_key.js b/jstests/sharding/collection_uuid_refine_collection_shard_key.js
index cb6ac1ee226..d3708e231d4 100644
--- a/jstests/sharding/collection_uuid_refine_collection_shard_key.js
+++ b/jstests/sharding/collection_uuid_refine_collection_shard_key.js
@@ -56,7 +56,7 @@ let res = assert.commandFailedWithCode(mongos.adminCommand({
ErrorCodes.CollectionUUIDMismatch);
assert.eq(res.collectionUUID, nonexistentUUID);
assert.eq(res.expectedNamespace, coll.getFullName());
-assert.eq(res.actualNamespace, "");
+assert.eq(res.actualNamespace, null);
// The command fails when provided with a different collection's UUID.
const coll2 = db['coll_2'];
diff --git a/jstests/sharding/collection_uuid_reshard_collection.js b/jstests/sharding/collection_uuid_reshard_collection.js
index 381a79147b2..2043de00bdc 100644
--- a/jstests/sharding/collection_uuid_reshard_collection.js
+++ b/jstests/sharding/collection_uuid_reshard_collection.js
@@ -53,7 +53,7 @@ let res = assert.commandFailedWithCode(mongos.adminCommand({
ErrorCodes.CollectionUUIDMismatch);
assert.eq(res.collectionUUID, nonexistentUUID);
assert.eq(res.expectedNamespace, coll.getFullName());
-assert.eq(res.actualNamespace, "");
+assert.eq(res.actualNamespace, null);
// The command fails when provided with a different collection's UUID.
const coll2 = db['coll_2'];
diff --git a/jstests/sharding/collection_uuid_shard_collection.js b/jstests/sharding/collection_uuid_shard_collection.js
index e9c2f3b5e2f..8681a4536d8 100644
--- a/jstests/sharding/collection_uuid_shard_collection.js
+++ b/jstests/sharding/collection_uuid_shard_collection.js
@@ -42,7 +42,7 @@ let res = assert.commandFailedWithCode(
ErrorCodes.CollectionUUIDMismatch);
assert.eq(res.collectionUUID, nonexistentUUID);
assert.eq(res.expectedNamespace, coll.getFullName());
-assert.eq(res.actualNamespace, "");
+assert.eq(res.actualNamespace, null);
// The command fails when the provided UUID corresponds to a different collection.
const coll2 = db['coll_2'];
diff --git a/src/mongo/db/catalog/collection_uuid_mismatch.cpp b/src/mongo/db/catalog/collection_uuid_mismatch.cpp
index 1eb6d30c931..ad79a15f02e 100644
--- a/src/mongo/db/catalog/collection_uuid_mismatch.cpp
+++ b/src/mongo/db/catalog/collection_uuid_mismatch.cpp
@@ -49,11 +49,8 @@ void checkCollectionUUIDMismatch(OperationContext* opCtx,
feature_flags::gCommandsAcceptCollectionUUID.isEnabled(
serverGlobalParams.featureCompatibility));
- uassert((CollectionUUIDMismatchInfo{*uuid,
- ns,
- CollectionCatalog::get(opCtx)
- ->lookupNSSByUUID(opCtx, *uuid)
- .value_or(NamespaceString{})}),
+ uassert((CollectionUUIDMismatchInfo{
+ *uuid, ns, CollectionCatalog::get(opCtx)->lookupNSSByUUID(opCtx, *uuid)}),
"Collection UUID does not match that specified",
coll && coll->uuid() == *uuid);
}
diff --git a/src/mongo/db/catalog/collection_uuid_mismatch_info.cpp b/src/mongo/db/catalog/collection_uuid_mismatch_info.cpp
index 3813615916a..5313b459b67 100644
--- a/src/mongo/db/catalog/collection_uuid_mismatch_info.cpp
+++ b/src/mongo/db/catalog/collection_uuid_mismatch_info.cpp
@@ -35,18 +35,29 @@
namespace mongo {
namespace {
MONGO_INIT_REGISTER_ERROR_EXTRA_INFO(CollectionUUIDMismatchInfo);
+
+constexpr StringData kCollectionUUIDFieldName = "collectionUUID"_sd;
+constexpr StringData kExpectedNamespaceFieldName = "expectedNamespace"_sd;
+constexpr StringData kActualNamespaceFieldName = "actualNamespace"_sd;
} // namespace
std::shared_ptr<const ErrorExtraInfo> CollectionUUIDMismatchInfo::parse(const BSONObj& obj) {
+ auto actualNamespace = obj[kActualNamespaceFieldName];
return std::make_shared<CollectionUUIDMismatchInfo>(
- UUID::parse(obj["collectionUUID"]).getValue(),
- NamespaceString{obj.getStringField("expectedNamespace")},
- NamespaceString{obj.getStringField("actualNamespace")});
+ UUID::parse(obj[kCollectionUUIDFieldName]).getValue(),
+ NamespaceString{obj.getStringField(kExpectedNamespaceFieldName)},
+ actualNamespace.isNull()
+ ? boost::none
+ : boost::make_optional(NamespaceString{actualNamespace.valueStringData()}));
}
void CollectionUUIDMismatchInfo::serialize(BSONObjBuilder* builder) const {
- _collectionUUID.appendToBuilder(builder, "collectionUUID");
- builder->append("expectedNamespace", _expectedNamespace.ns());
- builder->append("actualNamespace", _actualNamespace.ns());
+ _collectionUUID.appendToBuilder(builder, kCollectionUUIDFieldName);
+ builder->append(kExpectedNamespaceFieldName, _expectedNamespace.ns());
+ if (_actualNamespace) {
+ builder->append(kActualNamespaceFieldName, _actualNamespace->ns());
+ } else {
+ builder->appendNull(kActualNamespaceFieldName);
+ }
}
} // namespace mongo
diff --git a/src/mongo/db/catalog/collection_uuid_mismatch_info.h b/src/mongo/db/catalog/collection_uuid_mismatch_info.h
index c851c57e36d..538527b14c9 100644
--- a/src/mongo/db/catalog/collection_uuid_mismatch_info.h
+++ b/src/mongo/db/catalog/collection_uuid_mismatch_info.h
@@ -40,7 +40,7 @@ public:
explicit CollectionUUIDMismatchInfo(const UUID& collectionUUID,
const NamespaceString& expectedNamespace,
- const NamespaceString& actualNamespace)
+ const boost::optional<NamespaceString>& actualNamespace)
: _collectionUUID(collectionUUID),
_expectedNamespace(expectedNamespace),
_actualNamespace(actualNamespace) {}
@@ -56,6 +56,6 @@ public:
private:
UUID _collectionUUID;
NamespaceString _expectedNamespace;
- NamespaceString _actualNamespace;
+ boost::optional<NamespaceString> _actualNamespace;
};
} // namespace mongo
diff --git a/src/mongo/s/cluster_commands_helpers.cpp b/src/mongo/s/cluster_commands_helpers.cpp
index 32bc6e50137..abeec91696c 100644
--- a/src/mongo/s/cluster_commands_helpers.cpp
+++ b/src/mongo/s/cluster_commands_helpers.cpp
@@ -626,16 +626,14 @@ RawResponsesResult appendRawResponses(
auto& firstError = genericErrorsReceived.front().second;
if (firstError.code() == ErrorCodes::CollectionUUIDMismatch &&
- firstError.extraInfo<CollectionUUIDMismatchInfo>()->actualNamespace().isEmpty()) {
+ !firstError.extraInfo<CollectionUUIDMismatchInfo>()->actualNamespace()) {
// The first error is a CollectionUUIDMismatchInfo but it doesn't contain an actual
// namespace. It's possible that the acutal namespace is unsharded, in which case only the
// error from the primary shard will contain this information. Iterate through the errors to
// see if this is the case.
for (const auto& error : genericErrorsReceived) {
if (error.second.code() == ErrorCodes::CollectionUUIDMismatch &&
- !error.second.extraInfo<CollectionUUIDMismatchInfo>()
- ->actualNamespace()
- .isEmpty()) {
+ error.second.extraInfo<CollectionUUIDMismatchInfo>()->actualNamespace()) {
firstError = error.second;
break;
}
diff --git a/src/mongo/s/query/establish_cursors.cpp b/src/mongo/s/query/establish_cursors.cpp
index f73a1672efb..c37de60e22d 100644
--- a/src/mongo/s/query/establish_cursors.cpp
+++ b/src/mongo/s/query/establish_cursors.cpp
@@ -254,7 +254,7 @@ void CursorEstablisher::_favorCollectionUUIDMismatchError(Status newError) noexc
// Favor 'CollectionUUIDMismatchError' that has a non empty 'actualNamespace'.
auto errorInfo = _maybeFailure->extraInfo<CollectionUUIDMismatchInfo>();
invariant(errorInfo);
- if (errorInfo->actualNamespace().ns().empty()) {
+ if (!errorInfo->actualNamespace()) {
_maybeFailure = std::move(newError);
}
}