summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjannaerin <golden.janna@gmail.com>2023-03-29 16:29:36 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-03-29 19:13:28 +0000
commit4326f194dcd67e1053e7e57dae003831aacc5f2c (patch)
treeb8926e345b61498d7628cd340cc224cc610bc11b
parent6759d92c8cd619d00bd522bb5ebd688a4d685fd0 (diff)
downloadmongo-4326f194dcd67e1053e7e57dae003831aacc5f2c.tar.gz
SERVER-73112 Make NamespaceString constructors private
-rw-r--r--buildscripts/resmokeconfig/suites/serverless.yml4
-rw-r--r--jstests/auth/change_stream_change_collection_role_auth.js1
-rw-r--r--jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js10
-rw-r--r--src/mongo/db/auth/auth_op_observer.cpp4
-rw-r--r--src/mongo/db/auth/authorization_checks.cpp6
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_local.cpp10
-rw-r--r--src/mongo/db/auth/privilege_parser.cpp5
-rw-r--r--src/mongo/db/auth/resource_pattern.h25
-rw-r--r--src/mongo/db/catalog/coll_mod.cpp2
-rw-r--r--src/mongo/db/catalog/index_builds_manager.cpp2
-rw-r--r--src/mongo/db/catalog/index_consistency.cpp5
-rw-r--r--src/mongo/db/catalog/index_repair.cpp2
-rw-r--r--src/mongo/db/catalog/uncommitted_catalog_updates.cpp2
-rw-r--r--src/mongo/db/catalog/unique_collection_name.cpp2
-rw-r--r--src/mongo/db/commands.cpp6
-rw-r--r--src/mongo/db/commands/collection_to_capped.cpp7
-rw-r--r--src/mongo/db/commands/connection_status.cpp2
-rw-r--r--src/mongo/db/commands/create_command.cpp3
-rw-r--r--src/mongo/db/commands/dbcheck.cpp3
-rw-r--r--src/mongo/db/commands/dbcommands.cpp4
-rw-r--r--src/mongo/db/commands/dbcommands_d.cpp4
-rw-r--r--src/mongo/db/commands/fail_point_cmd.cpp2
-rw-r--r--src/mongo/db/commands/generic.cpp2
-rw-r--r--src/mongo/db/commands/generic_servers.cpp2
-rw-r--r--src/mongo/db/commands/get_cluster_parameter_command.cpp2
-rw-r--r--src/mongo/db/commands/getmore_cmd.cpp9
-rw-r--r--src/mongo/db/commands/http_client.cpp2
-rw-r--r--src/mongo/db/commands/killoperations_common.h2
-rw-r--r--src/mongo/db/commands/list_collections.cpp3
-rw-r--r--src/mongo/db/commands/list_databases.cpp2
-rw-r--r--src/mongo/db/commands/list_indexes.cpp2
-rw-r--r--src/mongo/db/commands/profile_common.cpp4
-rw-r--r--src/mongo/db/commands/run_aggregate.cpp4
-rw-r--r--src/mongo/db/commands/rwc_defaults_commands.cpp4
-rw-r--r--src/mongo/db/commands/shutdown.h2
-rw-r--r--src/mongo/db/commands/tenant_migration_donor_cmds.cpp6
-rw-r--r--src/mongo/db/commands/tenant_migration_recipient_cmds.cpp6
-rw-r--r--src/mongo/db/commands/traffic_recording_cmds.cpp4
-rw-r--r--src/mongo/db/commands/user_management_commands.cpp11
-rw-r--r--src/mongo/db/commands/validate_db_metadata_cmd.cpp5
-rw-r--r--src/mongo/db/commands/vote_abort_index_build_command.cpp2
-rw-r--r--src/mongo/db/commands/vote_commit_index_build_command.cpp2
-rw-r--r--src/mongo/db/exec/stagedebug_cmd.cpp3
-rw-r--r--src/mongo/db/fle_crud.cpp19
-rw-r--r--src/mongo/db/introspect.cpp6
-rw-r--r--src/mongo/db/namespace_string.cpp23
-rw-r--r--src/mongo/db/namespace_string.h157
-rw-r--r--src/mongo/db/namespace_string_test.cpp41
-rw-r--r--src/mongo/db/op_observer/op_observer_impl.cpp7
-rw-r--r--src/mongo/db/op_observer/op_observer_impl_test.cpp3
-rw-r--r--src/mongo/db/op_observer/user_write_block_mode_op_observer.cpp2
-rw-r--r--src/mongo/db/pipeline/aggregation_request_helper.cpp3
-rw-r--r--src/mongo/db/pipeline/change_stream_event_transform.cpp35
-rw-r--r--src/mongo/db/pipeline/change_stream_test_helpers.h3
-rw-r--r--src/mongo/db/pipeline/document_source_change_stream_add_post_image.cpp3
-rw-r--r--src/mongo/db/pipeline/document_source_graph_lookup.cpp8
-rw-r--r--src/mongo/db/pipeline/document_source_graph_lookup_test.cpp3
-rw-r--r--src/mongo/db/pipeline/document_source_lookup.cpp6
-rw-r--r--src/mongo/db/pipeline/document_source_merge.cpp7
-rw-r--r--src/mongo/db/pipeline/document_source_merge_cursors_test.cpp3
-rw-r--r--src/mongo/db/pipeline/document_source_merge_spec.cpp5
-rw-r--r--src/mongo/db/pipeline/document_source_out.cpp12
-rw-r--r--src/mongo/db/pipeline/document_source_union_with.cpp12
-rw-r--r--src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp3
-rw-r--r--src/mongo/db/pipeline/process_interface/replica_set_node_process_interface.cpp2
-rw-r--r--src/mongo/db/query/fle/server_rewrite.cpp20
-rw-r--r--src/mongo/db/repl/collection_cloner_test.cpp6
-rw-r--r--src/mongo/db/repl/database_cloner.cpp3
-rw-r--r--src/mongo/db/repl/idempotency_test_fixture.h3
-rw-r--r--src/mongo/db/repl/oplog.cpp2
-rw-r--r--src/mongo/db/repl/oplog_applier_impl_test.cpp4
-rw-r--r--src/mongo/db/repl/repl_set_test_egress.cpp2
-rw-r--r--src/mongo/db/repl/rollback_impl_test.cpp8
-rw-r--r--src/mongo/db/repl/shard_merge_recipient_service.cpp3
-rw-r--r--src/mongo/db/repl/tenant_migration_recipient_service.cpp3
-rw-r--r--src/mongo/db/repl/tenant_migration_shard_merge_util.h3
-rw-r--r--src/mongo/db/s/add_shard_cmd.cpp2
-rw-r--r--src/mongo/db/s/analyze_shard_key_cmd_util.cpp10
-rw-r--r--src/mongo/db/s/check_sharding_index_command.cpp3
-rw-r--r--src/mongo/db/s/config/configsvr_ensure_chunk_version_is_greater_than_command.cpp2
-rw-r--r--src/mongo/db/s/config/configsvr_remove_chunks_command.cpp2
-rw-r--r--src/mongo/db/s/config/configsvr_repair_sharded_collection_chunks_history_command.cpp3
-rw-r--r--src/mongo/db/s/config/configsvr_split_chunk_command.cpp3
-rw-r--r--src/mongo/db/s/get_database_version_command.cpp3
-rw-r--r--src/mongo/db/s/get_shard_version_command.cpp3
-rw-r--r--src/mongo/db/s/migration_destination_manager_commands.cpp3
-rw-r--r--src/mongo/db/s/move_primary/move_primary_recipient_cmds.cpp6
-rw-r--r--src/mongo/db/s/move_primary_coordinator.cpp5
-rw-r--r--src/mongo/db/s/resharding/resharding_collection_cloner.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_create_global_index_command.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_drop_database_command.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_drop_database_participant_command.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_drop_global_index_command.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_get_stats_for_balancing_command.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_join_migrations_command.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_merge_chunks_command.cpp3
-rw-r--r--src/mongo/db/s/shardsvr_move_primary_command.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_split_chunk_command.cpp3
-rw-r--r--src/mongo/db/s/shardsvr_write_global_index_keys_command.cpp2
-rw-r--r--src/mongo/db/s/split_vector_command.cpp3
-rw-r--r--src/mongo/db/s/txn_two_phase_commit_cmds.cpp4
-rw-r--r--src/mongo/db/serverless/shard_split_commands.cpp6
-rw-r--r--src/mongo/db/service_entry_point_common.cpp5
-rw-r--r--src/mongo/db/shard_role_test.cpp3
-rw-r--r--src/mongo/db/storage/kv/kv_engine_test_harness.cpp12
-rw-r--r--src/mongo/db/views/SConscript1
-rw-r--r--src/mongo/db/views/view.cpp4
-rw-r--r--src/mongo/dbtests/validate_tests.cpp12
-rw-r--r--src/mongo/s/commands/cluster_coordinate_commit_txn.cpp2
-rw-r--r--src/mongo/s/commands/cluster_filemd5_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_get_shard_version_cmd.cpp3
-rw-r--r--src/mongo/s/commands/cluster_getmore_cmd.h3
-rw-r--r--src/mongo/s/commands/cluster_list_databases_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_merge_chunks_cmd.cpp3
-rw-r--r--src/mongo/s/commands/cluster_move_primary_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_repair_sharded_collection_chunks_history_cmd.cpp3
-rw-r--r--src/mongo/s/commands/cluster_rwc_defaults_commands.cpp2
-rw-r--r--src/mongo/s/commands/cluster_shard_collection_cmd.cpp3
-rw-r--r--src/mongo/s/commands/cluster_split_cmd.cpp3
-rw-r--r--src/mongo/s/commands/cluster_split_vector_cmd.cpp3
-rw-r--r--src/mongo/s/commands/cluster_user_management_commands.cpp9
-rw-r--r--src/mongo/s/commands/internal_transactions_test_command.h2
-rw-r--r--src/mongo/s/commands/sharding_expressions.cpp3
-rw-r--r--src/mongo/s/query/cluster_find.cpp3
-rw-r--r--src/mongo/shell/bench.cpp22
-rw-r--r--src/mongo/util/namespace_string_util.cpp64
-rw-r--r--src/mongo/util/namespace_string_util.h20
128 files changed, 571 insertions, 314 deletions
diff --git a/buildscripts/resmokeconfig/suites/serverless.yml b/buildscripts/resmokeconfig/suites/serverless.yml
index 884947a11a0..079496d45fb 100644
--- a/buildscripts/resmokeconfig/suites/serverless.yml
+++ b/buildscripts/resmokeconfig/suites/serverless.yml
@@ -4,7 +4,9 @@ selector:
roots:
- jstests/serverless/*.js
- jstests/serverless/change_streams/**/*.js
- - src/mongo/db/modules/*/jstests/serverless/**/*.js
+ # TODO SERVER-74888 Re-enable once the encrypted shell can handle tenantIds regardless of
+ # multitenancySupport.
+ # - src/mongo/db/modules/*/jstests/serverless/**/*.js
executor:
config:
diff --git a/jstests/auth/change_stream_change_collection_role_auth.js b/jstests/auth/change_stream_change_collection_role_auth.js
index 7ea4be1ffb1..4d174543d66 100644
--- a/jstests/auth/change_stream_change_collection_role_auth.js
+++ b/jstests/auth/change_stream_change_collection_role_auth.js
@@ -6,6 +6,7 @@
* assumes_read_preference_unchanged,
* requires_replication,
* requires_fcv_62,
+ * __TEMPORARILY_DISABLED__
* ]
*/
(function() {
diff --git a/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js b/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js
index c56362a6db8..aff88c405b1 100644
--- a/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js
+++ b/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js
@@ -402,15 +402,13 @@ const testColl = testDb.getCollection(kCollName);
"collMod": kCollName,
"index": {"keyPattern": {c: 1}, expireAfterSeconds: 100},
});
- assert.commandFailedWithCode(res, ErrorCodes.NamespaceNotFound);
- // TODO SERVER-73025 Uncomment out this conditional below, and remove the assertion above in
- // favor of the assertion in the conditional.
- /* if (featureFlagRequireTenantId) {
- assert.commandFailedWithCode(res, 7005300);
+ if (featureFlagRequireTenantId) {
+ // When the feature flag is enabled, the server will assert that all requests contain a
+ // tenantId.
+ assert.commandFailedWithCode(res, 6972100);
} else {
assert.commandFailedWithCode(res, ErrorCodes.NamespaceNotFound);
}
- */
// Modify the index with the tenantId
res = assert.commandWorked(testDb.runCommand({
diff --git a/src/mongo/db/auth/auth_op_observer.cpp b/src/mongo/db/auth/auth_op_observer.cpp
index bc1091f2dae..1a61ba188dd 100644
--- a/src/mongo/db/auth/auth_op_observer.cpp
+++ b/src/mongo/db/auth/auth_op_observer.cpp
@@ -126,7 +126,7 @@ void AuthOpObserver::onCollMod(OperationContext* opCtx,
}
void AuthOpObserver::onDropDatabase(OperationContext* opCtx, const DatabaseName& dbName) {
- const NamespaceString cmdNss{dbName, "$cmd"};
+ const NamespaceString cmdNss(NamespaceString::makeCommandNamespace(dbName));
const auto cmdObj = BSON("dropDatabase" << 1);
AuthorizationManager::get(opCtx->getServiceContext())
@@ -206,7 +206,7 @@ void AuthOpObserver::onImportCollection(OperationContext* opCtx,
void AuthOpObserver::onApplyOps(OperationContext* opCtx,
const DatabaseName& dbName,
const BSONObj& applyOpCmd) {
- const NamespaceString cmdNss{dbName, "$cmd"};
+ const NamespaceString cmdNss(NamespaceString::makeCommandNamespace(dbName));
AuthorizationManager::get(opCtx->getServiceContext())
->logOp(opCtx, "c", cmdNss, applyOpCmd, nullptr);
diff --git a/src/mongo/db/auth/authorization_checks.cpp b/src/mongo/db/auth/authorization_checks.cpp
index 6af135d0ee2..5e1f9ad1987 100644
--- a/src/mongo/db/auth/authorization_checks.cpp
+++ b/src/mongo/db/auth/authorization_checks.cpp
@@ -225,7 +225,8 @@ Status checkAuthForCreate(OperationContext* opCtx,
// Parse the viewOn namespace and the pipeline. If no pipeline was specified, use the empty
// pipeline.
- NamespaceString viewOnNs(ns.db(), optViewOn.value());
+ NamespaceString viewOnNs(
+ NamespaceStringUtil::parseNamespaceFromRequest(ns.dbName(), optViewOn.value()));
auto pipeline = cmd.getPipeline().get_value_or(std::vector<BSONObj>());
BSONArrayBuilder pipelineArray;
for (const auto& stage : pipeline) {
@@ -266,7 +267,8 @@ Status checkAuthForCollMod(OperationContext* opCtx,
"Must specify both 'viewOn' and 'pipeline' when modifying a view and auth is enabled");
}
if (hasViewOn) {
- NamespaceString viewOnNs(ns.db(), cmdObj["viewOn"].checkAndGetStringData());
+ NamespaceString viewOnNs(NamespaceStringUtil::parseNamespaceFromRequest(
+ ns.dbName(), cmdObj["viewOn"].checkAndGetStringData()));
auto viewPipeline = BSONArray(cmdObj["pipeline"].Obj());
return checkAuthForCreateOrModifyView(
opCtx, authSession, ns, viewOnNs, viewPipeline, isMongos);
diff --git a/src/mongo/db/auth/authz_manager_external_state_local.cpp b/src/mongo/db/auth/authz_manager_external_state_local.cpp
index 007ab381646..f799c2fb1ba 100644
--- a/src/mongo/db/auth/authz_manager_external_state_local.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_local.cpp
@@ -105,11 +105,11 @@ Status AuthzManagerExternalStateLocal::getStoredAuthorizationVersion(OperationCo
namespace {
NamespaceString getUsersCollection(const boost::optional<TenantId>& tenant) {
- return NamespaceString(tenant, DatabaseName::kAdmin.db(), NamespaceString::kSystemUsers);
+ return NamespaceString::makeTenantUsersCollection(tenant);
}
NamespaceString getRolesCollection(const boost::optional<TenantId>& tenant) {
- return NamespaceString(tenant, DatabaseName::kAdmin.db(), NamespaceString::kSystemRoles);
+ return NamespaceString::makeTenantRolesCollection(tenant);
}
void serializeResolvedRoles(BSONObjBuilder* user,
@@ -253,10 +253,8 @@ void handleAuthLocalGetUserFailPoint(const std::vector<RoleName>& directRoles) {
Status AuthzManagerExternalStateLocal::hasAnyUserDocuments(
OperationContext* opCtx, const boost::optional<TenantId>& tenantId) {
BSONObj userBSONObj;
- return findOne(opCtx,
- NamespaceString(tenantId, NamespaceString::kAdminUsersNamespace.ns()),
- BSONObj(),
- &userBSONObj);
+ return findOne(
+ opCtx, NamespaceString::makeTenantUsersCollection(tenantId), BSONObj(), &userBSONObj);
}
// If tenantId is none, we're checking whether to enable localhost auth bypass which by definition
diff --git a/src/mongo/db/auth/privilege_parser.cpp b/src/mongo/db/auth/privilege_parser.cpp
index d240328a4bd..801e731af08 100644
--- a/src/mongo/db/auth/privilege_parser.cpp
+++ b/src/mongo/db/auth/privilege_parser.cpp
@@ -500,8 +500,9 @@ Status ParsedPrivilege::parsedPrivilegeToPrivilege(const ParsedPrivilege& parsed
} else {
if (parsedResource.isDbSet() && !parsedResource.getDb().empty()) {
if (parsedResource.isCollectionSet() && !parsedResource.getCollection().empty()) {
- resource = ResourcePattern::forExactNamespace(NamespaceString(
- boost::none, parsedResource.getDb(), parsedResource.getCollection()));
+ resource = ResourcePattern::forExactNamespace(
+ NamespaceString::createNamespaceStringForAuth(
+ boost::none, parsedResource.getDb(), parsedResource.getCollection()));
} else {
resource = ResourcePattern::forDatabaseName(parsedResource.getDb());
}
diff --git a/src/mongo/db/auth/resource_pattern.h b/src/mongo/db/auth/resource_pattern.h
index e289ca97049..036c12df655 100644
--- a/src/mongo/db/auth/resource_pattern.h
+++ b/src/mongo/db/auth/resource_pattern.h
@@ -79,8 +79,9 @@ public:
* "ns" for which ns.isSystem() is false and ns.db() == dbname.
*/
static ResourcePattern forDatabaseName(StringData dbName) {
- return ResourcePattern(MatchTypeEnum::kMatchDatabaseName,
- NamespaceString(boost::none, dbName, ""));
+ return ResourcePattern(
+ MatchTypeEnum::kMatchDatabaseName,
+ NamespaceString::createNamespaceStringForAuth(boost::none, dbName, ""));
}
/**
@@ -88,8 +89,9 @@ public:
* collectionName.
*/
static ResourcePattern forCollectionName(StringData collectionName) {
- return ResourcePattern(MatchTypeEnum::kMatchCollectionName,
- NamespaceString(boost::none, "", collectionName));
+ return ResourcePattern(
+ MatchTypeEnum::kMatchCollectionName,
+ NamespaceString::createNamespaceStringForAuth(boost::none, "", collectionName));
}
/**
@@ -112,8 +114,9 @@ public:
* "db".
*/
static ResourcePattern forAnySystemBucketsInDatabase(StringData dbName) {
- return ResourcePattern(MatchTypeEnum::kMatchAnySystemBucketInDBResource,
- NamespaceString(boost::none, dbName, ""));
+ return ResourcePattern(
+ MatchTypeEnum::kMatchAnySystemBucketInDBResource,
+ NamespaceString::createNamespaceStringForAuth(boost::none, dbName, ""));
}
/**
@@ -121,8 +124,9 @@ public:
* in any database.
*/
static ResourcePattern forAnySystemBucketsInAnyDatabase(StringData collectionName) {
- return ResourcePattern(MatchTypeEnum::kMatchSystemBucketInAnyDBResource,
- NamespaceString(boost::none, "", collectionName));
+ return ResourcePattern(
+ MatchTypeEnum::kMatchSystemBucketInAnyDBResource,
+ NamespaceString::createNamespaceStringForAuth(boost::none, "", collectionName));
}
/**
@@ -132,8 +136,9 @@ public:
static ResourcePattern forExactSystemBucketsCollection(StringData dbName,
StringData collectionName) {
invariant(!collectionName.startsWith("system.buckets."));
- return ResourcePattern(MatchTypeEnum::kMatchExactSystemBucketResource,
- NamespaceString(boost::none, dbName, collectionName));
+ return ResourcePattern(
+ MatchTypeEnum::kMatchExactSystemBucketResource,
+ NamespaceString::createNamespaceStringForAuth(boost::none, dbName, collectionName));
}
/**
diff --git a/src/mongo/db/catalog/coll_mod.cpp b/src/mongo/db/catalog/coll_mod.cpp
index daa52908254..3881b2dfba0 100644
--- a/src/mongo/db/catalog/coll_mod.cpp
+++ b/src/mongo/db/catalog/coll_mod.cpp
@@ -838,7 +838,7 @@ Status _collModInternal(OperationContext* opCtx,
view->setPipeline(*cmd.getPipeline());
if (!viewOn.empty())
- view->setViewOn(NamespaceString(dbName, viewOn));
+ view->setViewOn(NamespaceStringUtil::parseNamespaceFromRequest(dbName, viewOn));
BSONArrayBuilder pipeline;
for (auto& item : view->pipeline()) {
diff --git a/src/mongo/db/catalog/index_builds_manager.cpp b/src/mongo/db/catalog/index_builds_manager.cpp
index 90821c2b484..4233138c744 100644
--- a/src/mongo/db/catalog/index_builds_manager.cpp
+++ b/src/mongo/db/catalog/index_builds_manager.cpp
@@ -258,7 +258,7 @@ StatusWith<std::pair<long long, long long>> IndexBuildsManager::startBuildingInd
long long bytesRemoved = 0;
const NamespaceString lostAndFoundNss =
- NamespaceString(DatabaseName::kLocal, "lost_and_found." + coll->uuid().toString());
+ NamespaceString::makeLocalCollection("lost_and_found." + coll->uuid().toString());
// Delete duplicate record and insert it into local lost and found.
Status status = [&] {
diff --git a/src/mongo/db/catalog/index_consistency.cpp b/src/mongo/db/catalog/index_consistency.cpp
index 7875d7d13d8..186b3a61ae2 100644
--- a/src/mongo/db/catalog/index_consistency.cpp
+++ b/src/mongo/db/catalog/index_consistency.cpp
@@ -212,9 +212,8 @@ void KeyStringIndexConsistency::repairIndexEntries(OperationContext* opCtx,
<< " missing index entries.");
}
if (results->numDocumentsMovedToLostAndFound > 0) {
- const NamespaceString lostAndFoundNss =
- NamespaceString(DatabaseName::kLocal,
- "lost_and_found." + _validateState->getCollection()->uuid().toString());
+ const NamespaceString lostAndFoundNss = NamespaceString::makeLocalCollection(
+ "lost_and_found." + _validateState->getCollection()->uuid().toString());
results->warnings.push_back(str::stream()
<< "Removed " << results->numDocumentsMovedToLostAndFound
<< " duplicate documents to resolve "
diff --git a/src/mongo/db/catalog/index_repair.cpp b/src/mongo/db/catalog/index_repair.cpp
index 8ed4bb76a48..96fca0781dc 100644
--- a/src/mongo/db/catalog/index_repair.cpp
+++ b/src/mongo/db/catalog/index_repair.cpp
@@ -181,7 +181,7 @@ int repairMissingIndexEntry(OperationContext* opCtx,
if (coll->findDoc(opCtx, ridToMove, &doc)) {
const NamespaceString lostAndFoundNss =
- NamespaceString(DatabaseName::kLocal, "lost_and_found." + coll->uuid().toString());
+ NamespaceString::makeLocalCollection("lost_and_found." + coll->uuid().toString());
auto moveStatus = moveRecordToLostAndFound(opCtx, nss, lostAndFoundNss, ridToMove);
diff --git a/src/mongo/db/catalog/uncommitted_catalog_updates.cpp b/src/mongo/db/catalog/uncommitted_catalog_updates.cpp
index c98f88725ae..751c0b25f6f 100644
--- a/src/mongo/db/catalog/uncommitted_catalog_updates.cpp
+++ b/src/mongo/db/catalog/uncommitted_catalog_updates.cpp
@@ -216,7 +216,7 @@ void UncommittedCatalogUpdates::replaceViewsForDatabase(const DatabaseName& dbNa
ViewsForDatabase&& vfdb) {
_entries.push_back({Entry::Action::kReplacedViewsForDatabase,
nullptr,
- NamespaceString{dbName, ""},
+ NamespaceString{dbName},
boost::none,
{},
std::move(vfdb)});
diff --git a/src/mongo/db/catalog/unique_collection_name.cpp b/src/mongo/db/catalog/unique_collection_name.cpp
index 2096bed3820..a5efa4b22df 100644
--- a/src/mongo/db/catalog/unique_collection_name.cpp
+++ b/src/mongo/db/catalog/unique_collection_name.cpp
@@ -81,7 +81,7 @@ StatusWith<NamespaceString> makeUniqueCollectionName(OperationContext* opCtx,
collectionName.begin(),
replacePercentSign);
- NamespaceString nss(dbName, collectionName);
+ NamespaceString nss(NamespaceStringUtil::parseNamespaceFromDoc(dbName, collectionName));
if (!CollectionCatalog::get(opCtx)->lookupCollectionByNamespace(opCtx, nss)) {
return nss;
}
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 0fb0013dfb4..d470a767036 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -297,7 +297,8 @@ NamespaceString CommandHelpers::parseNsCollectionRequired(const DatabaseName& db
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "collection name has invalid type " << typeName(first.type()),
first.canonicalType() == canonicalizeBSONType(mongo::String));
- const NamespaceString nss(dbName, first.valueStringData());
+ const NamespaceString nss(
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, first.valueStringData()));
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "Invalid namespace specified '" << nss.ns() << "'",
nss.isValid());
@@ -328,7 +329,8 @@ NamespaceString CommandHelpers::parseNsFromCommand(const DatabaseName& dbName,
BSONElement first = cmdObj.firstElement();
if (first.type() != mongo::String)
return NamespaceString(dbName);
- return NamespaceString(dbName, cmdObj.firstElement().valueStringData());
+ return NamespaceStringUtil::parseNamespaceFromRequest(dbName,
+ cmdObj.firstElement().valueStringData());
}
ResourcePattern CommandHelpers::resourcePatternForNamespace(const std::string& ns) {
diff --git a/src/mongo/db/commands/collection_to_capped.cpp b/src/mongo/db/commands/collection_to_capped.cpp
index 2796e297e61..fd5bf446270 100644
--- a/src/mongo/db/commands/collection_to_capped.cpp
+++ b/src/mongo/db/commands/collection_to_capped.cpp
@@ -73,7 +73,8 @@ public:
uassert(ErrorCodes::TypeMismatch,
"'toCollection' must be of type String",
nssElt.type() == BSONType::String);
- const NamespaceString nss(dbName, nssElt.valueStringData());
+ const NamespaceString nss(
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, nssElt.valueStringData()));
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "Invalid target namespace: " << nss.ns(),
nss.isValid());
@@ -116,8 +117,8 @@ public:
uassert(ErrorCodes::InvalidOptions, "invalid command spec", size != 0);
- NamespaceString fromNs(dbName, from);
- NamespaceString toNs(dbName, to);
+ NamespaceString fromNs(NamespaceStringUtil::parseNamespaceFromRequest(dbName, from));
+ NamespaceString toNs(NamespaceStringUtil::parseNamespaceFromRequest(dbName, to));
AutoGetCollection autoColl(opCtx, fromNs, MODE_X);
Lock::CollectionLock collLock(opCtx, toNs, MODE_X);
diff --git a/src/mongo/db/commands/connection_status.cpp b/src/mongo/db/commands/connection_status.cpp
index 8e32d25f87e..152b9b69478 100644
--- a/src/mongo/db/commands/connection_status.cpp
+++ b/src/mongo/db/commands/connection_status.cpp
@@ -109,7 +109,7 @@ public:
}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/commands/create_command.cpp b/src/mongo/db/commands/create_command.cpp
index d91ec734f08..78573ff879a 100644
--- a/src/mongo/db/commands/create_command.cpp
+++ b/src/mongo/db/commands/create_command.cpp
@@ -115,7 +115,8 @@ void checkCollectionOptions(OperationContext* opCtx,
MONGO_UNREACHABLE;
}
- auto fullNewNamespace = NamespaceString(ns.dbName(), options.viewOn);
+ auto fullNewNamespace =
+ NamespaceStringUtil::parseNamespaceFromRequest(ns.dbName(), options.viewOn);
uassert(ErrorCodes::NamespaceExists,
str::stream() << "namespace " << ns.ns() << " already exists, but is a view on "
<< view->viewOn() << " rather than " << fullNewNamespace,
diff --git a/src/mongo/db/commands/dbcheck.cpp b/src/mongo/db/commands/dbcheck.cpp
index c55f42df246..cf90ec8ba73 100644
--- a/src/mongo/db/commands/dbcheck.cpp
+++ b/src/mongo/db/commands/dbcheck.cpp
@@ -156,7 +156,8 @@ using DbCheckRun = std::vector<DbCheckCollectionInfo>;
std::unique_ptr<DbCheckRun> singleCollectionRun(OperationContext* opCtx,
const DatabaseName& dbName,
const DbCheckSingleInvocation& invocation) {
- NamespaceString nss(dbName, invocation.getColl());
+ NamespaceString nss(
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, invocation.getColl()));
AutoGetCollectionForRead agc(opCtx, nss);
uassert(ErrorCodes::NamespaceNotFound,
diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp
index a0269f2ccc4..6216f7a7b22 100644
--- a/src/mongo/db/commands/dbcommands.cpp
+++ b/src/mongo/db/commands/dbcommands.cpp
@@ -255,9 +255,7 @@ public:
}
NamespaceString ns() const final {
- const auto& tenant = request().getDbName().tenantId();
- const auto& nss = request().getCommandParameter();
- return NamespaceString(tenant, nss.db(), nss.coll());
+ return request().getCommandParameter();
}
Reply typedRun(OperationContext* opCtx) {
diff --git a/src/mongo/db/commands/dbcommands_d.cpp b/src/mongo/db/commands/dbcommands_d.cpp
index 370f6861778..96b1058599c 100644
--- a/src/mongo/db/commands/dbcommands_d.cpp
+++ b/src/mongo/db/commands/dbcommands_d.cpp
@@ -165,7 +165,7 @@ protected:
// Accessing system.profile collection should not conflict with oplog application.
ShouldNotConflictWithSecondaryBatchApplicationBlock shouldNotConflictBlock(
opCtx->lockState());
- NamespaceString nss{dbName, NamespaceString::kSystemDotProfileCollectionName};
+ NamespaceString nss(NamespaceString::makeSystemDotProfileNamespace(dbName));
AutoGetCollection ctx(opCtx, nss, dbMode);
Database* db = ctx.getDb();
@@ -236,7 +236,7 @@ public:
if (collectionName.empty())
collectionName = "fs";
collectionName += ".chunks";
- return NamespaceString(dbName, collectionName);
+ return NamespaceStringUtil::parseNamespaceFromRequest(dbName, collectionName);
}
Status checkAuthForOperation(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/fail_point_cmd.cpp b/src/mongo/db/commands/fail_point_cmd.cpp
index a067522d6fe..04eda7ad215 100644
--- a/src/mongo/db/commands/fail_point_cmd.cpp
+++ b/src/mongo/db/commands/fail_point_cmd.cpp
@@ -144,7 +144,7 @@ public:
// The command parameter happens to be string so it's historically been interpreted
// by parseNs as a collection. Continuing to do so here for unexamined compatibility.
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
// No auth needed because it only works when enabled via command line.
diff --git a/src/mongo/db/commands/generic.cpp b/src/mongo/db/commands/generic.cpp
index 9bc1717f6e8..43ff09312ad 100644
--- a/src/mongo/db/commands/generic.cpp
+++ b/src/mongo/db/commands/generic.cpp
@@ -285,7 +285,7 @@ public:
}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/commands/generic_servers.cpp b/src/mongo/db/commands/generic_servers.cpp
index 46276bb285b..a565f4924f5 100644
--- a/src/mongo/db/commands/generic_servers.cpp
+++ b/src/mongo/db/commands/generic_servers.cpp
@@ -81,7 +81,7 @@ public:
}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/commands/get_cluster_parameter_command.cpp b/src/mongo/db/commands/get_cluster_parameter_command.cpp
index 40eca042887..2e11ef26363 100644
--- a/src/mongo/db/commands/get_cluster_parameter_command.cpp
+++ b/src/mongo/db/commands/get_cluster_parameter_command.cpp
@@ -96,7 +96,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
} getClusterParameterCommand;
diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp
index bb35a065a73..194f44a9092 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -322,7 +322,8 @@ public:
Invocation(Command* cmd, const OpMsgRequest& request)
: CommandInvocation(cmd),
_cmd(GetMoreCommandRequest::parse(IDLParserContext{"getMore"}, request)) {
- NamespaceString nss(_cmd.getDbName(), _cmd.getCollection());
+ NamespaceString nss(NamespaceStringUtil::parseNamespaceFromRequest(
+ _cmd.getDbName(), _cmd.getCollection()));
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "Invalid namespace for getMore: " << nss.ns(),
nss.isValid());
@@ -347,7 +348,8 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(_cmd.getDbName(), _cmd.getCollection());
+ return NamespaceStringUtil::parseNamespaceFromRequest(_cmd.getDbName(),
+ _cmd.getCollection());
}
void doCheckAuthorization(OperationContext* opCtx) const override {
@@ -481,7 +483,8 @@ public:
// the stats twice.
boost::optional<AutoGetCollectionForReadMaybeLockFree> readLock;
boost::optional<AutoStatsTracker> statsTracker;
- NamespaceString nss(_cmd.getDbName(), _cmd.getCollection());
+ NamespaceString nss(NamespaceStringUtil::parseNamespaceFromRequest(
+ _cmd.getDbName(), _cmd.getCollection()));
const bool disableAwaitDataFailpointActive =
MONGO_unlikely(disableAwaitDataForGetMoreCmd.shouldFail());
diff --git a/src/mongo/db/commands/http_client.cpp b/src/mongo/db/commands/http_client.cpp
index 7ff14d644c9..fe67aa7b889 100644
--- a/src/mongo/db/commands/http_client.cpp
+++ b/src/mongo/db/commands/http_client.cpp
@@ -127,7 +127,7 @@ public:
void doCheckAuthorization(OperationContext*) const final {}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/commands/killoperations_common.h b/src/mongo/db/commands/killoperations_common.h
index 22060c28d64..c4542e84857 100644
--- a/src/mongo/db/commands/killoperations_common.h
+++ b/src/mongo/db/commands/killoperations_common.h
@@ -70,7 +70,7 @@ public:
private:
NamespaceString ns() const override {
- return NamespaceString(Base::request().getDbName(), "");
+ return NamespaceString(Base::request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp
index 74895ba0322..d8c7ead1291 100644
--- a/src/mongo/db/commands/list_collections.cpp
+++ b/src/mongo/db/commands/list_collections.cpp
@@ -351,7 +351,8 @@ public:
if (DatabaseHolder::get(opCtx)->dbExists(opCtx, dbName)) {
if (auto collNames = _getExactNameMatches(matcher.get())) {
for (auto&& collName : *collNames) {
- auto nss = NamespaceString(dbName, collName);
+ auto nss =
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, collName);
// Only validate on a per-collection basis if the user requested
// a list of authorized collections
diff --git a/src/mongo/db/commands/list_databases.cpp b/src/mongo/db/commands/list_databases.cpp
index ecb4694e57d..3ad19b1d236 100644
--- a/src/mongo/db/commands/list_databases.cpp
+++ b/src/mongo/db/commands/list_databases.cpp
@@ -85,7 +85,7 @@ public:
void doCheckAuthorization(OperationContext*) const final {}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
ListDatabasesReply typedRun(OperationContext* opCtx) final {
diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp
index f0648835437..1ceae347f2e 100644
--- a/src/mongo/db/commands/list_indexes.cpp
+++ b/src/mongo/db/commands/list_indexes.cpp
@@ -233,7 +233,7 @@ public:
auto nss = request().getNamespaceOrUUID();
if (nss.uuid()) {
// UUID requires opCtx to resolve, settle on just the dbname.
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
invariant(nss.nss());
return nss.nss().value();
diff --git a/src/mongo/db/commands/profile_common.cpp b/src/mongo/db/commands/profile_common.cpp
index 94875fcbd70..6a33e66a561 100644
--- a/src/mongo/db/commands/profile_common.cpp
+++ b/src/mongo/db/commands/profile_common.cpp
@@ -56,7 +56,9 @@ Status ProfileCmdBase::checkAuthForOperation(OperationContext* opCtx,
// If the user just wants to view the current values of 'slowms' and 'sampleRate', they
// only need read rights on system.profile, even if they can't change the profiling level.
if (authzSession->isAuthorizedForActionsOnResource(
- ResourcePattern::forExactNamespace({dbName, "system.profile"}), ActionType::find)) {
+ ResourcePattern::forExactNamespace(
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, "system.profile")),
+ ActionType::find)) {
return Status::OK();
}
}
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp
index 7c4166b8bf3..5e14d4c6549 100644
--- a/src/mongo/db/commands/run_aggregate.cpp
+++ b/src/mongo/db/commands/run_aggregate.cpp
@@ -374,8 +374,8 @@ StatusWith<StringMap<ExpressionContext::ResolvedNamespace>> resolveInvolvedNames
// collection name references a view on the aggregation request's database. Note
// that the inverse scenario (mistaking a view for a collection) is not an issue
// because $merge/$out cannot target a view.
- auto nssToCheck =
- NamespaceString(request.getNamespace().dbName(), involvedNs.coll());
+ auto nssToCheck = NamespaceStringUtil::parseNamespaceFromRequest(
+ request.getNamespace().dbName(), involvedNs.coll());
if (catalog->lookupView(opCtx, nssToCheck)) {
auto status = resolveViewDefinition(nssToCheck);
if (!status.isOK()) {
diff --git a/src/mongo/db/commands/rwc_defaults_commands.cpp b/src/mongo/db/commands/rwc_defaults_commands.cpp
index 8e1f1cb16cc..1a39456b35c 100644
--- a/src/mongo/db/commands/rwc_defaults_commands.cpp
+++ b/src/mongo/db/commands/rwc_defaults_commands.cpp
@@ -167,7 +167,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
} setDefaultRWConcernCommand;
@@ -219,7 +219,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
} getDefaultRWConcernCommand;
diff --git a/src/mongo/db/commands/shutdown.h b/src/mongo/db/commands/shutdown.h
index 446c78632e0..373eb4a007e 100644
--- a/src/mongo/db/commands/shutdown.h
+++ b/src/mongo/db/commands/shutdown.h
@@ -86,7 +86,7 @@ public:
private:
NamespaceString ns() const override {
- return NamespaceString(Base::request().getDbName(), "");
+ return NamespaceString(Base::request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/commands/tenant_migration_donor_cmds.cpp b/src/mongo/db/commands/tenant_migration_donor_cmds.cpp
index c1b73eb3ac8..ddd1dc50afa 100644
--- a/src/mongo/db/commands/tenant_migration_donor_cmds.cpp
+++ b/src/mongo/db/commands/tenant_migration_donor_cmds.cpp
@@ -150,7 +150,7 @@ public:
return false;
}
NamespaceString ns() const {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -225,7 +225,7 @@ public:
return false;
}
NamespaceString ns() const {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -309,7 +309,7 @@ public:
return false;
}
NamespaceString ns() const {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp b/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp
index ff7c94df325..684d9c35624 100644
--- a/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp
+++ b/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp
@@ -181,7 +181,7 @@ public:
return false;
}
NamespaceString ns() const {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -248,7 +248,7 @@ public:
private:
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
@@ -404,7 +404,7 @@ public:
}
NamespaceString ns() const {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/commands/traffic_recording_cmds.cpp b/src/mongo/db/commands/traffic_recording_cmds.cpp
index 143175c7301..b82157eb082 100644
--- a/src/mongo/db/commands/traffic_recording_cmds.cpp
+++ b/src/mongo/db/commands/traffic_recording_cmds.cpp
@@ -75,7 +75,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -110,7 +110,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp
index 233c9772a46..3741db51431 100644
--- a/src/mongo/db/commands/user_management_commands.cpp
+++ b/src/mongo/db/commands/user_management_commands.cpp
@@ -225,7 +225,7 @@ Status checkOkayToGrantPrivilegesToRole(const RoleName& role, const PrivilegeVec
NamespaceString usersNSS(const boost::optional<TenantId>& tenant) {
if (tenant) {
- return NamespaceString(tenant, DatabaseName::kAdmin.db(), NamespaceString::kSystemUsers);
+ return NamespaceString::makeTenantUsersCollection(tenant);
} else {
return NamespaceString::kAdminUsersNamespace;
}
@@ -233,7 +233,7 @@ NamespaceString usersNSS(const boost::optional<TenantId>& tenant) {
NamespaceString rolesNSS(const boost::optional<TenantId>& tenant) {
if (tenant) {
- return NamespaceString(tenant, DatabaseName::kAdmin.db(), NamespaceString::kSystemRoles);
+ return NamespaceString::makeTenantRolesCollection(tenant);
} else {
return NamespaceString::kAdminRolesNamespace;
}
@@ -961,9 +961,10 @@ public:
NamespaceString ns() const final {
const auto& cmd = request();
if constexpr (hasGetCmdParamStringData<RequestT>) {
- return NamespaceString(cmd.getDbName(), cmd.getCommandParameter());
+ return NamespaceStringUtil::parseNamespaceFromRequest(cmd.getDbName(),
+ cmd.getCommandParameter());
}
- return NamespaceString(cmd.getDbName(), "");
+ return NamespaceString(cmd.getDbName());
}
};
@@ -2138,7 +2139,7 @@ public:
}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/commands/validate_db_metadata_cmd.cpp b/src/mongo/db/commands/validate_db_metadata_cmd.cpp
index 785236f2e5b..ea4a72feb8d 100644
--- a/src/mongo/db/commands/validate_db_metadata_cmd.cpp
+++ b/src/mongo/db/commands/validate_db_metadata_cmd.cpp
@@ -134,8 +134,9 @@ public:
}
if (validateCmdRequest.getCollection()) {
- if (!_validateNamespace(
- opCtx, NamespaceString(dbName, *validateCmdRequest.getCollection()))) {
+ if (!_validateNamespace(opCtx,
+ NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName, *validateCmdRequest.getCollection()))) {
return;
}
continue;
diff --git a/src/mongo/db/commands/vote_abort_index_build_command.cpp b/src/mongo/db/commands/vote_abort_index_build_command.cpp
index e5577f60da8..c5e76436073 100644
--- a/src/mongo/db/commands/vote_abort_index_build_command.cpp
+++ b/src/mongo/db/commands/vote_abort_index_build_command.cpp
@@ -104,7 +104,7 @@ public:
private:
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/commands/vote_commit_index_build_command.cpp b/src/mongo/db/commands/vote_commit_index_build_command.cpp
index 475d23dddf1..2deaa460163 100644
--- a/src/mongo/db/commands/vote_commit_index_build_command.cpp
+++ b/src/mongo/db/commands/vote_commit_index_build_command.cpp
@@ -103,7 +103,7 @@ public:
private:
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp
index 8c909acffdf..d6d167893ae 100644
--- a/src/mongo/db/exec/stagedebug_cmd.cpp
+++ b/src/mongo/db/exec/stagedebug_cmd.cpp
@@ -140,7 +140,8 @@ public:
return false;
}
- const NamespaceString nss(dbName, collElt.String());
+ const NamespaceString nss(
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, collElt.String()));
uassert(ErrorCodes::InvalidNamespace,
str::stream() << nss.toString() << " is not a valid namespace",
nss.isValid());
diff --git a/src/mongo/db/fle_crud.cpp b/src/mongo/db/fle_crud.cpp
index 885a8e60b6d..b5f93148306 100644
--- a/src/mongo/db/fle_crud.cpp
+++ b/src/mongo/db/fle_crud.cpp
@@ -614,7 +614,8 @@ void processFieldsForInsertV1(FLEQueryInterface* queryImpl,
int32_t* pStmtId,
bool bypassDocumentValidation) {
- const NamespaceString nssEsc(edcNss.dbName(), efc.getEscCollection().value());
+ const NamespaceString nssEsc = NamespaceStringUtil::parseNamespaceFromRequest(
+ edcNss.dbName(), efc.getEscCollection().value());
auto docCount = queryImpl->countDocuments(nssEsc);
@@ -676,7 +677,8 @@ void processFieldsForInsertV1(FLEQueryInterface* queryImpl,
checkWriteErrors(escInsertReply);
- const NamespaceString nssEcoc(edcNss.dbName(), efc.getEcocCollection().value());
+ const NamespaceString nssEcoc = NamespaceStringUtil::parseNamespaceFromRequest(
+ edcNss.dbName(), efc.getEcocCollection().value());
// TODO - should we make this a batch of ECOC updates?
const auto ecocInsertReply = uassertStatusOK(queryImpl->insertDocuments(
@@ -708,12 +710,12 @@ void processFieldsForInsertV2(FLEQueryInterface* queryImpl,
const EncryptedFieldConfig& efc,
int32_t* pStmtId,
bool bypassDocumentValidation) {
-
if (serverPayload.empty()) {
return;
}
- const NamespaceString nssEsc(edcNss.dbName(), efc.getEscCollection().value());
+ const NamespaceString nssEsc = NamespaceStringUtil::parseNamespaceFromRequest(
+ edcNss.dbName(), efc.getEscCollection().value());
uint32_t totalTokens = 0;
@@ -775,7 +777,8 @@ void processFieldsForInsertV2(FLEQueryInterface* queryImpl,
uassertStatusOK(queryImpl->insertDocuments(nssEsc, escDocuments, pStmtId, true));
checkWriteErrors(escInsertReply);
- NamespaceString nssEcoc(edcNss.dbName(), efc.getEcocCollection().value());
+ NamespaceString nssEcoc = NamespaceStringUtil::parseNamespaceFromRequest(
+ edcNss.dbName(), efc.getEcocCollection().value());
std::vector<BSONObj> ecocDocuments;
ecocDocuments.reserve(totalTokens);
@@ -864,7 +867,8 @@ void processRemovedFieldsHelper(FLEQueryInterface* queryImpl,
true));
checkWriteErrors(eccInsertReply);
- const NamespaceString nssEcoc(edcNss.dbName(), efc.getEcocCollection().value());
+ const NamespaceString nssEcoc = NamespaceStringUtil::parseNamespaceFromRequest(
+ edcNss.dbName(), efc.getEcocCollection().value());
// TODO - make this a batch of ECOC updates?
EncryptedStateCollectionTokens tokens(esc, ecc);
@@ -884,7 +888,8 @@ void processRemovedFields(FLEQueryInterface* queryImpl,
const std::vector<EDCIndexedFields>& deletedFields,
int32_t* pStmtId) {
- const NamespaceString eccNss(edcNss.dbName(), efc.getEccCollection().value());
+ const NamespaceString eccNss = NamespaceStringUtil::parseNamespaceFromRequest(
+ edcNss.dbName(), efc.getEccCollection().value());
auto docCount = queryImpl->countDocuments(eccNss);
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index 3d236fe7524..6e9cf7bfbfe 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -112,8 +112,7 @@ void profile(OperationContext* opCtx, NetworkOp op) {
opCtx->getClient()->swapLockState(std::move(oldCtxLocker));
});
AlternativeClientRegion acr(newClient);
- const auto dbProfilingNS =
- NamespaceString(ns.dbName(), NamespaceString::kSystemDotProfileCollectionName);
+ const auto dbProfilingNS = NamespaceString::makeSystemDotProfileNamespace(ns.dbName());
AutoGetCollection autoColl(newCtx.get(), dbProfilingNS, MODE_IX);
Database* const db = autoColl.getDb();
if (!db) {
@@ -149,8 +148,7 @@ void profile(OperationContext* opCtx, NetworkOp op) {
Status createProfileCollection(OperationContext* opCtx, Database* db) {
invariant(opCtx->lockState()->isDbLockedForMode(db->name(), MODE_IX));
- const auto dbProfilingNS =
- NamespaceString(db->name(), NamespaceString::kSystemDotProfileCollectionName);
+ const auto dbProfilingNS = NamespaceString::makeSystemDotProfileNamespace(db->name());
// Checking the collection exists must also be done in the WCE retry loop. Only retrying
// collection creation would endlessly throw errors because the collection exists: must check
diff --git a/src/mongo/db/namespace_string.cpp b/src/mongo/db/namespace_string.cpp
index 3fd5a88f4cc..157e02cb3c6 100644
--- a/src/mongo/db/namespace_string.cpp
+++ b/src/mongo/db/namespace_string.cpp
@@ -189,6 +189,10 @@ NamespaceString NamespaceString::makeSystemDotViewsNamespace(const DatabaseName&
return NamespaceString(dbName, kSystemDotViewsCollectionName);
}
+NamespaceString NamespaceString::makeSystemDotProfileNamespace(const DatabaseName& dbName) {
+ return NamespaceString(dbName, kSystemDotProfileCollectionName);
+}
+
NamespaceString NamespaceString::makeListCollectionsNSS(const DatabaseName& dbName) {
NamespaceString nss(dbName, listCollectionsCursorCol);
dassert(nss.isValid());
@@ -200,6 +204,10 @@ NamespaceString NamespaceString::makeGlobalConfigCollection(StringData collName)
return NamespaceString(DatabaseName::kConfig, collName);
}
+NamespaceString NamespaceString::makeLocalCollection(StringData collName) {
+ return NamespaceString(DatabaseName::kLocal, collName);
+}
+
NamespaceString NamespaceString::makeCollectionlessAggregateNSS(const DatabaseName& dbName) {
NamespaceString nss(dbName, collectionlessAggregateCursorCol);
dassert(nss.isValid());
@@ -241,11 +249,24 @@ NamespaceString NamespaceString::makeReshardingLocalConflictStashNSS(
donorShardId);
}
+NamespaceString NamespaceString::makeTenantUsersCollection(
+ const boost::optional<TenantId>& tenantId) {
+ return NamespaceString(tenantId, DatabaseName::kAdmin.db(), NamespaceString::kSystemUsers);
+}
+
+NamespaceString NamespaceString::makeTenantRolesCollection(
+ const boost::optional<TenantId>& tenantId) {
+ return NamespaceString(tenantId, DatabaseName::kAdmin.db(), NamespaceString::kSystemRoles);
+}
+
+NamespaceString NamespaceString::makeCommandNamespace(const DatabaseName& dbName) {
+ return NamespaceString(dbName, "$cmd");
+}
+
NamespaceString NamespaceString::makeDummyNamespace(const boost::optional<TenantId>& tenantId) {
return NamespaceString(tenantId, DatabaseName::kConfig.db(), "dummy.namespace");
}
-
std::string NamespaceString::getSisterNS(StringData local) const {
verify(local.size() && local[0] != '.');
return db().toString() + "." + local.toString();
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index 2acb9d556fb..06a40dc1b44 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -47,6 +47,8 @@
#include "mongo/util/uuid.h"
namespace mongo {
+class NamespaceStringUtil;
+class IDLParserContext;
class NamespaceString {
public:
@@ -208,23 +210,6 @@ public:
NamespaceString() = default;
/**
- * Constructs a NamespaceString from the fully qualified namespace named in "ns" and the
- * tenantId. "ns" is NOT expected to contain the tenantId.
- */
- explicit NamespaceString(boost::optional<TenantId> tenantId, StringData ns) {
- _dotIndex = ns.find(".");
-
- uassert(ErrorCodes::InvalidNamespace,
- "namespaces cannot have embedded null characters",
- ns.find('\0') == std::string::npos);
-
- StringData db = ns.substr(0, _dotIndex);
- _dbName = DatabaseName(std::move(tenantId), db);
- _ns = ns.toString();
- }
-
-
- /**
* Constructs a NamespaceString for the given database.
*/
explicit NamespaceString(DatabaseName dbName) : _dbName(std::move(dbName)), _ns(_dbName.db()) {}
@@ -234,37 +219,6 @@ public:
explicit NamespaceString(StringData ns, boost::optional<TenantId> tenantId = boost::none)
: NamespaceString(std::move(tenantId), ns) {}
- /**
- * Constructs a NamespaceString for the given database and collection names.
- * "dbName" must not contain a ".", and "collectionName" must not start with one.
- */
- NamespaceString(DatabaseName dbName, StringData collectionName)
- : _dbName(std::move(dbName)), _ns(str::stream() << _dbName.db() << '.' << collectionName) {
- const auto& db = _dbName.db();
-
- uassert(ErrorCodes::InvalidNamespace,
- "'.' is an invalid character in the database name: " + db,
- db.find('.') == std::string::npos);
- uassert(ErrorCodes::InvalidNamespace,
- "Collection names cannot start with '.': " + collectionName,
- collectionName.empty() || collectionName[0] != '.');
-
- _dotIndex = db.size();
- dassert(_ns[_dotIndex] == '.');
-
- uassert(ErrorCodes::InvalidNamespace,
- "namespaces cannot have embedded null characters",
- _ns.find('\0') == std::string::npos);
- }
-
- /**
- * Constructs a NamespaceString for the given db name, collection name, and tenantId.
- * "db" must not contain a ".", and "collectionName" must not start with one. "dbName" is
- * NOT expected to contain a tenantId.
- */
- NamespaceString(boost::optional<TenantId> tenantId, StringData db, StringData collectionName)
- : NamespaceString(DatabaseName(std::move(tenantId), db), collectionName) {}
-
// TODO SERVER-65920 Remove this constructor once all constructor call sites have been updated
// to pass tenantId explicitly
NamespaceString(StringData db,
@@ -286,6 +240,11 @@ public:
static NamespaceString makeGlobalConfigCollection(StringData collName);
/**
+ * Constructs a NamespaceString in the local db, "local.<collName>".
+ */
+ static NamespaceString makeLocalCollection(StringData collName);
+
+ /**
* These functions construct a NamespaceString without checking for presence of TenantId.
*
* MUST only be used for tests.
@@ -319,6 +278,24 @@ public:
}
/**
+ * These functions construct a NamespaceString without checking for presence of TenantId. These
+ * must only be used by auth systems which are not yet tenant aware.
+ *
+ * TODO SERVER-74896 Remove this function. Any remaining call sites must be changed to use a
+ * function on NamespaceStringUtil.
+ */
+ static NamespaceString createNamespaceStringForAuth(const boost::optional<TenantId>& tenantId,
+ StringData db,
+ StringData coll) {
+ return NamespaceString(tenantId, db, coll);
+ }
+
+ static NamespaceString createNamespaceStringForAuth(const boost::optional<TenantId>& tenantId,
+ StringData ns) {
+ return NamespaceString(tenantId, ns);
+ }
+
+ /**
* Constructs the namespace '<dbName>.$cmd.aggregate', which we use as the namespace for
* aggregation commands with the format {aggregate: 1}.
*/
@@ -358,6 +335,11 @@ public:
static NamespaceString makeSystemDotViewsNamespace(const DatabaseName& dbName);
/**
+ * Constructs the system.profile NamespaceString for the specified DatabaseName.
+ */
+ static NamespaceString makeSystemDotProfileNamespace(const DatabaseName& dbName);
+
+ /**
* Constructs a NamespaceString representing a BulkWrite namespace. The format for this
* namespace is admin.$cmd.bulkWrite".
*/
@@ -381,6 +363,23 @@ public:
const std::string& donorShardId);
/**
+ * Constructs the tenant-specific admin.system.users NamespaceString for the given tenant,
+ * "tenant_admin.system.users".
+ */
+ static NamespaceString makeTenantUsersCollection(const boost::optional<TenantId>& tenantId);
+
+ /**
+ * Constructs the tenant-specific admin.system.roles NamespaceString for the given tenant,
+ * "tenant_admin.system.roles".
+ */
+ static NamespaceString makeTenantRolesCollection(const boost::optional<TenantId>& tenantId);
+
+ /**
+ * Constructs the command NamespaceString, "<dbName>.$cmd".
+ */
+ static NamespaceString makeCommandNamespace(const DatabaseName& dbName);
+
+ /**
* Constructs a dummy NamespaceString, "<tenantId>.config.dummy.namespace", to be used where a
* placeholder NamespaceString is needed. It must be acceptable for tenantId to be empty, so we
* use "config" as the db.
@@ -468,6 +467,10 @@ public:
bool isSystemDotViews() const {
return coll() == kSystemDotViewsCollectionName;
}
+ static bool resolvesToSystemDotViews(StringData ns) {
+ auto nss = NamespaceString(boost::none, ns);
+ return nss.isSystemDotViews();
+ }
bool isSystemDotJavascript() const {
return coll() == kSystemDotJavascriptCollectionName;
}
@@ -768,6 +771,64 @@ public:
}
private:
+ friend NamespaceStringUtil;
+ // TODO SERVER-74897 IDLParserContext should no longer be a friend once IDL generated commands
+ // call into NamespaceStringUtil directly to construct NamespaceStrings.
+ friend IDLParserContext;
+
+ /**
+ * In order to construct NamespaceString objects, use NamespaceStringUtil. The functions
+ * on NamespaceStringUtil make assertions necessary when running in Serverless.
+ */
+
+ /**
+ * Constructs a NamespaceString from the fully qualified namespace named in "ns" and the
+ * tenantId. "ns" is NOT expected to contain the tenantId.
+ */
+ explicit NamespaceString(boost::optional<TenantId> tenantId, StringData ns) {
+ _dotIndex = ns.find(".");
+
+ uassert(ErrorCodes::InvalidNamespace,
+ "namespaces cannot have embedded null characters",
+ ns.find('\0') == std::string::npos);
+
+ StringData db = ns.substr(0, _dotIndex);
+ _dbName = DatabaseName(std::move(tenantId), db);
+ _ns = ns.toString();
+ }
+
+ /**
+ * Constructs a NamespaceString for the given database and collection names.
+ * "dbName" must not contain a ".", and "collectionName" must not start with one.
+ */
+ NamespaceString(DatabaseName dbName, StringData collectionName)
+ : _dbName(std::move(dbName)), _ns(str::stream() << _dbName.db() << '.' << collectionName) {
+ const auto& db = _dbName.db();
+
+ uassert(ErrorCodes::InvalidNamespace,
+ "'.' is an invalid character in the database name: " + db,
+ db.find('.') == std::string::npos);
+ uassert(ErrorCodes::InvalidNamespace,
+ "Collection names cannot start with '.': " + collectionName,
+ collectionName.empty() || collectionName[0] != '.');
+
+ _dotIndex = db.size();
+ dassert(_ns[_dotIndex] == '.');
+
+ uassert(ErrorCodes::InvalidNamespace,
+ "namespaces cannot have embedded null characters",
+ _ns.find('\0') == std::string::npos);
+ }
+
+ /**
+ * Constructs a NamespaceString for the given db name, collection name, and tenantId.
+ * "db" must not contain a ".", and "collectionName" must not start with one. "db" is
+ * NOT expected to contain a tenantId.
+ */
+ NamespaceString(boost::optional<TenantId> tenantId, StringData db, StringData collectionName)
+ : NamespaceString(DatabaseName(std::move(tenantId), db), collectionName) {}
+
+
std::tuple<const boost::optional<TenantId>&, const std::string&> _lens() const {
return std::tie(tenantId(), ns());
}
diff --git a/src/mongo/db/namespace_string_test.cpp b/src/mongo/db/namespace_string_test.cpp
index 231c14f6083..0d8e25255d4 100644
--- a/src/mongo/db/namespace_string_test.cpp
+++ b/src/mongo/db/namespace_string_test.cpp
@@ -375,21 +375,32 @@ TEST(NamespaceStringTest, CompareNSSWithTenantId) {
TenantId tenantIdMin(OID("000000000000000000000000"));
TenantId tenantIdMax(OID::max());
- ASSERT(NamespaceString(tenantIdMin, "foo.bar") == NamespaceString(tenantIdMin, "foo.bar"));
-
- ASSERT(NamespaceString(tenantIdMin, "foo.bar") != NamespaceString(tenantIdMax, "foo.bar"));
- ASSERT(NamespaceString(tenantIdMin, "foo.bar") != NamespaceString(tenantIdMin, "zoo.bar"));
-
- ASSERT(NamespaceString(tenantIdMin, "foo.bar") < NamespaceString(tenantIdMax, "foo.bar"));
- ASSERT(NamespaceString(tenantIdMin, "foo.bar") < NamespaceString(tenantIdMin, "zoo.bar"));
- ASSERT(NamespaceString(tenantIdMin, "zoo.bar") < NamespaceString(tenantIdMax, "foo.bar"));
-
- ASSERT(NamespaceString(tenantIdMax, "foo.bar") > NamespaceString(tenantIdMin, "foo.bar"));
- ASSERT(NamespaceString(tenantIdMin, "zoo.bar") > NamespaceString(tenantIdMin, "foo.bar"));
- ASSERT(NamespaceString(tenantIdMax, "foo.bar") > NamespaceString(tenantIdMin, "zoo.bar"));
-
- ASSERT(NamespaceString(tenantIdMin, "foo.bar") <= NamespaceString(tenantIdMin, "foo.bar"));
- ASSERT(NamespaceString(tenantIdMin, "foo.bar") >= NamespaceString(tenantIdMin, "foo.bar"));
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar") ==
+ NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar"));
+
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar") !=
+ NamespaceString::createNamespaceString_forTest(tenantIdMax, "foo.bar"));
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar") !=
+ NamespaceString::createNamespaceString_forTest(tenantIdMin, "zoo.bar"));
+
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar") <
+ NamespaceString::createNamespaceString_forTest(tenantIdMax, "foo.bar"));
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar") <
+ NamespaceString::createNamespaceString_forTest(tenantIdMin, "zoo.bar"));
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "zoo.bar") <
+ NamespaceString::createNamespaceString_forTest(tenantIdMax, "foo.bar"));
+
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMax, "foo.bar") >
+ NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar"));
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "zoo.bar") >
+ NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar"));
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMax, "foo.bar") >
+ NamespaceString::createNamespaceString_forTest(tenantIdMin, "zoo.bar"));
+
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar") <=
+ NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar"));
+ ASSERT(NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar") >=
+ NamespaceString::createNamespaceString_forTest(tenantIdMin, "foo.bar"));
}
} // namespace
diff --git a/src/mongo/db/op_observer/op_observer_impl.cpp b/src/mongo/db/op_observer/op_observer_impl.cpp
index f9c4cf02b2e..9e242aee14a 100644
--- a/src/mongo/db/op_observer/op_observer_impl.cpp
+++ b/src/mongo/db/op_observer/op_observer_impl.cpp
@@ -691,7 +691,8 @@ void OpObserverImpl::onInserts(OperationContext* opCtx,
opCtx,
NamespaceStringUtil::deserialize(nss.dbName().tenantId(),
it->doc.getStringField("_id")),
- {nss.dbName(), it->doc.getStringField("viewOn")},
+ NamespaceStringUtil::parseNamespaceFromDoc(nss.dbName(),
+ it->doc.getStringField("viewOn")),
BSONArray{it->doc.getObjectField("pipeline")},
view_catalog_helpers::validatePipeline,
it->doc.getObjectField("collation"),
@@ -1282,7 +1283,7 @@ void OpObserverImpl::onDropDatabase(OperationContext* opCtx, const DatabaseName&
oplogEntry.setOpType(repl::OpTypeEnum::kCommand);
oplogEntry.setTid(dbName.tenantId());
- oplogEntry.setNss({dbName, "$cmd"});
+ oplogEntry.setNss(NamespaceString::makeCommandNamespace(dbName));
oplogEntry.setObject(BSON("dropDatabase" << 1));
auto opTime =
logOperation(opCtx, &oplogEntry, true /*assignWallClockTime*/, _oplogWriter.get());
@@ -1538,7 +1539,7 @@ void OpObserverImpl::onApplyOps(OperationContext* opCtx,
oplogEntry.setOpType(repl::OpTypeEnum::kCommand);
oplogEntry.setTid(dbName.tenantId());
- oplogEntry.setNss({dbName, "$cmd"});
+ oplogEntry.setNss(NamespaceString::makeCommandNamespace(dbName));
oplogEntry.setObject(applyOpCmd);
logOperation(opCtx, &oplogEntry, true /*assignWallClockTime*/, _oplogWriter.get());
}
diff --git a/src/mongo/db/op_observer/op_observer_impl_test.cpp b/src/mongo/db/op_observer/op_observer_impl_test.cpp
index 64a636974d4..f9d12984f34 100644
--- a/src/mongo/db/op_observer/op_observer_impl_test.cpp
+++ b/src/mongo/db/op_observer/op_observer_impl_test.cpp
@@ -348,7 +348,8 @@ protected:
const UUID uuid3{UUID::gen()};
const TenantId kTenantId = TenantId(OID::gen());
- const NamespaceString kNssUnderTenantId{boost::none, kTenantId.toString() + "_db", "testColl"};
+ const NamespaceString kNssUnderTenantId = NamespaceString::createNamespaceString_forTest(
+ boost::none, kTenantId.toString() + "_db", "testColl");
const UUID kNssUnderTenantIdUUID{UUID::gen()};
ReadWriteConcernDefaultsLookupMock _lookupMock;
diff --git a/src/mongo/db/op_observer/user_write_block_mode_op_observer.cpp b/src/mongo/db/op_observer/user_write_block_mode_op_observer.cpp
index 6330d195585..d9158099dca 100644
--- a/src/mongo/db/op_observer/user_write_block_mode_op_observer.cpp
+++ b/src/mongo/db/op_observer/user_write_block_mode_op_observer.cpp
@@ -223,7 +223,7 @@ void UserWriteBlockModeOpObserver::onCollMod(OperationContext* opCtx,
void UserWriteBlockModeOpObserver::onDropDatabase(OperationContext* opCtx,
const DatabaseName& dbName) {
- _checkWriteAllowed(opCtx, NamespaceString(dbName, ""));
+ _checkWriteAllowed(opCtx, NamespaceString(dbName));
}
repl::OpTime UserWriteBlockModeOpObserver::onDropCollection(OperationContext* opCtx,
diff --git a/src/mongo/db/pipeline/aggregation_request_helper.cpp b/src/mongo/db/pipeline/aggregation_request_helper.cpp
index 29a5fe90cd8..43d0c0491a7 100644
--- a/src/mongo/db/pipeline/aggregation_request_helper.cpp
+++ b/src/mongo/db/pipeline/aggregation_request_helper.cpp
@@ -136,7 +136,8 @@ NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) {
<< typeName(firstElement.type()),
firstElement.type() == BSONType::String);
- const NamespaceString nss(dbName, firstElement.valueStringData());
+ const NamespaceString nss(
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, firstElement.valueStringData()));
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "Invalid namespace specified '" << nss.ns() << "'",
diff --git a/src/mongo/db/pipeline/change_stream_event_transform.cpp b/src/mongo/db/pipeline/change_stream_event_transform.cpp
index 9a54ec6b042..df965830b9d 100644
--- a/src/mongo/db/pipeline/change_stream_event_transform.cpp
+++ b/src/mongo/db/pipeline/change_stream_event_transform.cpp
@@ -243,7 +243,8 @@ Document ChangeStreamDefaultEventTransformation::applyTransformation(const Docum
operationType = DocumentSourceChangeStream::kDropCollectionOpType;
// The "o.drop" field will contain the actual collection name.
- nss = NamespaceString(nss.dbName(), nssField.getStringData());
+ nss = NamespaceStringUtil::parseNamespaceFromDoc(nss.dbName(),
+ nssField.getStringData());
} else if (auto nssField = oField.getField("renameCollection"); !nssField.missing()) {
operationType = DocumentSourceChangeStream::kRenameCollectionOpType;
@@ -270,32 +271,37 @@ Document ChangeStreamDefaultEventTransformation::applyTransformation(const Docum
// Extract the database name from the namespace field and leave the collection name
// empty.
- nss = NamespaceString(nss.tenantId(), nss.dbName().db());
+ nss = NamespaceString(nss.dbName());
} else if (auto nssField = oField.getField("create"); !nssField.missing()) {
operationType = DocumentSourceChangeStream::kCreateOpType;
- nss = NamespaceString(nss.dbName(), nssField.getStringData());
+ nss = NamespaceStringUtil::parseNamespaceFromDoc(nss.dbName(),
+ nssField.getStringData());
operationDescription = Value(copyDocExceptFields(oField, {"create"_sd}));
} else if (auto nssField = oField.getField("createIndexes"); !nssField.missing()) {
operationType = DocumentSourceChangeStream::kCreateIndexesOpType;
- nss = NamespaceString(nss.dbName(), nssField.getStringData());
+ nss = NamespaceStringUtil::parseNamespaceFromDoc(nss.dbName(),
+ nssField.getStringData());
// Wrap the index spec in an "indexes" array for consistency with commitIndexBuild.
auto indexSpec = Value(copyDocExceptFields(oField, {"createIndexes"_sd}));
operationDescription = Value(Document{{"indexes", std::vector<Value>{indexSpec}}});
} else if (auto nssField = oField.getField("commitIndexBuild"); !nssField.missing()) {
operationType = DocumentSourceChangeStream::kCreateIndexesOpType;
- nss = NamespaceString(nss.dbName(), nssField.getStringData());
+ nss = NamespaceStringUtil::parseNamespaceFromDoc(nss.dbName(),
+ nssField.getStringData());
operationDescription = Value(Document{{"indexes", oField.getField("indexes")}});
} else if (auto nssField = oField.getField("dropIndexes"); !nssField.missing()) {
const auto o2Field = input[repl::OplogEntry::kObject2FieldName].getDocument();
operationType = DocumentSourceChangeStream::kDropIndexesOpType;
- nss = NamespaceString(nss.dbName(), nssField.getStringData());
+ nss = NamespaceStringUtil::parseNamespaceFromDoc(nss.dbName(),
+ nssField.getStringData());
// Wrap the index spec in an "indexes" array for consistency with createIndexes
// and commitIndexBuild.
auto indexSpec = Value(copyDocExceptFields(o2Field, {"dropIndexes"_sd}));
operationDescription = Value(Document{{"indexes", std::vector<Value>{indexSpec}}});
} else if (auto nssField = oField.getField("collMod"); !nssField.missing()) {
operationType = DocumentSourceChangeStream::kModifyOpType;
- nss = NamespaceString(nss.dbName(), nssField.getStringData());
+ nss = NamespaceStringUtil::parseNamespaceFromDoc(nss.dbName(),
+ nssField.getStringData());
operationDescription = Value(copyDocExceptFields(oField, {"collMod"_sd}));
const auto o2Field = input[repl::OplogEntry::kObject2FieldName].getDocument();
@@ -552,13 +558,14 @@ ChangeStreamEventTransformer::ChangeStreamEventTransformer(
ChangeStreamEventTransformation* ChangeStreamEventTransformer::getBuilder(
const Document& oplog) const {
- // 'nss' is only used here determine which type of transformation to use. This is not dependent
- // on the tenantId, so it is safe to ignore the tenantId in the oplog entry. It is useful to
- // avoid extracting the tenantId because we must make this determination for every change stream
- // event, and the check should therefore be as optimized as possible.
- auto nss = NamespaceString(boost::none, oplog[repl::OplogEntry::kNssFieldName].getStringData());
-
- if (!_isSingleCollStream && nss.isSystemDotViews()) {
+ // The nss from the entry is only used here determine which type of transformation to use. This
+ // is not dependent on the tenantId, so it is safe to ignore the tenantId in the oplog entry.
+ // It is useful to avoid extracting the tenantId because we must make this determination for
+ // every change stream event, and the check should therefore be as optimized as possible.
+
+ if (!_isSingleCollStream &&
+ NamespaceString::resolvesToSystemDotViews(
+ oplog[repl::OplogEntry::kNssFieldName].getStringData())) {
return _viewNsEventBuilder.get();
}
return _defaultEventBuilder.get();
diff --git a/src/mongo/db/pipeline/change_stream_test_helpers.h b/src/mongo/db/pipeline/change_stream_test_helpers.h
index 9e472042a25..a1bc916d2a0 100644
--- a/src/mongo/db/pipeline/change_stream_test_helpers.h
+++ b/src/mongo/db/pipeline/change_stream_test_helpers.h
@@ -42,7 +42,8 @@
namespace mongo::change_stream_test_helper {
static const Timestamp kDefaultTs(100, 1);
static const repl::OpTime kDefaultOpTime(kDefaultTs, 1);
-static const NamespaceString nss(boost::none, "unittests.change_stream");
+static const NamespaceString nss =
+ NamespaceString::createNamespaceString_forTest(boost::none, "unittests.change_stream");
static const BSONObj kDefaultSpec = fromjson("{$changeStream: {}}");
static const BSONObj kShowExpandedEventsSpec =
fromjson("{$changeStream: {showExpandedEvents: true}}");
diff --git a/src/mongo/db/pipeline/document_source_change_stream_add_post_image.cpp b/src/mongo/db/pipeline/document_source_change_stream_add_post_image.cpp
index f6e655ea79e..217518bc20e 100644
--- a/src/mongo/db/pipeline/document_source_change_stream_add_post_image.cpp
+++ b/src/mongo/db/pipeline/document_source_change_stream_add_post_image.cpp
@@ -112,7 +112,8 @@ NamespaceString DocumentSourceChangeStreamAddPostImage::assertValidNamespace(
.getDocument();
auto dbName = assertFieldHasType(namespaceObject, "db"_sd, BSONType::String);
auto collectionName = assertFieldHasType(namespaceObject, "coll"_sd, BSONType::String);
- NamespaceString nss(pExpCtx->ns.tenantId(), dbName.getString(), collectionName.getString());
+ NamespaceString nss(NamespaceStringUtil::parseNamespaceFromDoc(
+ pExpCtx->ns.tenantId(), dbName.getString(), collectionName.getString()));
// Change streams on an entire database only need to verify that the database names match. If
// the database is 'admin', then this is a cluster-wide $changeStream and we are permitted to
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup.cpp b/src/mongo/db/pipeline/document_source_graph_lookup.cpp
index f8a7244b03a..244939c2d61 100644
--- a/src/mongo/db/pipeline/document_source_graph_lookup.cpp
+++ b/src/mongo/db/pipeline/document_source_graph_lookup.cpp
@@ -71,7 +71,8 @@ NamespaceString parseGraphLookupFromAndResolveNamespace(const BSONElement& elem,
elem.type() == String || elem.type() == Object);
if (elem.type() == BSONType::String) {
- NamespaceString fromNss(defaultDb, elem.valueStringData());
+ NamespaceString fromNss(
+ NamespaceStringUtil::parseNamespaceFromRequest(defaultDb, elem.valueStringData()));
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "invalid $graphLookup namespace: " << fromNss.ns(),
fromNss.isValid());
@@ -82,8 +83,9 @@ NamespaceString parseGraphLookupFromAndResolveNamespace(const BSONElement& elem,
auto spec = NamespaceSpec::parse(
IDLParserContext{elem.fieldNameStringData(), false /* apiStrict */, defaultDb.tenantId()},
elem.embeddedObject());
- // TODO SERVER-62491 Use system tenantId to construct nss.
- auto nss = NamespaceString(spec.getDb().value_or(DatabaseName()), spec.getColl().value_or(""));
+
+ auto nss = NamespaceStringUtil::parseNamespaceFromRequest(spec.getDb().value_or(DatabaseName()),
+ spec.getColl().value_or(""));
uassert(ErrorCodes::FailedToParse,
str::stream()
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp b/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
index 9f571b8a26a..11938238198 100644
--- a/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
+++ b/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
@@ -892,7 +892,8 @@ TEST_F(DocumentSourceGraphLookupServerlessTest,
auto tenantId = expCtx->ns.tenantId();
ASSERT(tenantId);
- NamespaceString graphLookupNs(expCtx->ns.dbName(), "foo");
+ NamespaceString graphLookupNs(
+ NamespaceString::createNamespaceString_forTest(expCtx->ns.dbName(), "foo"));
expCtx->setResolvedNamespaces(StringMap<ExpressionContext::ResolvedNamespace>{
{graphLookupNs.coll().toString(), {graphLookupNs, std::vector<BSONObj>()}}});
diff --git a/src/mongo/db/pipeline/document_source_lookup.cpp b/src/mongo/db/pipeline/document_source_lookup.cpp
index 9dee46e0326..976ce9c78e5 100644
--- a/src/mongo/db/pipeline/document_source_lookup.cpp
+++ b/src/mongo/db/pipeline/document_source_lookup.cpp
@@ -105,15 +105,15 @@ NamespaceString parseLookupFromAndResolveNamespace(const BSONElement& elem,
elem.type() == BSONType::String || elem.type() == BSONType::Object);
if (elem.type() == BSONType::String) {
- return NamespaceString(defaultDb, elem.valueStringData());
+ return NamespaceStringUtil::parseNamespaceFromRequest(defaultDb, elem.valueStringData());
}
// Valdate the db and coll names.
auto spec = NamespaceSpec::parse(
IDLParserContext{elem.fieldNameStringData(), false /* apiStrict */, defaultDb.tenantId()},
elem.embeddedObject());
- // TODO SERVER-62491 Use system tenantId to construct nss if running in serverless.
- auto nss = NamespaceString(spec.getDb().value_or(DatabaseName()), spec.getColl().value_or(""));
+ auto nss = NamespaceStringUtil::parseNamespaceFromRequest(spec.getDb().value_or(DatabaseName()),
+ spec.getColl().value_or(""));
uassert(
ErrorCodes::FailedToParse,
str::stream() << "$lookup with syntax {from: {db:<>, coll:<>},..} is not supported for db: "
diff --git a/src/mongo/db/pipeline/document_source_merge.cpp b/src/mongo/db/pipeline/document_source_merge.cpp
index 48052af235f..00b033a5b34 100644
--- a/src/mongo/db/pipeline/document_source_merge.cpp
+++ b/src/mongo/db/pipeline/document_source_merge.cpp
@@ -286,7 +286,8 @@ DocumentSourceMergeSpec parseMergeSpecAndResolveTargetNamespace(const BSONElemen
// database name using the shortcut syntax (to match the semantics of the $out stage), the
// target database will use the default name provided.
if (spec.type() == BSONType::String) {
- targetNss = {defaultDb, spec.valueStringData()};
+ targetNss =
+ NamespaceStringUtil::parseNamespaceFromRequest(defaultDb, spec.valueStringData());
} else {
mergeSpec = DocumentSourceMergeSpec::parse(
IDLParserContext(kStageName, false /* apiStrict */, defaultDb.tenantId()),
@@ -299,10 +300,10 @@ DocumentSourceMergeSpec parseMergeSpecAndResolveTargetNamespace(const BSONElemen
// from the NamespaceString semantics which treats it as a database name. So, if the
// target namespace collection is empty, we'll use the default database name as a target
// database, and the provided namespace value as a collection name.
- targetNss = {defaultDb, targetNss.ns()};
+ targetNss = NamespaceStringUtil::parseNamespaceFromRequest(defaultDb, targetNss.ns());
} else if (targetNss.dbName().db().empty()) {
// Use the default database name if it wasn't specified explicilty.
- targetNss = {defaultDb, targetNss.coll()};
+ targetNss = NamespaceStringUtil::parseNamespaceFromRequest(defaultDb, targetNss.coll());
}
}
diff --git a/src/mongo/db/pipeline/document_source_merge_cursors_test.cpp b/src/mongo/db/pipeline/document_source_merge_cursors_test.cpp
index b0c6fff8037..9829838aba8 100644
--- a/src/mongo/db/pipeline/document_source_merge_cursors_test.cpp
+++ b/src/mongo/db/pipeline/document_source_merge_cursors_test.cpp
@@ -83,7 +83,8 @@ const CursorId kExhaustedCursorID = 0;
class DocumentSourceMergeCursorsTest : public ShardingTestFixture {
public:
- DocumentSourceMergeCursorsTest() : _nss(boost::none, kMergeCursorNsStr) {
+ DocumentSourceMergeCursorsTest()
+ : _nss(NamespaceString::createNamespaceString_forTest(boost::none, kMergeCursorNsStr)) {
TimeZoneDatabase::set(getServiceContext(), std::make_unique<TimeZoneDatabase>());
}
diff --git a/src/mongo/db/pipeline/document_source_merge_spec.cpp b/src/mongo/db/pipeline/document_source_merge_spec.cpp
index 7518c8e2df0..d98b567f5c5 100644
--- a/src/mongo/db/pipeline/document_source_merge_spec.cpp
+++ b/src/mongo/db/pipeline/document_source_merge_spec.cpp
@@ -53,7 +53,7 @@ NamespaceString mergeTargetNssParseFromBSON(boost::optional<TenantId> tenantId,
uassert(5786800,
"{} 'into' field cannot be an empty string"_format(DocumentSourceMerge::kStageName),
!elem.valueStringData().empty());
- return NamespaceString(tenantId, "", elem.valueStringData());
+ return NamespaceStringUtil::parseNamespaceFromRequest(tenantId, "", elem.valueStringData());
}
auto spec = NamespaceSpec::parse(
IDLParserContext(
@@ -65,7 +65,8 @@ NamespaceString mergeTargetNssParseFromBSON(boost::optional<TenantId> tenantId,
DocumentSourceMerge::kStageName),
coll && !coll->empty());
- return {spec.getDb().value_or(DatabaseName(tenantId, "")), *coll};
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ spec.getDb().value_or(DatabaseName(tenantId, "")), *coll);
}
void mergeTargetNssSerializeToBSON(const NamespaceString& targetNss,
diff --git a/src/mongo/db/pipeline/document_source_out.cpp b/src/mongo/db/pipeline/document_source_out.cpp
index 12abd30a6b7..bd2eddac692 100644
--- a/src/mongo/db/pipeline/document_source_out.cpp
+++ b/src/mongo/db/pipeline/document_source_out.cpp
@@ -85,14 +85,15 @@ DocumentSourceOut::~DocumentSourceOut() {
NamespaceString DocumentSourceOut::parseNsFromElem(const BSONElement& spec,
const DatabaseName& defaultDB) {
if (spec.type() == BSONType::String) {
- return NamespaceString(defaultDB, spec.valueStringData());
+ return NamespaceStringUtil::parseNamespaceFromRequest(defaultDB, spec.valueStringData());
} else if (spec.type() == BSONType::Object) {
auto nsObj = spec.Obj();
uassert(16994,
str::stream() << "If an object is passed to " << kStageName
<< " it must have exactly 2 fields: 'db' and 'coll'",
nsObj.nFields() == 2 && nsObj.hasField("coll") && nsObj.hasField("db"));
- return NamespaceString(defaultDB.tenantId(), nsObj["db"].String(), nsObj["coll"].String());
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ defaultDB.tenantId(), nsObj["db"].String(), nsObj["coll"].String());
} else {
uassert(16990,
"{} only supports a string or object argument, but found {}"_format(
@@ -104,7 +105,6 @@ NamespaceString DocumentSourceOut::parseNsFromElem(const BSONElement& spec,
std::unique_ptr<DocumentSourceOut::LiteParsed> DocumentSourceOut::LiteParsed::parse(
const NamespaceString& nss, const BSONElement& spec) {
-
NamespaceString targetNss = parseNsFromElem(spec, nss.dbName());
uassert(ErrorCodes::InvalidNamespace,
"Invalid {} target namespace, {}"_format(kStageName, targetNss.ns()),
@@ -120,9 +120,9 @@ void DocumentSourceOut::initialize() {
// to be the target collection once we are done.
// Note that this temporary collection name is used by MongoMirror and thus should not be
// changed without consultation.
- _tempNs = NamespaceString(outputNs.tenantId(),
- str::stream() << outputNs.dbName().toString() << ".tmp.agg_out."
- << UUID::gen());
+ _tempNs = NamespaceStringUtil::parseNamespaceFromRequest(
+ outputNs.tenantId(),
+ str::stream() << outputNs.dbName().toString() << ".tmp.agg_out." << UUID::gen());
// Save the original collection options and index specs so we can check they didn't change
// during computation.
diff --git a/src/mongo/db/pipeline/document_source_union_with.cpp b/src/mongo/db/pipeline/document_source_union_with.cpp
index f8d61a9e061..3506561f46a 100644
--- a/src/mongo/db/pipeline/document_source_union_with.cpp
+++ b/src/mongo/db/pipeline/document_source_union_with.cpp
@@ -127,12 +127,14 @@ std::unique_ptr<DocumentSourceUnionWith::LiteParsed> DocumentSourceUnionWith::Li
NamespaceString unionNss;
boost::optional<LiteParsedPipeline> liteParsedPipeline;
if (spec.type() == BSONType::String) {
- unionNss = NamespaceString(nss.dbName(), spec.valueStringData());
+ unionNss =
+ NamespaceStringUtil::parseNamespaceFromRequest(nss.dbName(), spec.valueStringData());
} else {
auto unionWithSpec =
UnionWithSpec::parse(IDLParserContext(kStageName), spec.embeddedObject());
if (unionWithSpec.getColl()) {
- unionNss = NamespaceString(nss.dbName(), *unionWithSpec.getColl());
+ unionNss = NamespaceStringUtil::parseNamespaceFromRequest(nss.dbName(),
+ *unionWithSpec.getColl());
} else {
// If no collection specified, it must have $documents as first field in pipeline.
validateUnionWithCollectionlessPipeline(unionWithSpec.getPipeline());
@@ -185,12 +187,14 @@ boost::intrusive_ptr<DocumentSource> DocumentSourceUnionWith::createFromBson(
NamespaceString unionNss;
std::vector<BSONObj> pipeline;
if (elem.type() == BSONType::String) {
- unionNss = NamespaceString(expCtx->ns.dbName(), elem.valueStringData());
+ unionNss = NamespaceStringUtil::parseNamespaceFromRequest(expCtx->ns.dbName(),
+ elem.valueStringData());
} else {
auto unionWithSpec =
UnionWithSpec::parse(IDLParserContext(kStageName), elem.embeddedObject());
if (unionWithSpec.getColl()) {
- unionNss = NamespaceString(expCtx->ns.dbName(), *unionWithSpec.getColl());
+ unionNss = NamespaceStringUtil::parseNamespaceFromRequest(expCtx->ns.dbName(),
+ *unionWithSpec.getColl());
} else {
// if no collection specified, it must have $documents as first field in pipeline
validateUnionWithCollectionlessPipeline(unionWithSpec.getPipeline());
diff --git a/src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp b/src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp
index 4bcd1db560b..f4d8e02d896 100644
--- a/src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp
+++ b/src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp
@@ -296,7 +296,8 @@ std::deque<BSONObj> CommonMongodProcessInterface::listCatalog(OperationContext*
NamespaceString ns(NamespaceStringUtil::deserialize((*svns.nss()).tenantId(),
obj.getStringField("_id")));
- NamespaceString viewOnNs(ns.dbName(), obj.getStringField("viewOn"));
+ NamespaceString viewOnNs(NamespaceStringUtil::parseNamespaceFromDoc(
+ ns.dbName(), obj.getStringField("viewOn")));
BSONObjBuilder builder;
builder.append("db", DatabaseNameUtil::serialize(ns.dbName()));
diff --git a/src/mongo/db/pipeline/process_interface/replica_set_node_process_interface.cpp b/src/mongo/db/pipeline/process_interface/replica_set_node_process_interface.cpp
index 6dc8109420c..16473b19bda 100644
--- a/src/mongo/db/pipeline/process_interface/replica_set_node_process_interface.cpp
+++ b/src/mongo/db/pipeline/process_interface/replica_set_node_process_interface.cpp
@@ -152,7 +152,7 @@ void ReplicaSetNodeProcessInterface::renameIfOptionsAndIndexesHaveNotChanged(
void ReplicaSetNodeProcessInterface::createCollection(OperationContext* opCtx,
const DatabaseName& dbName,
const BSONObj& cmdObj) {
- NamespaceString dbNs = NamespaceString(dbName, StringData(""));
+ NamespaceString dbNs = NamespaceString(dbName);
if (_canWriteLocally(opCtx, dbNs)) {
return NonShardServerProcessInterface::createCollection(opCtx, dbName, cmdObj);
}
diff --git a/src/mongo/db/query/fle/server_rewrite.cpp b/src/mongo/db/query/fle/server_rewrite.cpp
index f0f0db0da1e..a48ad5d7789 100644
--- a/src/mongo/db/query/fle/server_rewrite.cpp
+++ b/src/mongo/db/query/fle/server_rewrite.cpp
@@ -256,7 +256,8 @@ void doFLERewriteInTxn(OperationContext* opCtx,
// if breaks us off of the current optctx readconcern and other settings
//
if (!opCtx->inMultiDocumentTransaction()) {
- NamespaceString nssEsc(sharedBlock->dbName, sharedBlock->esc);
+ NamespaceString nssEsc(NamespaceStringUtil::parseNamespaceFromRequest(
+ sharedBlock->dbName, sharedBlock->esc));
NamespaceString nssEcc; // Ignored in V2
FLETagNoTXNQuery queryInterface(opCtx);
@@ -268,17 +269,18 @@ void doFLERewriteInTxn(OperationContext* opCtx,
auto txn = getTxn(opCtx);
auto swCommitResult = txn->runNoThrow(
opCtx, [sharedBlock](const txn_api::TransactionClient& txnClient, auto txnExec) {
- NamespaceString nssEsc(sharedBlock->dbName, sharedBlock->esc);
+ NamespaceString nssEsc(NamespaceStringUtil::parseNamespaceFromRequest(
+ sharedBlock->dbName, sharedBlock->esc));
// Construct FLE rewriter from the transaction client and encryptionInformation.
auto queryInterface = FLEQueryInterfaceImpl(txnClient, getGlobalServiceContext());
// Rewrite the MatchExpression.
if (sharedBlock->ecc) {
- sharedBlock->doRewrite(
- &queryInterface,
- nssEsc,
- NamespaceString(sharedBlock->dbName, sharedBlock->ecc.get()));
+ sharedBlock->doRewrite(&queryInterface,
+ nssEsc,
+ NamespaceStringUtil::parseNamespaceFromRequest(
+ sharedBlock->dbName, sharedBlock->ecc.get()));
} else {
sharedBlock->doRewrite(&queryInterface, nssEsc);
}
@@ -298,10 +300,12 @@ BSONObj rewriteEncryptedFilterInsideTxn(FLETagQueryInterface* queryImpl,
boost::intrusive_ptr<ExpressionContext> expCtx,
BSONObj filter,
EncryptedCollScanModeAllowed mode) {
- NamespaceString nssEsc(dbName, efc.getEscCollection().value());
+ NamespaceString nssEsc(
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, efc.getEscCollection().value()));
if (!gFeatureFlagFLE2ProtocolVersion2.isEnabled(serverGlobalParams.featureCompatibility)) {
- NamespaceString nssEcc(dbName, efc.getEccCollection().value());
+ NamespaceString nssEcc(
+ NamespaceStringUtil::parseNamespaceFromRequest(dbName, efc.getEccCollection().value()));
return rewriteEncryptedFilter(queryImpl, nssEsc, nssEcc, expCtx, filter, mode);
}
diff --git a/src/mongo/db/repl/collection_cloner_test.cpp b/src/mongo/db/repl/collection_cloner_test.cpp
index 5332d05ec4d..c51b32e7c89 100644
--- a/src/mongo/db/repl/collection_cloner_test.cpp
+++ b/src/mongo/db/repl/collection_cloner_test.cpp
@@ -60,7 +60,8 @@ const std::string kTestNs = "testDb.testColl";
class CollectionClonerTest : public InitialSyncClonerTestFixture {
public:
- CollectionClonerTest() : _nss(boost::none, kTestNs) {}
+ CollectionClonerTest()
+ : _nss(NamespaceString::createNamespaceString_forTest(boost::none, kTestNs)) {}
protected:
void setUp() override {
@@ -1013,7 +1014,8 @@ TEST_F(CollectionClonerTestResumable, ResumableQueryTwoResumes) {
class CollectionClonerMultitenancyTest : public CollectionClonerTestResumable {
public:
- CollectionClonerMultitenancyTest() : _nss(TenantId(OID::gen()), kTestNs) {}
+ CollectionClonerMultitenancyTest()
+ : _nss(NamespaceString::createNamespaceString_forTest(TenantId(OID::gen()), kTestNs)) {}
protected:
void setUp() final {
diff --git a/src/mongo/db/repl/database_cloner.cpp b/src/mongo/db/repl/database_cloner.cpp
index b19708702d1..5d600993f32 100644
--- a/src/mongo/db/repl/database_cloner.cpp
+++ b/src/mongo/db/repl/database_cloner.cpp
@@ -89,7 +89,8 @@ BaseCloner::AfterStageBehavior DatabaseCloner::listCollectionsStage() {
.reason());
}
- NamespaceString collectionNamespace(_dbName, result.getName());
+ NamespaceString collectionNamespace(
+ NamespaceStringUtil::parseNamespaceFromResponse(_dbName, result.getName()));
if (collectionNamespace.isSystem() && !collectionNamespace.isReplicated()) {
LOGV2_DEBUG(21146,
1,
diff --git a/src/mongo/db/repl/idempotency_test_fixture.h b/src/mongo/db/repl/idempotency_test_fixture.h
index 33d4f1c4ffa..9412aac9aa9 100644
--- a/src/mongo/db/repl/idempotency_test_fixture.h
+++ b/src/mongo/db/repl/idempotency_test_fixture.h
@@ -89,7 +89,8 @@ StringBuilder& operator<<(StringBuilder& sb, const CollectionState& state);
class IdempotencyTest : public OplogApplierImplTest {
public:
- IdempotencyTest() : _nss(boost::none, "test.foo") {
+ IdempotencyTest()
+ : _nss(NamespaceString::createNamespaceString_forTest(boost::none, "test.foo")) {
globalFailPointRegistry()
.find("doUntimestampedWritesForIdempotencyTests")
->setMode(FailPoint::alwaysOn);
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 98c57c1496f..04f92aeb17b 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -841,7 +841,7 @@ NamespaceString extractNs(DatabaseName dbName, const BSONObj& cmdObj) {
first.canonicalType() == canonicalizeBSONType(mongo::String));
StringData coll = first.valueStringData();
uassert(28635, "no collection name specified", !coll.empty());
- return NamespaceString(dbName, coll);
+ return NamespaceStringUtil::parseNamespaceFromDoc(dbName, coll);
}
NamespaceString extractNsFromUUID(OperationContext* opCtx, const UUID& uuid) {
diff --git a/src/mongo/db/repl/oplog_applier_impl_test.cpp b/src/mongo/db/repl/oplog_applier_impl_test.cpp
index e55ef97dffa..337c8f14075 100644
--- a/src/mongo/db/repl/oplog_applier_impl_test.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl_test.cpp
@@ -1685,8 +1685,8 @@ class MultiOplogEntryOplogApplierImplTestMultitenant : public OplogApplierImplTe
public:
MultiOplogEntryOplogApplierImplTestMultitenant()
: _tenantId(OID::gen()),
- _nss(_tenantId, "test.preptxn"),
- _cmdNss(_tenantId, "admin", "$cmd"),
+ _nss(NamespaceString::createNamespaceString_forTest(_tenantId, "test.preptxn")),
+ _cmdNss(NamespaceString::createNamespaceString_forTest(_tenantId, "admin", "$cmd")),
_txnNum(1) {}
protected:
diff --git a/src/mongo/db/repl/repl_set_test_egress.cpp b/src/mongo/db/repl/repl_set_test_egress.cpp
index c3c5b9861eb..6fad40ebb51 100644
--- a/src/mongo/db/repl/repl_set_test_egress.cpp
+++ b/src/mongo/db/repl/repl_set_test_egress.cpp
@@ -139,7 +139,7 @@ public:
void doCheckAuthorization(OperationContext*) const final {}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/repl/rollback_impl_test.cpp b/src/mongo/db/repl/rollback_impl_test.cpp
index bafd638b045..5ffbb4edf96 100644
--- a/src/mongo/db/repl/rollback_impl_test.cpp
+++ b/src/mongo/db/repl/rollback_impl_test.cpp
@@ -2068,8 +2068,8 @@ TEST_F(RollbackImplObserverInfoTest,
RAIIServerParameterControllerForTest multitenancyController("multitenancySupport", true);
boost::optional<TenantId> tid(OID::gen());
- auto fromNss = NamespaceString(tid, "test", "source");
- auto toNss = NamespaceString(tid, "test", "dest");
+ auto fromNss = NamespaceString::createNamespaceString_forTest(tid, "test", "source");
+ auto toNss = NamespaceString::createNamespaceString_forTest(tid, "test", "dest");
auto cmdObj = BSON("renameCollection" << NamespaceStringUtil::serialize(fromNss) << "to"
<< NamespaceStringUtil::serialize(toNss));
@@ -2089,8 +2089,8 @@ TEST_F(RollbackImplObserverInfoTest,
RAIIServerParameterControllerForTest featureFlagController("featureFlagRequireTenantID", true);
boost::optional<TenantId> tid(OID::gen());
- auto fromNss = NamespaceString(tid, "test", "source");
- auto toNss = NamespaceString(tid, "test", "dest");
+ auto fromNss = NamespaceString::createNamespaceString_forTest(tid, "test", "source");
+ auto toNss = NamespaceString::createNamespaceString_forTest(tid, "test", "dest");
auto cmdObj = BSON("renameCollection" << NamespaceStringUtil::serialize(fromNss) << "to"
<< NamespaceStringUtil::serialize(toNss));
diff --git a/src/mongo/db/repl/shard_merge_recipient_service.cpp b/src/mongo/db/repl/shard_merge_recipient_service.cpp
index 8e362697ee3..7bd286b4b7f 100644
--- a/src/mongo/db/repl/shard_merge_recipient_service.cpp
+++ b/src/mongo/db/repl/shard_merge_recipient_service.cpp
@@ -97,7 +97,8 @@ constexpr int kCheckpointTsBackupCursorErrorCode = 6929900;
constexpr int kCloseCursorBeforeOpenErrorCode = 50886;
NamespaceString getOplogBufferNs(const UUID& migrationUUID) {
- return NamespaceString(DatabaseName::kConfig, kOplogBufferPrefix + migrationUUID.toString());
+ return NamespaceString::makeGlobalConfigCollection(kOplogBufferPrefix +
+ migrationUUID.toString());
}
boost::intrusive_ptr<ExpressionContext> makeExpressionContext(OperationContext* opCtx) {
diff --git a/src/mongo/db/repl/tenant_migration_recipient_service.cpp b/src/mongo/db/repl/tenant_migration_recipient_service.cpp
index e02202bfcb4..77829e61f4f 100644
--- a/src/mongo/db/repl/tenant_migration_recipient_service.cpp
+++ b/src/mongo/db/repl/tenant_migration_recipient_service.cpp
@@ -100,7 +100,8 @@ constexpr int kCheckpointTsBackupCursorErrorCode = 6929900;
constexpr int kCloseCursorBeforeOpenErrorCode = 50886;
NamespaceString getOplogBufferNs(const UUID& migrationUUID) {
- return NamespaceString(DatabaseName::kConfig, kOplogBufferPrefix + migrationUUID.toString());
+ return NamespaceString::makeGlobalConfigCollection(kOplogBufferPrefix +
+ migrationUUID.toString());
}
bool isMigrationCompleted(TenantMigrationRecipientStateEnum state) {
diff --git a/src/mongo/db/repl/tenant_migration_shard_merge_util.h b/src/mongo/db/repl/tenant_migration_shard_merge_util.h
index 4950d392bf9..203fe094fc2 100644
--- a/src/mongo/db/repl/tenant_migration_shard_merge_util.h
+++ b/src/mongo/db/repl/tenant_migration_shard_merge_util.h
@@ -58,7 +58,8 @@ inline bool isDonatedFilesCollection(const NamespaceString& ns) {
}
inline NamespaceString getDonatedFilesNs(const UUID& migrationUUID) {
- return NamespaceString(DatabaseName::kConfig, kDonatedFilesPrefix + migrationUUID.toString());
+ return NamespaceString::makeGlobalConfigCollection(kDonatedFilesPrefix +
+ migrationUUID.toString());
}
inline boost::filesystem::path fileClonerTempDir(const UUID& migrationId) {
diff --git a/src/mongo/db/s/add_shard_cmd.cpp b/src/mongo/db/s/add_shard_cmd.cpp
index 6682c51df21..b5505c4371c 100644
--- a/src/mongo/db/s/add_shard_cmd.cpp
+++ b/src/mongo/db/s/add_shard_cmd.cpp
@@ -95,7 +95,7 @@ public:
// The command parameter happens to be string so it's historically been interpreted
// by parseNs as a collection. Continuing to do so here for unexamined compatibility.
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
void doCheckAuthorization(OperationContext* opCtx) const override {
diff --git a/src/mongo/db/s/analyze_shard_key_cmd_util.cpp b/src/mongo/db/s/analyze_shard_key_cmd_util.cpp
index e0ba2487254..6dac0d170f2 100644
--- a/src/mongo/db/s/analyze_shard_key_cmd_util.cpp
+++ b/src/mongo/db/s/analyze_shard_key_cmd_util.cpp
@@ -619,11 +619,11 @@ CollStatsMetrics calculateCollStats(OperationContext* opCtx, const NamespaceStri
* Generates the namespace for the temporary collection storing the split points.
*/
NamespaceString makeSplitPointsNss(const UUID& origCollUuid, const UUID& tempCollUuid) {
- return NamespaceString(DatabaseName::kConfig,
- fmt::format("{}{}.{}",
- NamespaceString::kAnalyzeShardKeySplitPointsCollectionPrefix,
- origCollUuid.toString(),
- tempCollUuid.toString()));
+ return NamespaceString::makeGlobalConfigCollection(
+ fmt::format("{}{}.{}",
+ NamespaceString::kAnalyzeShardKeySplitPointsCollectionPrefix,
+ origCollUuid.toString(),
+ tempCollUuid.toString()));
}
/**
diff --git a/src/mongo/db/s/check_sharding_index_command.cpp b/src/mongo/db/s/check_sharding_index_command.cpp
index 9da41e79384..b1094698bde 100644
--- a/src/mongo/db/s/check_sharding_index_command.cpp
+++ b/src/mongo/db/s/check_sharding_index_command.cpp
@@ -72,7 +72,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool errmsgRun(OperationContext* opCtx,
diff --git a/src/mongo/db/s/config/configsvr_ensure_chunk_version_is_greater_than_command.cpp b/src/mongo/db/s/config/configsvr_ensure_chunk_version_is_greater_than_command.cpp
index 9acbfb2f107..7d2f659703e 100644
--- a/src/mongo/db/s/config/configsvr_ensure_chunk_version_is_greater_than_command.cpp
+++ b/src/mongo/db/s/config/configsvr_ensure_chunk_version_is_greater_than_command.cpp
@@ -64,7 +64,7 @@ public:
private:
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/s/config/configsvr_remove_chunks_command.cpp b/src/mongo/db/s/config/configsvr_remove_chunks_command.cpp
index f91f0b312df..5da8491410d 100644
--- a/src/mongo/db/s/config/configsvr_remove_chunks_command.cpp
+++ b/src/mongo/db/s/config/configsvr_remove_chunks_command.cpp
@@ -112,7 +112,7 @@ public:
private:
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/s/config/configsvr_repair_sharded_collection_chunks_history_command.cpp b/src/mongo/db/s/config/configsvr_repair_sharded_collection_chunks_history_command.cpp
index 2017fc4e8f9..1524ec36138 100644
--- a/src/mongo/db/s/config/configsvr_repair_sharded_collection_chunks_history_command.cpp
+++ b/src/mongo/db/s/config/configsvr_repair_sharded_collection_chunks_history_command.cpp
@@ -69,7 +69,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
Status checkAuthForOperation(OperationContext* opCtx,
diff --git a/src/mongo/db/s/config/configsvr_split_chunk_command.cpp b/src/mongo/db/s/config/configsvr_split_chunk_command.cpp
index 60d96eb8901..48eb421a579 100644
--- a/src/mongo/db/s/config/configsvr_split_chunk_command.cpp
+++ b/src/mongo/db/s/config/configsvr_split_chunk_command.cpp
@@ -106,7 +106,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/s/get_database_version_command.cpp b/src/mongo/db/s/get_database_version_command.cpp
index 6d23fc2782d..f47466b361f 100644
--- a/src/mongo/db/s/get_database_version_command.cpp
+++ b/src/mongo/db/s/get_database_version_command.cpp
@@ -62,7 +62,8 @@ public:
// The command parameter happens to be string so it's historically been interpreted
// by parseNs as a collection. Continuing to do so here for unexamined compatibility.
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), _targetDb());
+ return NamespaceStringUtil::parseNamespaceFromRequest(request().getDbName(),
+ _targetDb());
}
void doCheckAuthorization(OperationContext* opCtx) const override {
diff --git a/src/mongo/db/s/get_shard_version_command.cpp b/src/mongo/db/s/get_shard_version_command.cpp
index 57906f8aaae..6bfbf1fc308 100644
--- a/src/mongo/db/s/get_shard_version_command.cpp
+++ b/src/mongo/db/s/get_shard_version_command.cpp
@@ -78,7 +78,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/s/migration_destination_manager_commands.cpp b/src/mongo/db/s/migration_destination_manager_commands.cpp
index 7af69307659..6e289ccf0cd 100644
--- a/src/mongo/db/s/migration_destination_manager_commands.cpp
+++ b/src/mongo/db/s/migration_destination_manager_commands.cpp
@@ -85,7 +85,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
Status checkAuthForOperation(OperationContext* opCtx,
diff --git a/src/mongo/db/s/move_primary/move_primary_recipient_cmds.cpp b/src/mongo/db/s/move_primary/move_primary_recipient_cmds.cpp
index a99cf7f6299..6f3faeb2043 100644
--- a/src/mongo/db/s/move_primary/move_primary_recipient_cmds.cpp
+++ b/src/mongo/db/s/move_primary/move_primary_recipient_cmds.cpp
@@ -93,7 +93,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -161,7 +161,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -232,7 +232,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/s/move_primary_coordinator.cpp b/src/mongo/db/s/move_primary_coordinator.cpp
index 5f34c64cbfe..1b695aafc45 100644
--- a/src/mongo/db/s/move_primary_coordinator.cpp
+++ b/src/mongo/db/s/move_primary_coordinator.cpp
@@ -387,7 +387,8 @@ std::vector<NamespaceString> MovePrimaryCoordinator::getUnshardedCollections(
std::string collName;
uassertStatusOK(bsonExtractStringField(collInfo, "name", &collName));
- const NamespaceString nss(_dbName, collName);
+ const NamespaceString nss(
+ NamespaceStringUtil::parseNamespaceFromDoc(_dbName, collName));
if (!nss.isSystem() ||
nss.isLegalClientSystemNS(serverGlobalParams.featureCompatibility)) {
colls.push_back(nss);
@@ -442,7 +443,7 @@ void MovePrimaryCoordinator::assertNoOrphanedDataOnRecipient(
for (const auto& bsonColl : listResponse.docs) {
std::string collName;
uassertStatusOK(bsonExtractStringField(bsonColl, "name", &collName));
- colls.push_back({_dbName, collName});
+ colls.push_back(NamespaceStringUtil::parseNamespaceFromResponse(_dbName, collName));
}
std::sort(colls.begin(), colls.end());
diff --git a/src/mongo/db/s/resharding/resharding_collection_cloner.cpp b/src/mongo/db/s/resharding/resharding_collection_cloner.cpp
index 07538097e26..c34a5d0350b 100644
--- a/src/mongo/db/s/resharding/resharding_collection_cloner.cpp
+++ b/src/mongo/db/s/resharding/resharding_collection_cloner.cpp
@@ -109,7 +109,7 @@ ReshardingCollectionCloner::makeRawPipeline(
// Assume that the config.cache.chunks collection isn't a view either.
auto tempNss = resharding::constructTemporaryReshardingNss(_sourceNss.db(), _sourceUUID);
auto tempCacheChunksNss =
- NamespaceString(DatabaseName::kConfig, "cache.chunks." + tempNss.ns());
+ NamespaceString::makeGlobalConfigCollection("cache.chunks." + tempNss.ns());
resolvedNamespaces[tempCacheChunksNss.coll()] = {tempCacheChunksNss, std::vector<BSONObj>{}};
// Pipeline::makePipeline() ignores the collation set on the AggregationRequest (or lack
diff --git a/src/mongo/db/s/shardsvr_create_global_index_command.cpp b/src/mongo/db/s/shardsvr_create_global_index_command.cpp
index 0ed41877b14..a5b626fea85 100644
--- a/src/mongo/db/s/shardsvr_create_global_index_command.cpp
+++ b/src/mongo/db/s/shardsvr_create_global_index_command.cpp
@@ -80,7 +80,7 @@ public:
}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
void typedRun(OperationContext* opCtx) {
diff --git a/src/mongo/db/s/shardsvr_drop_database_command.cpp b/src/mongo/db/s/shardsvr_drop_database_command.cpp
index 3f23ffa2fa8..55c11b82e71 100644
--- a/src/mongo/db/s/shardsvr_drop_database_command.cpp
+++ b/src/mongo/db/s/shardsvr_drop_database_command.cpp
@@ -121,7 +121,7 @@ public:
private:
NamespaceString ns() const override {
- return {request().getDbName(), ""};
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/s/shardsvr_drop_database_participant_command.cpp b/src/mongo/db/s/shardsvr_drop_database_participant_command.cpp
index e1c5978c9e4..dd354b2e2e2 100644
--- a/src/mongo/db/s/shardsvr_drop_database_participant_command.cpp
+++ b/src/mongo/db/s/shardsvr_drop_database_participant_command.cpp
@@ -88,7 +88,7 @@ public:
private:
NamespaceString ns() const override {
- return {request().getDbName(), ""};
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/s/shardsvr_drop_global_index_command.cpp b/src/mongo/db/s/shardsvr_drop_global_index_command.cpp
index c55526cb16a..e28d4e94da2 100644
--- a/src/mongo/db/s/shardsvr_drop_global_index_command.cpp
+++ b/src/mongo/db/s/shardsvr_drop_global_index_command.cpp
@@ -79,7 +79,7 @@ public:
}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
void typedRun(OperationContext* opCtx) {
diff --git a/src/mongo/db/s/shardsvr_get_stats_for_balancing_command.cpp b/src/mongo/db/s/shardsvr_get_stats_for_balancing_command.cpp
index d50b3fbc26d..4034d70a4ea 100644
--- a/src/mongo/db/s/shardsvr_get_stats_for_balancing_command.cpp
+++ b/src/mongo/db/s/shardsvr_get_stats_for_balancing_command.cpp
@@ -134,7 +134,7 @@ public:
}
NamespaceString ns() const override {
- return {request().getDbName(), ""};
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/s/shardsvr_join_migrations_command.cpp b/src/mongo/db/s/shardsvr_join_migrations_command.cpp
index eeb2cdbcd3f..d5b2e171038 100644
--- a/src/mongo/db/s/shardsvr_join_migrations_command.cpp
+++ b/src/mongo/db/s/shardsvr_join_migrations_command.cpp
@@ -83,7 +83,7 @@ public:
static constexpr char kRegistryLockReason[] = "Running _shardsvrJoinMigrations";
NamespaceString ns() const override {
- return {request().getDbName(), ""};
+ return NamespaceString(request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/db/s/shardsvr_merge_chunks_command.cpp b/src/mongo/db/s/shardsvr_merge_chunks_command.cpp
index 0b5c48213c1..4169f3235d5 100644
--- a/src/mongo/db/s/shardsvr_merge_chunks_command.cpp
+++ b/src/mongo/db/s/shardsvr_merge_chunks_command.cpp
@@ -140,7 +140,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool adminOnly() const override {
diff --git a/src/mongo/db/s/shardsvr_move_primary_command.cpp b/src/mongo/db/s/shardsvr_move_primary_command.cpp
index 55170519081..aeca60ed58d 100644
--- a/src/mongo/db/s/shardsvr_move_primary_command.cpp
+++ b/src/mongo/db/s/shardsvr_move_primary_command.cpp
@@ -83,7 +83,7 @@ public:
uassert(ErrorCodes::InvalidNamespace,
"'movePrimary' must be of type String",
nsElt.type() == BSONType::String);
- return NamespaceString(dbName.tenantId(), nsElt.str());
+ return NamespaceStringUtil::parseNamespaceFromRequest(dbName.tenantId(), nsElt.str());
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/s/shardsvr_split_chunk_command.cpp b/src/mongo/db/s/shardsvr_split_chunk_command.cpp
index 52536354781..33cb9dcd496 100644
--- a/src/mongo/db/s/shardsvr_split_chunk_command.cpp
+++ b/src/mongo/db/s/shardsvr_split_chunk_command.cpp
@@ -88,7 +88,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool errmsgRun(OperationContext* opCtx,
diff --git a/src/mongo/db/s/shardsvr_write_global_index_keys_command.cpp b/src/mongo/db/s/shardsvr_write_global_index_keys_command.cpp
index 77536e7773f..8eece73ffc9 100644
--- a/src/mongo/db/s/shardsvr_write_global_index_keys_command.cpp
+++ b/src/mongo/db/s/shardsvr_write_global_index_keys_command.cpp
@@ -67,7 +67,7 @@ public:
}
NamespaceString ns() const override {
- return {request().getDbName(), ""};
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/s/split_vector_command.cpp b/src/mongo/db/s/split_vector_command.cpp
index 511d9ff52f0..2e2bf3cb9b3 100644
--- a/src/mongo/db/s/split_vector_command.cpp
+++ b/src/mongo/db/s/split_vector_command.cpp
@@ -82,7 +82,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool errmsgRun(OperationContext* opCtx,
diff --git a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp
index 09c8897ae08..19c7d58e58d 100644
--- a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp
+++ b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp
@@ -184,7 +184,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
void doCheckAuthorization(OperationContext* opCtx) const override {
@@ -374,7 +374,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
void doCheckAuthorization(OperationContext* opCtx) const override {}
diff --git a/src/mongo/db/serverless/shard_split_commands.cpp b/src/mongo/db/serverless/shard_split_commands.cpp
index b7757134c4b..b01d3867c08 100644
--- a/src/mongo/db/serverless/shard_split_commands.cpp
+++ b/src/mongo/db/serverless/shard_split_commands.cpp
@@ -105,7 +105,7 @@ public:
}
NamespaceString ns() const {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -183,7 +183,7 @@ public:
}
NamespaceString ns() const {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -260,7 +260,7 @@ public:
}
NamespaceString ns() const {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp
index 09780d00045..2c6c3bbd2f1 100644
--- a/src/mongo/db/service_entry_point_common.cpp
+++ b/src/mongo/db/service_entry_point_common.cpp
@@ -1995,9 +1995,8 @@ void curOpCommandSetup(OperationContext* opCtx, const OpMsgRequest& request) {
// We construct a legacy $cmd namespace so we can fill in curOp using
// the existing logic that existed for OP_QUERY commands
- NamespaceString nss(
- DatabaseNameUtil::deserialize(request.getValidatedTenantId(), request.getDatabase()),
- "$cmd");
+ NamespaceString nss(NamespaceString::makeCommandNamespace(
+ DatabaseNameUtil::deserialize(request.getValidatedTenantId(), request.getDatabase())));
stdx::lock_guard<Client> lk(*opCtx->getClient());
curop->setNS_inlock(nss);
diff --git a/src/mongo/db/shard_role_test.cpp b/src/mongo/db/shard_role_test.cpp
index 2dc888976f3..7cdd771d50b 100644
--- a/src/mongo/db/shard_role_test.cpp
+++ b/src/mongo/db/shard_role_test.cpp
@@ -960,7 +960,8 @@ TEST_F(ShardRoleTest, RestoreWithShardVersionIgnored) {
void ShardRoleTest::testRestoreFailsIfCollectionBecomesCreated(
AcquisitionPrerequisites::OperationType operationType) {
- NamespaceString nss(dbNameTestDb, "NonExistentCollectionWhichWillBeCreated");
+ NamespaceString nss(NamespaceString::createNamespaceString_forTest(
+ dbNameTestDb, "NonExistentCollectionWhichWillBeCreated"));
const auto acquisition = acquireCollection(
opCtx(), CollectionAcquisitionRequest::fromOpCtx(opCtx(), nss, operationType), MODE_IX);
diff --git a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
index 61971054cb3..2b1259ab8fb 100644
--- a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
+++ b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
@@ -1091,7 +1091,7 @@ TEST_F(DurableCatalogImplTest, Idx1) {
WriteUnitOfWork uow(opCtx);
BSONCollectionCatalogEntry::MetaData md;
- md.nss = NamespaceString(boost::none, "a.b");
+ md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b");
BSONCollectionCatalogEntry::IndexMetaData imd;
imd.spec = BSON("name"
@@ -1125,7 +1125,7 @@ TEST_F(DurableCatalogImplTest, Idx1) {
WriteUnitOfWork uow(opCtx);
BSONCollectionCatalogEntry::MetaData md;
- md.nss = NamespaceString(boost::none, "a.b");
+ md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b");
putMetaData(opCtx, catalog.get(), catalogId, md); // remove index
BSONCollectionCatalogEntry::IndexMetaData imd;
@@ -1181,7 +1181,7 @@ TEST_F(DurableCatalogImplTest, DirectoryPerDb1) {
WriteUnitOfWork uow(opCtx);
BSONCollectionCatalogEntry::MetaData md;
- md.nss = NamespaceString(boost::none, "a.b");
+ md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b");
BSONCollectionCatalogEntry::IndexMetaData imd;
imd.spec = BSON("name"
@@ -1233,7 +1233,7 @@ TEST_F(DurableCatalogImplTest, Split1) {
WriteUnitOfWork uow(opCtx);
BSONCollectionCatalogEntry::MetaData md;
- md.nss = NamespaceString(boost::none, "a.b");
+ md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b");
BSONCollectionCatalogEntry::IndexMetaData imd;
imd.spec = BSON("name"
@@ -1285,7 +1285,7 @@ TEST_F(DurableCatalogImplTest, DirectoryPerAndSplit1) {
WriteUnitOfWork uow(opCtx);
BSONCollectionCatalogEntry::MetaData md;
- md.nss = NamespaceString(boost::none, "a.b");
+ md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b");
BSONCollectionCatalogEntry::IndexMetaData imd;
imd.spec = BSON("name"
@@ -1383,7 +1383,7 @@ TEST_F(DurableCatalogImplTest, EntryIncludesTenantIdInMultitenantEnv) {
// entry.
RecordId catalogId;
auto tenantId = TenantId(OID::gen());
- const NamespaceString nss = NamespaceString(tenantId, "a.b");
+ const NamespaceString nss = NamespaceString::createNamespaceString_forTest(tenantId, "a.b");
{
auto clientAndCtx = makeClientAndCtx("opCtx");
auto opCtx = clientAndCtx.opCtx();
diff --git a/src/mongo/db/views/SConscript b/src/mongo/db/views/SConscript
index 2cb81766efe..53cfc7e4bec 100644
--- a/src/mongo/db/views/SConscript
+++ b/src/mongo/db/views/SConscript
@@ -12,6 +12,7 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/db/query/collation/collator_factory_interface',
+ '$BUILD_DIR/mongo/util/namespace_string_database_name_util',
],
)
diff --git a/src/mongo/db/views/view.cpp b/src/mongo/db/views/view.cpp
index bc86e73f26e..e9d9ec5b7ca 100644
--- a/src/mongo/db/views/view.cpp
+++ b/src/mongo/db/views/view.cpp
@@ -42,7 +42,9 @@ ViewDefinition::ViewDefinition(const DatabaseName& dbName,
StringData viewOnName,
const BSONObj& pipeline,
std::unique_ptr<CollatorInterface> collator)
- : _viewNss(dbName, viewName), _viewOnNss(dbName, viewOnName), _collator(std::move(collator)) {
+ : _viewNss(NamespaceStringUtil::parseNamespaceFromDoc(dbName, viewName)),
+ _viewOnNss(NamespaceStringUtil::parseNamespaceFromDoc(dbName, viewOnName)),
+ _collator(std::move(collator)) {
for (BSONElement e : pipeline) {
_pipeline.push_back(e.Obj().getOwned());
}
diff --git a/src/mongo/dbtests/validate_tests.cpp b/src/mongo/dbtests/validate_tests.cpp
index 93847675bb1..fac9153c789 100644
--- a/src/mongo/dbtests/validate_tests.cpp
+++ b/src/mongo/dbtests/validate_tests.cpp
@@ -2192,8 +2192,8 @@ public:
// Verify the older duplicate document appears in the lost-and-found as expected.
{
- const NamespaceString lostAndFoundNss = NamespaceString(
- DatabaseName::kLocal, "lost_and_found." + coll()->uuid().toString());
+ const NamespaceString lostAndFoundNss = NamespaceString::makeLocalCollection(
+ "lost_and_found." + coll()->uuid().toString());
AutoGetCollectionForRead autoColl(&_opCtx, lostAndFoundNss);
Snapshotted<BSONObj> result;
ASSERT(autoColl.getCollection()->findDoc(&_opCtx, RecordId(1), &result));
@@ -2451,8 +2451,8 @@ public:
// Verify the older document appears in the lost-and-found as expected.
{
- const NamespaceString lostAndFoundNss = NamespaceString(
- DatabaseName::kLocal, "lost_and_found." + coll()->uuid().toString());
+ const NamespaceString lostAndFoundNss = NamespaceString::makeLocalCollection(
+ "lost_and_found." + coll()->uuid().toString());
AutoGetCollectionForRead autoColl(&_opCtx, lostAndFoundNss);
Snapshotted<BSONObj> result;
ASSERT(autoColl.getCollection()->findDoc(&_opCtx, RecordId(1), &result));
@@ -2794,8 +2794,8 @@ public:
// Verify the older duplicate document appears in the lost-and-found as expected.
{
- const NamespaceString lostAndFoundNss = NamespaceString(
- DatabaseName::kLocal, "lost_and_found." + coll()->uuid().toString());
+ const NamespaceString lostAndFoundNss = NamespaceString::makeLocalCollection(
+ "lost_and_found." + coll()->uuid().toString());
AutoGetCollectionForRead autoColl(&_opCtx, lostAndFoundNss);
Snapshotted<BSONObj> result;
ASSERT(autoColl.getCollection()->findDoc(&_opCtx, RecordId(1), &result));
diff --git a/src/mongo/s/commands/cluster_coordinate_commit_txn.cpp b/src/mongo/s/commands/cluster_coordinate_commit_txn.cpp
index c1c33413ee9..62abf79ce99 100644
--- a/src/mongo/s/commands/cluster_coordinate_commit_txn.cpp
+++ b/src/mongo/s/commands/cluster_coordinate_commit_txn.cpp
@@ -76,7 +76,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
void doCheckAuthorization(OperationContext* opCtx) const override {
diff --git a/src/mongo/s/commands/cluster_filemd5_cmd.cpp b/src/mongo/s/commands/cluster_filemd5_cmd.cpp
index 61cea761bf6..63b5a2a5033 100644
--- a/src/mongo/s/commands/cluster_filemd5_cmd.cpp
+++ b/src/mongo/s/commands/cluster_filemd5_cmd.cpp
@@ -69,7 +69,7 @@ public:
if (collectionName.empty())
collectionName = "fs";
collectionName += ".chunks";
- return NamespaceString(dbName, collectionName);
+ return NamespaceStringUtil::parseNamespaceFromRequest(dbName, collectionName);
}
Status checkAuthForOperation(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp b/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
index c062456cc06..d0539898b96 100644
--- a/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
+++ b/src/mongo/s/commands/cluster_get_cluster_parameter_cmd.cpp
@@ -100,7 +100,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
} getClusterParameterCmd;
diff --git a/src/mongo/s/commands/cluster_get_shard_version_cmd.cpp b/src/mongo/s/commands/cluster_get_shard_version_cmd.cpp
index 8a3930b9b1e..01f79021811 100644
--- a/src/mongo/s/commands/cluster_get_shard_version_cmd.cpp
+++ b/src/mongo/s/commands/cluster_get_shard_version_cmd.cpp
@@ -82,7 +82,8 @@ public:
uassert(ErrorCodes::BadValue,
str::stream() << "namespace has invalid type " << typeName(first.type()),
first.canonicalType() == canonicalizeBSONType(mongo::String));
- return NamespaceString(dbName.tenantId(), first.valueStringData());
+ return NamespaceStringUtil::parseNamespaceFromRequest(dbName.tenantId(),
+ first.valueStringData());
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_getmore_cmd.h b/src/mongo/s/commands/cluster_getmore_cmd.h
index f576d877d1b..6a2e181ef1a 100644
--- a/src/mongo/s/commands/cluster_getmore_cmd.h
+++ b/src/mongo/s/commands/cluster_getmore_cmd.h
@@ -82,7 +82,8 @@ public:
private:
NamespaceString ns() const override {
- return NamespaceString(_cmd.getDbName(), _cmd.getCollection());
+ return NamespaceStringUtil::parseNamespaceFromRequest(_cmd.getDbName(),
+ _cmd.getCollection());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/s/commands/cluster_list_databases_cmd.cpp b/src/mongo/s/commands/cluster_list_databases_cmd.cpp
index f86faa767f6..66448312301 100644
--- a/src/mongo/s/commands/cluster_list_databases_cmd.cpp
+++ b/src/mongo/s/commands/cluster_list_databases_cmd.cpp
@@ -72,7 +72,7 @@ public:
void doCheckAuthorization(OperationContext*) const final {}
NamespaceString ns() const final {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
ListDatabasesReply typedRun(OperationContext* opCtx) final {
diff --git a/src/mongo/s/commands/cluster_merge_chunks_cmd.cpp b/src/mongo/s/commands/cluster_merge_chunks_cmd.cpp
index af6562ecc67..52ea981c079 100644
--- a/src/mongo/s/commands/cluster_merge_chunks_cmd.cpp
+++ b/src/mongo/s/commands/cluster_merge_chunks_cmd.cpp
@@ -65,7 +65,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool adminOnly() const override {
diff --git a/src/mongo/s/commands/cluster_move_primary_cmd.cpp b/src/mongo/s/commands/cluster_move_primary_cmd.cpp
index 661f0821698..e401f4811ea 100644
--- a/src/mongo/s/commands/cluster_move_primary_cmd.cpp
+++ b/src/mongo/s/commands/cluster_move_primary_cmd.cpp
@@ -88,7 +88,7 @@ public:
uassert(ErrorCodes::InvalidNamespace,
"'movePrimary' must be of type String",
nsElt.type() == BSONType::String);
- return NamespaceString(dbName.tenantId(), nsElt.str());
+ return NamespaceStringUtil::parseNamespaceFromRequest(dbName.tenantId(), nsElt.str());
}
virtual bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_repair_sharded_collection_chunks_history_cmd.cpp b/src/mongo/s/commands/cluster_repair_sharded_collection_chunks_history_cmd.cpp
index 7cc6f88a532..5daff9c7d5c 100644
--- a/src/mongo/s/commands/cluster_repair_sharded_collection_chunks_history_cmd.cpp
+++ b/src/mongo/s/commands/cluster_repair_sharded_collection_chunks_history_cmd.cpp
@@ -87,7 +87,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_rwc_defaults_commands.cpp b/src/mongo/s/commands/cluster_rwc_defaults_commands.cpp
index 9a342382670..180d03b0d08 100644
--- a/src/mongo/s/commands/cluster_rwc_defaults_commands.cpp
+++ b/src/mongo/s/commands/cluster_rwc_defaults_commands.cpp
@@ -172,7 +172,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/s/commands/cluster_shard_collection_cmd.cpp b/src/mongo/s/commands/cluster_shard_collection_cmd.cpp
index 9d7b8c22353..cab047e6ade 100644
--- a/src/mongo/s/commands/cluster_shard_collection_cmd.cpp
+++ b/src/mongo/s/commands/cluster_shard_collection_cmd.cpp
@@ -80,7 +80,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_split_cmd.cpp b/src/mongo/s/commands/cluster_split_cmd.cpp
index 0b8deb18b26..0e4d2c44ae1 100644
--- a/src/mongo/s/commands/cluster_split_cmd.cpp
+++ b/src/mongo/s/commands/cluster_split_cmd.cpp
@@ -123,7 +123,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool errmsgRun(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_split_vector_cmd.cpp b/src/mongo/s/commands/cluster_split_vector_cmd.cpp
index 0de63a429c0..2a4ccd15cb0 100644
--- a/src/mongo/s/commands/cluster_split_vector_cmd.cpp
+++ b/src/mongo/s/commands/cluster_split_vector_cmd.cpp
@@ -50,7 +50,8 @@ public:
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
- return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
+ return NamespaceStringUtil::parseNamespaceFromRequest(
+ dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
bool supportsWriteConcern(const BSONObj& cmd) const override {
diff --git a/src/mongo/s/commands/cluster_user_management_commands.cpp b/src/mongo/s/commands/cluster_user_management_commands.cpp
index c735219739d..42512a64b3e 100644
--- a/src/mongo/s/commands/cluster_user_management_commands.cpp
+++ b/src/mongo/s/commands/cluster_user_management_commands.cpp
@@ -174,9 +174,10 @@ public:
NamespaceString ns() const override {
const auto& cmd = request();
if constexpr (hasGetCmdParamStringData<RequestT>) {
- return NamespaceString(cmd.getDbName(), cmd.getCommandParameter());
+ return NamespaceStringUtil::parseNamespaceFromRequest(cmd.getDbName(),
+ cmd.getCommandParameter());
} else {
- return NamespaceString(cmd.getDbName(), "");
+ return NamespaceString(cmd.getDbName());
}
}
};
@@ -264,7 +265,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
@@ -299,7 +300,7 @@ public:
}
NamespaceString ns() const override {
- return NamespaceString(request().getDbName(), "");
+ return NamespaceString(request().getDbName());
}
};
diff --git a/src/mongo/s/commands/internal_transactions_test_command.h b/src/mongo/s/commands/internal_transactions_test_command.h
index 45d966a1846..d8374b7aa90 100644
--- a/src/mongo/s/commands/internal_transactions_test_command.h
+++ b/src/mongo/s/commands/internal_transactions_test_command.h
@@ -124,7 +124,7 @@ public:
};
NamespaceString ns() const override {
- return NamespaceString(Base::request().getDbName(), "");
+ return NamespaceString(Base::request().getDbName());
}
bool supportsWriteConcern() const override {
diff --git a/src/mongo/s/commands/sharding_expressions.cpp b/src/mongo/s/commands/sharding_expressions.cpp
index a4525e64656..e20683d251e 100644
--- a/src/mongo/s/commands/sharding_expressions.cpp
+++ b/src/mongo/s/commands/sharding_expressions.cpp
@@ -372,7 +372,8 @@ Value ExpressionInternalOwningShard::evaluate(const Document& root, Variables* v
}
// Retrieve the values from the incoming document.
- NamespaceString ns(getExpressionContext()->ns.tenantId(), input["ns"_sd].getStringData());
+ NamespaceString ns(NamespaceStringUtil::parseNamespaceFromDoc(
+ getExpressionContext()->ns.tenantId(), input["ns"_sd].getStringData()));
const auto shardVersionObj = input["shardVersion"_sd].getDocument().toBson();
const auto shardVersion = ShardVersion::parse(BSON("" << shardVersionObj).firstElement());
const auto shardKeyVal = input["shardKeyVal"_sd].getDocument().toBson();
diff --git a/src/mongo/s/query/cluster_find.cpp b/src/mongo/s/query/cluster_find.cpp
index faa516ca359..20899afae5c 100644
--- a/src/mongo/s/query/cluster_find.cpp
+++ b/src/mongo/s/query/cluster_find.cpp
@@ -778,7 +778,8 @@ StatusWith<CursorResponse> ClusterFind::runGetMore(OperationContext* opCtx,
: Status(ErrorCodes::Unauthorized, "User not authorized to access cursor");
};
- NamespaceString nss(cmd.getDbName(), cmd.getCollection());
+ NamespaceString nss(
+ NamespaceStringUtil::parseNamespaceFromRequest(cmd.getDbName(), cmd.getCollection()));
int64_t cursorId = cmd.getCommandParameter();
auto pinnedCursor = cursorManager->checkOutCursor(cursorId, opCtx, authChecker);
diff --git a/src/mongo/shell/bench.cpp b/src/mongo/shell/bench.cpp
index 7e4ee3ae10d..b71e82a5a50 100644
--- a/src/mongo/shell/bench.cpp
+++ b/src/mongo/shell/bench.cpp
@@ -1049,8 +1049,8 @@ void BenchRunOp::executeOnce(DBClientBase* conn,
case OpType::FINDONE: {
BSONObj fixedQuery = fixQuery(this->query, *state->bsonTemplateEvaluator);
BSONObj result;
- auto findCommand =
- std::make_unique<FindCommandRequest>(NamespaceString(this->tenantId, this->ns));
+ auto findCommand = std::make_unique<FindCommandRequest>(
+ NamespaceString::createNamespaceString_forTest(this->tenantId, this->ns));
findCommand->setFilter(fixedQuery);
findCommand->setProjection(this->projection);
findCommand->setLimit(1LL);
@@ -1137,8 +1137,8 @@ void BenchRunOp::executeOnce(DBClientBase* conn,
uassert(
28824, "cannot use 'options' in combination with read commands", !this->options);
- auto findCommand =
- std::make_unique<FindCommandRequest>(NamespaceString(this->tenantId, this->ns));
+ auto findCommand = std::make_unique<FindCommandRequest>(
+ NamespaceString::createNamespaceString_forTest(this->tenantId, this->ns));
findCommand->setFilter(fixedQuery);
findCommand->setProjection(this->projection);
if (this->skip) {
@@ -1337,14 +1337,16 @@ void BenchRunOp::executeOnce(DBClientBase* conn,
22801, 5, "Result from benchRun thread [safe remove]", "result"_attr = result);
} break;
case OpType::CREATEINDEX:
- conn->createIndex(NamespaceString(this->tenantId, this->ns),
- this->key,
- boost::none /* writeConcernObj */);
+ conn->createIndex(
+ NamespaceString::createNamespaceString_forTest(this->tenantId, this->ns),
+ this->key,
+ boost::none /* writeConcernObj */);
break;
case OpType::DROPINDEX:
- conn->dropIndex(NamespaceString(this->tenantId, this->ns),
- this->key,
- boost::none /* writeConcernObj */);
+ conn->dropIndex(
+ NamespaceString::createNamespaceString_forTest(this->tenantId, this->ns),
+ this->key,
+ boost::none /* writeConcernObj */);
break;
case OpType::LET: {
BSONObjBuilder templateBuilder;
diff --git a/src/mongo/util/namespace_string_util.cpp b/src/mongo/util/namespace_string_util.cpp
index 26322d4af70..5084a0c2ee4 100644
--- a/src/mongo/util/namespace_string_util.cpp
+++ b/src/mongo/util/namespace_string_util.cpp
@@ -92,4 +92,68 @@ NamespaceString NamespaceStringUtil::deserialize(boost::optional<TenantId> tenan
return nss;
}
+NamespaceString NamespaceStringUtil::parseNamespaceFromRequest(
+ const boost::optional<TenantId>& tenantId, StringData ns) {
+ return deserialize(tenantId, ns);
+}
+
+NamespaceString NamespaceStringUtil::parseNamespaceFromRequest(
+ const boost::optional<TenantId>& tenantId, StringData db, StringData coll) {
+ if (coll.empty())
+ return deserialize(tenantId, db);
+
+ uassert(ErrorCodes::InvalidNamespace,
+ "Collection names cannot start with '.': " + coll,
+ coll[0] != '.');
+
+ return deserialize(tenantId, str::stream() << db << "." << coll);
+}
+
+NamespaceString NamespaceStringUtil::parseNamespaceFromRequest(const DatabaseName& dbName,
+ StringData coll) {
+ if (coll.empty()) {
+ return NamespaceString(dbName);
+ }
+
+ uassert(ErrorCodes::InvalidNamespace,
+ "Collection names cannot start with '.': " + coll,
+ coll[0] != '.');
+
+ return deserialize(dbName.tenantId(), str::stream() << dbName.db() << "." << coll);
+}
+
+NamespaceString NamespaceStringUtil::parseNamespaceFromDoc(
+ const boost::optional<TenantId>& tenantId, StringData ns) {
+ return deserialize(tenantId, ns);
+}
+
+NamespaceString NamespaceStringUtil::parseNamespaceFromDoc(
+ const boost::optional<TenantId>& tenantId, StringData db, StringData coll) {
+ if (coll.empty())
+ return deserialize(tenantId, db);
+
+ uassert(ErrorCodes::InvalidNamespace,
+ "Collection names cannot start with '.': " + coll,
+ coll[0] != '.');
+
+ return deserialize(tenantId, str::stream() << db << "." << coll);
+}
+
+NamespaceString NamespaceStringUtil::parseNamespaceFromDoc(const DatabaseName& dbName,
+ StringData coll) {
+ if (coll.empty())
+ return NamespaceString(dbName);
+
+ uassert(ErrorCodes::InvalidNamespace,
+ "Collection names cannot start with '.': " + coll,
+ coll[0] != '.');
+
+ return deserialize(dbName.tenantId(), str::stream() << dbName.db() << "." << coll);
+}
+
+NamespaceString NamespaceStringUtil::parseNamespaceFromResponse(const DatabaseName& dbName,
+ StringData coll) {
+ return parseNamespaceFromDoc(dbName, coll);
+}
+
} // namespace mongo
diff --git a/src/mongo/util/namespace_string_util.h b/src/mongo/util/namespace_string_util.h
index 23aebf90362..20e69c3fe17 100644
--- a/src/mongo/util/namespace_string_util.h
+++ b/src/mongo/util/namespace_string_util.h
@@ -77,6 +77,26 @@ public:
boost::optional<TenantId> tenantId,
StringData ns,
const SerializationContext& context = SerializationContext());
+
+ static NamespaceString parseNamespaceFromRequest(const boost::optional<TenantId>& tenantId,
+ StringData ns);
+
+ static NamespaceString parseNamespaceFromRequest(const boost::optional<TenantId>& tenantId,
+ StringData db,
+ StringData coll);
+
+ static NamespaceString parseNamespaceFromRequest(const DatabaseName& dbName, StringData coll);
+
+ static NamespaceString parseNamespaceFromDoc(const boost::optional<TenantId>& tenantId,
+ StringData ns);
+
+ static NamespaceString parseNamespaceFromDoc(const boost::optional<TenantId>& tenantId,
+ StringData db,
+ StringData coll);
+
+ static NamespaceString parseNamespaceFromDoc(const DatabaseName& dbName, StringData coll);
+
+ static NamespaceString parseNamespaceFromResponse(const DatabaseName& dbName, StringData coll);
};
} // namespace mongo