diff --git a/buildscripts/idl/idl/struct_types.py b/buildscripts/idl/idl/struct_types.py index 3d44458a436..760c4dd5358 100644 --- a/buildscripts/idl/idl/struct_types.py +++ b/buildscripts/idl/idl/struct_types.py @@ -562,8 +562,9 @@ class _CommandWithNamespaceTypeInfo(_CommandBaseTypeInfo): indented_writer.write_line('invariant(_nss.isEmpty());') allow_global = 'true' if self._struct.allow_global_collection_name else 'false' indented_writer.write_line( - '_nss = ctxt.parseNSCollectionRequired(%s, %s, %s);' % (db_name, element, allow_global)) - + 'auto collectionName = ctxt.checkAndAssertCollectionName(%s, %s);' % (element, allow_global)) + indented_writer.write_line('_nss = NamespaceStringUtil::parseNamespaceFromRequest(%s, collectionName);' % (db_name)) + indented_writer.write_line('uassert(ErrorCodes::InvalidNamespace, str::stream() << "Invalid namespace specified '" << _nss.ns() << "'", _nss.isValid());') class _CommandWithUUIDNamespaceTypeInfo(_CommandBaseTypeInfo): """Class for command with namespace or UUID code generation.""" @@ -633,7 +634,9 @@ class _CommandWithUUIDNamespaceTypeInfo(_CommandBaseTypeInfo): def gen_namespace_check(self, indented_writer, db_name, element): # type: (writer.IndentedTextWriter, str, str) -> None indented_writer.write_line('invariant(_nssOrUUID.nss() || _nssOrUUID.uuid());') - indented_writer.write_line('_nssOrUUID = ctxt.parseNsOrUUID(%s, %s);' % (db_name, element)) + indented_writer.write_line('auto collOrUUID = ctxt.checkAndAssertCollectionNameOrUUID(%s);' % (element)) + indented_writer.write_line('_nssOrUUID = stdx::holds_alternative(collOrUUID) ? NamespaceStringUtil::parseNamespaceFromRequest(%s, stdx::get(collOrUUID)) : NamespaceStringOrUUID(%s, stdx::get(collOrUUID));' % (db_name, db_name)) + indented_writer.write_line('uassert(ErrorCodes::InvalidNamespace, str::stream() << "Invalid namespace specified '" << _nssOrUUID.nss()->ns() << "'", _nssOrUUID.nss() ? _nssOrUUID.nss()->isValid() : true);') def get_struct_info(struct): diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h index e83e5d6abab..948ff12ae7b 100644 --- a/src/mongo/db/namespace_string.h +++ b/src/mongo/db/namespace_string.h @@ -48,7 +48,6 @@ namespace mongo { class NamespaceStringUtil; -class IDLParserContext; class NamespaceString { public: @@ -752,7 +751,6 @@ public: private: friend NamespaceStringUtil; - friend IDLParserContext; /** * In order to construct NamespaceString objects, use NamespaceStringUtil. The functions diff --git a/src/mongo/idl/idl_parser.cpp b/src/mongo/idl/idl_parser.cpp index b847cd7e90d..5bded0b0335 100644 --- a/src/mongo/idl/idl_parser.cpp +++ b/src/mongo/idl/idl_parser.cpp @@ -240,11 +240,10 @@ void IDLParserContext::throwAPIStrictErrorIfApplicable(StringData fieldName) con !_apiStrict); } -NamespaceString IDLParserContext::parseNSCollectionRequired(const DatabaseName& dbName, - const BSONElement& element, +StringData IDLParserContext::checkAndAssertCollectionName(const BSONElement& element, bool allowGlobalCollectionName) { - const bool isUUID = (element.canonicalType() == canonicalizeBSONType(mongo::BinData) && - element.binDataType() == BinDataType::newUUID); + const bool isUUID = (element.canonicalType() == canonicalizeBSONType(mongo::BinData) && + element.binDataType() == BinDataType::newUUID); uassert(ErrorCodes::BadValue, str::stream() << "Collection name must be provided. UUID is not valid in this " << "context", @@ -255,29 +254,22 @@ NamespaceString IDLParserContext::parseNSCollectionRequired(const DatabaseName& str::stream() << "Invalid command format: the '" << element.fieldNameStringData() << "' field must specify a collection name or 1", element.number() == 1); - return NamespaceString(dbName, collectionlessAggregateCursorCol); + return collectionlessAggregateCursorCol; } uassert(ErrorCodes::BadValue, - str::stream() << "collection name has invalid type " << typeName(element.type()), + str::stream() << "collection name has invalid type " << typeName(element.type()), element.canonicalType() == canonicalizeBSONType(mongo::String)); - - const NamespaceString nss(dbName, element.valueStringData()); - - uassert(ErrorCodes::InvalidNamespace, - str::stream() << "Invalid namespace specified '" << nss.ns() << "'", - nss.isValid()); - - return nss; + + return element.valueStringData(); } -NamespaceStringOrUUID IDLParserContext::parseNsOrUUID(const DatabaseName& dbName, - const BSONElement& element) { +stdx::variant IDLParserContext::checkAndAssertCollectionNameOrUUID(const BSONElement& element) { if (element.type() == BinData && element.binDataType() == BinDataType::newUUID) { - return {dbName, uassertStatusOK(UUID::parse(element))}; + return uassertStatusOK(UUID::parse(element)); } else { // Ensure collection identifier is not a Command - return {parseNSCollectionRequired(dbName, element, false)}; + return checkAndAssertCollectionName(element, false); } } diff --git a/src/mongo/idl/idl_parser.h b/src/mongo/idl/idl_parser.h index 6b68eebf7d9..f0fea2cdd17 100644 --- a/src/mongo/idl/idl_parser.h +++ b/src/mongo/idl/idl_parser.h @@ -359,18 +359,17 @@ public: void throwAPIStrictErrorIfApplicable(BSONElement fieldName) const; /** - * Equivalent to CommandHelpers::parseNsCollectionRequired. - * 'allowGlobalCollectionName' allows use of global collection name, e.g. {aggregate: 1}. + * Check that the collection name in 'element' is valid. Throws an exception if not valid. + * Returns the collection name otherwise. */ - static NamespaceString parseNSCollectionRequired(const DatabaseName& dbname, - const BSONElement& element, - bool allowGlobalCollectionName); + static StringData checkAndAssertCollectionName(const BSONElement& element, + bool allowGlobalCollectionName); /** - * Equivalent to CommandHelpers::parseNsOrUUID + * Check that the collection name or UUID in 'element' is valid. Throws an exception if not + * valid. Returns either the collection name or UUID otherwise. */ - static NamespaceStringOrUUID parseNsOrUUID(const DatabaseName& dbname, - const BSONElement& element); + static stdx::variant checkAndAssertCollectionNameOrUUID(const BSONElement& element); /** * Take all the well known command generic arguments from commandPassthroughFields, but ignore