diff options
author | Gregory Wlodarek <gregory.wlodarek@mongodb.com> | 2019-07-29 21:00:16 -0400 |
---|---|---|
committer | Gregory Wlodarek <gregory.wlodarek@mongodb.com> | 2019-07-29 21:06:47 -0400 |
commit | 0d6d248c39a5b4e43eefc9320b5dec3229cfcfdb (patch) | |
tree | 1fb67633d3c9c551341dbf41efb47a80c6392553 /src/mongo/db/catalog | |
parent | 47d0308cd596c6d40d6a3069379be1bdaf51d47b (diff) | |
download | mongo-0d6d248c39a5b4e43eefc9320b5dec3229cfcfdb.tar.gz |
SERVER-41696 Remove the 'ns' field from index specs
Diffstat (limited to 'src/mongo/db/catalog')
-rw-r--r-- | src/mongo/db/catalog/SConscript | 14 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/catalog/database_test.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/catalog/disable_index_spec_namespace_generation.idl | 41 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_builds_manager_test.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_entry.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_entry_impl.cpp | 43 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_entry_impl.h | 9 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_impl.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_impl.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_noop.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_key_validate.cpp | 57 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_key_validate.h | 1 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_spec_validate_test.cpp | 200 | ||||
-rw-r--r-- | src/mongo/db/catalog/rename_collection.cpp | 25 | ||||
-rw-r--r-- | src/mongo/db/catalog/rename_collection_test.cpp | 2 |
17 files changed, 92 insertions, 355 deletions
diff --git a/src/mongo/db/catalog/SConscript b/src/mongo/db/catalog/SConscript index c2a92d5acca..369017cd7d3 100644 --- a/src/mongo/db/catalog/SConscript +++ b/src/mongo/db/catalog/SConscript @@ -114,16 +114,6 @@ env.Library( ) env.Library( - target='disable_index_spec_namespace_generation', - source=[ - env.Idlc('disable_index_spec_namespace_generation.idl')[0], - ], - LIBDEPS_PRIVATE=[ - '$BUILD_DIR/mongo/idl/server_parameter', - ], -) - -env.Library( target='index_key_validate', source=[ "index_key_validate.cpp", @@ -138,9 +128,6 @@ env.Library( '$BUILD_DIR/mongo/db/query/collation/collator_factory_interface', '$BUILD_DIR/mongo/util/fail_point', ], - LIBDEPS_PRIVATE=[ - 'disable_index_spec_namespace_generation', - ], ) env.Library( @@ -331,7 +318,6 @@ env.Library( ], LIBDEPS_PRIVATE=[ 'index_build_block', - 'disable_index_spec_namespace_generation', '$BUILD_DIR/mongo/db/catalog/collection_catalog_helper', '$BUILD_DIR/mongo/db/commands/server_status_core', '$BUILD_DIR/mongo/db/index/index_build_interceptor', diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp index 6ebdaf1ec51..2d441c2b2f6 100644 --- a/src/mongo/db/catalog/collection_impl.cpp +++ b/src/mongo/db/catalog/collection_impl.cpp @@ -1051,7 +1051,6 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> CollectionImpl::makePlanExe void CollectionImpl::setNs(NamespaceString nss) { _ns = std::move(nss); - _indexCatalog->setNs(_ns); _infoCache->setNs(_ns); _recordStore.get()->setNs(_ns); } diff --git a/src/mongo/db/catalog/database_test.cpp b/src/mongo/db/catalog/database_test.cpp index 542cae76e80..173e797851d 100644 --- a/src/mongo/db/catalog/database_test.cpp +++ b/src/mongo/db/catalog/database_test.cpp @@ -301,8 +301,7 @@ void _testDropCollectionThrowsExceptionIfThereAreIndexesInProgress(OperationCont ASSERT_EQUALS(indexCatalog->numIndexesInProgress(opCtx), 0); auto indexInfoObj = BSON("v" << int(IndexDescriptor::kLatestIndexVersion) << "key" << BSON("a" << 1) << "name" - << "a_1" - << "ns" << nss.ns()); + << "a_1"); auto indexBuildBlock = std::make_unique<IndexBuildBlock>( indexCatalog, collection->ns(), indexInfoObj, IndexBuildMethod::kHybrid); diff --git a/src/mongo/db/catalog/disable_index_spec_namespace_generation.idl b/src/mongo/db/catalog/disable_index_spec_namespace_generation.idl deleted file mode 100644 index c750956396c..00000000000 --- a/src/mongo/db/catalog/disable_index_spec_namespace_generation.idl +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2019-present MongoDB, Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the Server Side Public License, version 1, -# as published by MongoDB, Inc. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# Server Side Public License for more details. -# -# You should have received a copy of the Server Side Public License -# along with this program. If not, see -# <http://www.mongodb.com/licensing/server-side-public-license>. -# -# As a special exception, the copyright holders give permission to link the -# code of portions of this program with the OpenSSL library under certain -# conditions as described in each individual source file and distribute -# linked combinations including the program with the OpenSSL library. You -# must comply with the Server Side Public License in all respects for -# all of the code used other than as permitted herein. If you modify file(s) -# with this exception, you may extend this exception to your version of the -# file(s), but you are not obligated to do so. If you do not wish to do so, -# delete this exception statement from your version. If you delete this -# exception statement from all source files in the program, then also delete -# it in the license file. -# - -global: - cpp_namespace: "mongo" - -server_parameters: - disableIndexSpecNamespaceGeneration: - description: "If enabled, the 'ns' field will not be generated for index specs if it's missing." - set_at: - - startup - - runtime - cpp_vartype: AtomicWord<bool> - cpp_varname: "disableIndexSpecNamespaceGeneration" - default: false - test_only: true diff --git a/src/mongo/db/catalog/index_builds_manager_test.cpp b/src/mongo/db/catalog/index_builds_manager_test.cpp index df5e50d244c..3ca43d04039 100644 --- a/src/mongo/db/catalog/index_builds_manager_test.cpp +++ b/src/mongo/db/catalog/index_builds_manager_test.cpp @@ -75,8 +75,8 @@ std::vector<BSONObj> makeSpecs(const NamespaceString& nss, std::vector<std::stri ASSERT(keys.size()); std::vector<BSONObj> indexSpecs; for (auto keyName : keys) { - indexSpecs.push_back(BSON("ns" << nss.toString() << "v" << 2 << "key" << BSON(keyName << 1) - << "name" << (keyName + "_1"))); + indexSpecs.push_back( + BSON("v" << 2 << "key" << BSON(keyName << 1) << "name" << (keyName + "_1"))); } return indexSpecs; } diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h index de87ee6a172..8a069ea65a0 100644 --- a/src/mongo/db/catalog/index_catalog.h +++ b/src/mongo/db/catalog/index_catalog.h @@ -470,8 +470,6 @@ public: const IndexDescriptor* desc, InsertDeleteOptions* options) const = 0; - virtual void setNs(NamespaceString ns) = 0; - virtual void indexBuildSuccess(OperationContext* opCtx, IndexCatalogEntry* index) = 0; }; } // namespace mongo diff --git a/src/mongo/db/catalog/index_catalog_entry.h b/src/mongo/db/catalog/index_catalog_entry.h index de034469453..863718a57fc 100644 --- a/src/mongo/db/catalog/index_catalog_entry.h +++ b/src/mongo/db/catalog/index_catalog_entry.h @@ -138,8 +138,6 @@ public: virtual boost::optional<Timestamp> getMinimumVisibleSnapshot() = 0; virtual void setMinimumVisibleSnapshot(const Timestamp name) = 0; - - virtual void setNs(NamespaceString ns) = 0; }; class IndexCatalogEntryContainer { diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.cpp b/src/mongo/db/catalog/index_catalog_entry_impl.cpp index 9a30dfc9687..1cd68cd0900 100644 --- a/src/mongo/db/catalog/index_catalog_entry_impl.cpp +++ b/src/mongo/db/catalog/index_catalog_entry_impl.cpp @@ -37,6 +37,7 @@ #include <memory> #include "mongo/base/init.h" +#include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/collection_info_cache_impl.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/write_conflict_exception.h" @@ -59,15 +60,14 @@ namespace mongo { using std::string; IndexCatalogEntryImpl::IndexCatalogEntryImpl(OperationContext* const opCtx, - const NamespaceString& nss, std::unique_ptr<IndexDescriptor> descriptor, CollectionInfoCache* const infoCache) - : _ns(nss), - _descriptor(std::move(descriptor)), + : _descriptor(std::move(descriptor)), _infoCache(infoCache), _ordering(Ordering::make(_descriptor->keyPattern())), _isReady(false), - _prefix(DurableCatalog::get(opCtx)->getIndexPrefix(opCtx, nss, _descriptor->indexName())) { + _prefix(DurableCatalog::get(opCtx)->getIndexPrefix( + opCtx, _descriptor->parentNS(), _descriptor->indexName())) { _descriptor->_cachedEntry = this; _isReady = _catalogIsReady(opCtx); @@ -104,7 +104,7 @@ IndexCatalogEntryImpl::IndexCatalogEntryImpl(OperationContext* const opCtx, MatchExpressionParser::kBanAllSpecialFeatures); invariant(statusWithMatcher.getStatus()); _filterExpression = std::move(statusWithMatcher.getValue()); - LOG(2) << "have filter expression for " << _ns << " " << _descriptor->indexName() << " " + LOG(2) << "have filter expression for " << ns() << " " << _descriptor->indexName() << " " << redact(filter); } } @@ -115,6 +115,10 @@ IndexCatalogEntryImpl::~IndexCatalogEntryImpl() { _descriptor.reset(); } +const NamespaceString& IndexCatalogEntryImpl::ns() const { + return _descriptor->parentNS(); +} + void IndexCatalogEntryImpl::init(std::unique_ptr<IndexAccessMethod> accessMethod) { invariant(!_accessMethod); _accessMethod = std::move(accessMethod); @@ -157,7 +161,7 @@ bool IndexCatalogEntryImpl::isMultikey(OperationContext* opCtx) const { } for (const MultikeyPathInfo& path : txnParticipant.getUncommittedMultikeyPathInfos()) { - if (path.nss == NamespaceString(_ns) && path.indexName == _descriptor->indexName()) { + if (path.nss == ns() && path.indexName == _descriptor->indexName()) { return true; } } @@ -175,7 +179,7 @@ MultikeyPaths IndexCatalogEntryImpl::getMultikeyPaths(OperationContext* opCtx) c MultikeyPaths ret = _indexMultikeyPaths; for (const MultikeyPathInfo& path : txnParticipant.getUncommittedMultikeyPathInfos()) { - if (path.nss == NamespaceString(_ns) && path.indexName == _descriptor->indexName()) { + if (path.nss == ns() && path.indexName == _descriptor->indexName()) { MultikeyPathTracker::mergeMultikeyPaths(&ret, path.multikeyPaths); } } @@ -251,7 +255,7 @@ void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx, // OperationContext and we can safely defer that write to the end of the batch. if (MultikeyPathTracker::get(opCtx).isTrackingMultikeyPathInfo()) { MultikeyPathInfo info; - info.nss = _ns; + info.nss = ns(); info.indexName = _descriptor->indexName(); info.multikeyPaths = paths; MultikeyPathTracker::get(opCtx).addMultikeyPathInfo(info); @@ -279,7 +283,7 @@ void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx, } if (indexMetadataHasChanged && _infoCache) { - LOG(1) << _ns << ": clearing plan cache - index " << _descriptor->keyPattern() + LOG(1) << ns() << ": clearing plan cache - index " << _descriptor->keyPattern() << " set to multi key."; _infoCache->clearQueryCache(); } @@ -294,7 +298,7 @@ void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx, auto txnParticipant = TransactionParticipant::get(opCtx); if (txnParticipant && txnParticipant.inMultiDocumentTransaction()) { TransactionParticipant::SideTransactionBlock sideTxn(opCtx); - writeConflictRetry(opCtx, "set index multikey", _ns.ns(), [&] { + writeConflictRetry(opCtx, "set index multikey", ns().ns(), [&] { WriteUnitOfWork wuow(opCtx); // If we have a prepare optime for recovery, then we always use that. During recovery of @@ -316,7 +320,7 @@ void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx, } fassert(31164, status); indexMetadataHasChanged = DurableCatalog::get(opCtx)->setIndexIsMultikey( - opCtx, _ns, _descriptor->indexName(), paths); + opCtx, ns(), _descriptor->indexName(), paths); opCtx->recoveryUnit()->onCommit( [onMultikeyCommitFn, indexMetadataHasChanged](boost::optional<Timestamp>) { onMultikeyCommitFn(indexMetadataHasChanged); @@ -325,7 +329,7 @@ void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx, }); } else { indexMetadataHasChanged = DurableCatalog::get(opCtx)->setIndexIsMultikey( - opCtx, _ns, _descriptor->indexName(), paths); + opCtx, ns(), _descriptor->indexName(), paths); } opCtx->recoveryUnit()->onCommit( @@ -342,33 +346,28 @@ void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx, // previous write in the transaction. if (txnParticipant && txnParticipant.inMultiDocumentTransaction()) { txnParticipant.addUncommittedMultikeyPathInfo( - MultikeyPathInfo{_ns, _descriptor->indexName(), std::move(paths)}); + MultikeyPathInfo{ns(), _descriptor->indexName(), std::move(paths)}); } } -void IndexCatalogEntryImpl::setNs(NamespaceString ns) { - _ns = ns; - _descriptor->setNs(std::move(ns)); -} - // ---- bool IndexCatalogEntryImpl::_catalogIsReady(OperationContext* opCtx) const { - return DurableCatalog::get(opCtx)->isIndexReady(opCtx, _ns, _descriptor->indexName()); + return DurableCatalog::get(opCtx)->isIndexReady(opCtx, ns(), _descriptor->indexName()); } bool IndexCatalogEntryImpl::_catalogIsPresent(OperationContext* opCtx) const { - return DurableCatalog::get(opCtx)->isIndexPresent(opCtx, _ns, _descriptor->indexName()); + return DurableCatalog::get(opCtx)->isIndexPresent(opCtx, ns(), _descriptor->indexName()); } bool IndexCatalogEntryImpl::_catalogIsMultikey(OperationContext* opCtx, MultikeyPaths* multikeyPaths) const { return DurableCatalog::get(opCtx)->isIndexMultikey( - opCtx, _ns, _descriptor->indexName(), multikeyPaths); + opCtx, ns(), _descriptor->indexName(), multikeyPaths); } KVPrefix IndexCatalogEntryImpl::_catalogGetPrefix(OperationContext* opCtx) const { - return DurableCatalog::get(opCtx)->getIndexPrefix(opCtx, _ns, _descriptor->indexName()); + return DurableCatalog::get(opCtx)->getIndexPrefix(opCtx, ns(), _descriptor->indexName()); } } // namespace mongo diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.h b/src/mongo/db/catalog/index_catalog_entry_impl.h index cb697a3d177..525b003b878 100644 --- a/src/mongo/db/catalog/index_catalog_entry_impl.h +++ b/src/mongo/db/catalog/index_catalog_entry_impl.h @@ -59,17 +59,12 @@ class IndexCatalogEntryImpl : public IndexCatalogEntry { public: explicit IndexCatalogEntryImpl( OperationContext* opCtx, - const NamespaceString& nss, std::unique_ptr<IndexDescriptor> descriptor, // ownership passes to me CollectionInfoCache* infoCache); // not owned, optional ~IndexCatalogEntryImpl() final; - const NamespaceString& ns() const final { - return _ns; - } - - void setNs(NamespaceString ns) final; + const NamespaceString& ns() const final; void init(std::unique_ptr<IndexAccessMethod> accessMethod) final; @@ -192,8 +187,6 @@ private: // ----- - NamespaceString _ns; - std::unique_ptr<IndexDescriptor> _descriptor; // owned here CollectionInfoCache* _infoCache; // not owned here diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp index a4d4c6ec5b8..261f656d77c 100644 --- a/src/mongo/db/catalog/index_catalog_impl.cpp +++ b/src/mongo/db/catalog/index_catalog_impl.cpp @@ -41,7 +41,6 @@ #include "mongo/db/audit.h" #include "mongo/db/background.h" #include "mongo/db/catalog/collection.h" -#include "mongo/db/catalog/disable_index_spec_namespace_generation_gen.h" #include "mongo/db/catalog/index_build_block.h" #include "mongo/db/catalog/index_catalog_entry_impl.h" #include "mongo/db/catalog/index_key_validate.h" @@ -373,7 +372,7 @@ IndexCatalogEntry* IndexCatalogImpl::createIndexEntry(OperationContext* opCtx, auto* const descriptorPtr = descriptor.get(); auto entry = std::make_shared<IndexCatalogEntryImpl>( - opCtx, _collection->ns(), std::move(descriptor), _collection->infoCache()); + opCtx, std::move(descriptor), _collection->infoCache()); IndexDescriptor* desc = entry->descriptor(); @@ -531,21 +530,6 @@ Status IndexCatalogImpl::_isSpecOk(OperationContext* opCtx, const BSONObj& spec) if (nss.isOplog()) return Status(ErrorCodes::CannotCreateIndex, "cannot have an index on the oplog"); - // If we stop generating the 'ns' field for index specs during testing, then we shouldn't - // validate that the 'ns' field is missing. - if (!disableIndexSpecNamespaceGeneration.load()) { - const BSONElement specNamespace = spec["ns"]; - if (specNamespace.type() != String) - return Status(ErrorCodes::CannotCreateIndex, - "the index spec is missing a \"ns\" string field"); - - if (nss.ns() != specNamespace.valueStringData()) - return Status(ErrorCodes::CannotCreateIndex, - str::stream() << "the \"ns\" field of the index spec '" - << specNamespace.valueStringData() - << "' does not match the collection name '" << nss << "'"); - } - // logical name of the index const BSONElement nameElem = spec["name"]; if (nameElem.type() != String) @@ -811,7 +795,6 @@ BSONObj IndexCatalogImpl::getDefaultIdIndexSpec() const { BSONObjBuilder b; b.append("v", static_cast<int>(indexVersion)); b.append("name", "_id_"); - b.append("ns", _collection->ns().ns()); b.append("key", _idObj); if (_collection->getDefaultCollator() && indexVersion >= IndexVersion::kV2) { // Creating an index with the "collation" option requires a v=2 index. @@ -1660,6 +1643,14 @@ StatusWith<BSONObj> IndexCatalogImpl::_fixIndexSpec(OperationContext* opCtx, } b.append("name", name); + // During repair, if the 'ns' field exists in the index spec, do not remove it as repair can be + // running on old data files from other mongod versions. Removing the 'ns' field during repair + // would prevent the data files from starting up on the original mongod version as the 'ns' + // field is required to be present in 3.6 and 4.0. + if (storageGlobalParams.repair && o.hasField("ns")) { + b.append("ns", o.getField("ns").String()); + } + { BSONObjIterator i(o); while (i.more()) { @@ -1668,8 +1659,9 @@ StatusWith<BSONObj> IndexCatalogImpl::_fixIndexSpec(OperationContext* opCtx, if (s == "_id") { // skip - } else if (s == "dropDups") { + } else if (s == "dropDups" || s == "ns") { // dropDups is silently ignored and removed from the spec as of SERVER-14710. + // ns is removed from the spec as of 4.4. } else if (s == "v" || s == "unique" || s == "key" || s == "name") { // covered above } else { @@ -1681,13 +1673,4 @@ StatusWith<BSONObj> IndexCatalogImpl::_fixIndexSpec(OperationContext* opCtx, return b.obj(); } -void IndexCatalogImpl::setNs(NamespaceString ns) { - for (auto&& ice : _readyIndexes) { - ice->setNs(ns); - } - - for (auto&& ice : _buildingIndexes) { - ice->setNs(ns); - } -} } // namespace mongo diff --git a/src/mongo/db/catalog/index_catalog_impl.h b/src/mongo/db/catalog/index_catalog_impl.h index 813c90b3d4e..9eecee90e52 100644 --- a/src/mongo/db/catalog/index_catalog_impl.h +++ b/src/mongo/db/catalog/index_catalog_impl.h @@ -296,8 +296,6 @@ public: const IndexDescriptor* desc, InsertDeleteOptions* options) const override; - void setNs(NamespaceString ns) override; - void indexBuildSuccess(OperationContext* opCtx, IndexCatalogEntry* index) override; private: diff --git a/src/mongo/db/catalog/index_catalog_noop.h b/src/mongo/db/catalog/index_catalog_noop.h index a9caf06f132..8590d18b37d 100644 --- a/src/mongo/db/catalog/index_catalog_noop.h +++ b/src/mongo/db/catalog/index_catalog_noop.h @@ -236,8 +236,6 @@ public: const IndexDescriptor* desc, InsertDeleteOptions* options) const override {} - void setNs(NamespaceString ns) override {} - void indexBuildSuccess(OperationContext* opCtx, IndexCatalogEntry* index) override {} }; diff --git a/src/mongo/db/catalog/index_key_validate.cpp b/src/mongo/db/catalog/index_key_validate.cpp index 2bc450516fb..83c6812f5b1 100644 --- a/src/mongo/db/catalog/index_key_validate.cpp +++ b/src/mongo/db/catalog/index_key_validate.cpp @@ -40,7 +40,6 @@ #include "mongo/base/status.h" #include "mongo/base/status_with.h" -#include "mongo/db/catalog/disable_index_spec_namespace_generation_gen.h" #include "mongo/db/field_ref.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index/wildcard_key_generator.h" @@ -255,7 +254,6 @@ BSONObj removeUnknownFields(const BSONObj& indexSpec) { StatusWith<BSONObj> validateIndexSpec( OperationContext* opCtx, const BSONObj& indexSpec, - const NamespaceString& expectedNamespace, const ServerGlobalParams::FeatureCompatibility& featureCompatibility) { bool hasKeyPatternField = false; bool hasIndexNameField = false; @@ -327,28 +325,6 @@ StatusWith<BSONObj> validateIndexSpec( hasIndexNameField = true; } else if (IndexDescriptor::kNamespaceFieldName == indexSpecElemFieldName) { - if (indexSpecElem.type() != BSONType::String) { - return {ErrorCodes::TypeMismatch, - str::stream() - << "The field '" << IndexDescriptor::kNamespaceFieldName - << "' must be a string, but got " << typeName(indexSpecElem.type())}; - } - - StringData ns = indexSpecElem.valueStringData(); - if (ns.empty()) { - return {ErrorCodes::BadValue, - str::stream() << "The field '" << IndexDescriptor::kNamespaceFieldName - << "' cannot be an empty string"}; - } - - if (ns != expectedNamespace.ns()) { - return {ErrorCodes::BadValue, - str::stream() - << "The value of the field '" << IndexDescriptor::kNamespaceFieldName - << "' (" << ns << ") doesn't match the namespace '" << expectedNamespace - << "'"}; - } - hasNamespaceField = true; } else if (IndexDescriptor::kIndexVersionFieldName == indexSpecElemFieldName) { if (!indexSpecElem.isNumber()) { @@ -485,29 +461,24 @@ StatusWith<BSONObj> validateIndexSpec( << static_cast<int>(*resolvedIndexVersion)}; } - if (!hasNamespaceField || !hasVersionField) { - BSONObjBuilder bob; + BSONObj modifiedSpec = indexSpec; - // Only generate the 'ns' field for the index spec if it's missing it and if the server test - // parameter to disable the generation isn't enabled. - if (!hasNamespaceField && !disableIndexSpecNamespaceGeneration.load()) { - // We create a new index specification with the 'ns' field set as 'expectedNamespace' if - // the field was omitted. - bob.append(IndexDescriptor::kNamespaceFieldName, expectedNamespace.ns()); - } - - if (!hasVersionField) { - // We create a new index specification with the 'v' field set as 'defaultIndexVersion' - // if the field was omitted. - bob.append(IndexDescriptor::kIndexVersionFieldName, - static_cast<int>(*resolvedIndexVersion)); - } + // Ignore any 'ns' field in the index spec because this field is dropped post-4.0. Don't remove + // the field during repair, as repair may run on old data files (version 3.6 and 4.0) that + // require the field to be present. + if (hasNamespaceField && !storageGlobalParams.repair) { + modifiedSpec = modifiedSpec.removeField(IndexDescriptor::kNamespaceFieldName); + } - bob.appendElements(indexSpec); - return bob.obj(); + if (!hasVersionField) { + // We create a new index specification with the 'v' field set as 'defaultIndexVersion' if + // the field was omitted. + BSONObj versionObj = BSON(IndexDescriptor::kIndexVersionFieldName + << static_cast<int>(*resolvedIndexVersion)); + modifiedSpec = modifiedSpec.addField(versionObj.firstElement()); } - return indexSpec; + return modifiedSpec; } Status validateIdIndexSpec(const BSONObj& indexSpec) { diff --git a/src/mongo/db/catalog/index_key_validate.h b/src/mongo/db/catalog/index_key_validate.h index 52ba7fd3ed2..7c177c50355 100644 --- a/src/mongo/db/catalog/index_key_validate.h +++ b/src/mongo/db/catalog/index_key_validate.h @@ -58,7 +58,6 @@ Status validateKeyPattern(const BSONObj& key, IndexDescriptor::IndexVersion inde StatusWith<BSONObj> validateIndexSpec( OperationContext* opCtx, const BSONObj& indexSpec, - const NamespaceString& expectedNamespace, const ServerGlobalParams::FeatureCompatibility& featureCompatibility); /** diff --git a/src/mongo/db/catalog/index_spec_validate_test.cpp b/src/mongo/db/catalog/index_spec_validate_test.cpp index 6b472d09073..cb2d66df78f 100644 --- a/src/mongo/db/catalog/index_spec_validate_test.cpp +++ b/src/mongo/db/catalog/index_spec_validate_test.cpp @@ -55,7 +55,6 @@ using index_key_validate::validateIndexSpec; using index_key_validate::validateIndexSpecCollation; using unittest::EnsureFCV; -const NamespaceString kTestNamespace("test", "index_spec_validate"); constexpr OperationContext* kDefaultOpCtx = nullptr; /** @@ -75,7 +74,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfKeyPatternIsNotAnObject) { validateIndexSpec(kDefaultOpCtx, BSON("key" << 1 << "name" << "indexName"), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::TypeMismatch, validateIndexSpec(kDefaultOpCtx, @@ -83,13 +81,11 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfKeyPatternIsNotAnObject) { << "not an object" << "name" << "indexName"), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::TypeMismatch, validateIndexSpec(kDefaultOpCtx, BSON("key" << BSONArray() << "name" << "indexName"), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -98,7 +94,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfFieldRepeatedInKeyPattern) { validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1 << "field" << 1) << "name" << "indexName"), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::BadValue, validateIndexSpec(kDefaultOpCtx, @@ -106,7 +101,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfFieldRepeatedInKeyPattern) { << "2dsphere") << "name" << "indexName"), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -115,7 +109,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfKeyPatternIsNotPresent) { validateIndexSpec(kDefaultOpCtx, BSON("name" << "indexName"), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -123,7 +116,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfNameIsNotAString) { ASSERT_EQ(ErrorCodes::TypeMismatch, validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -131,93 +123,20 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfNameIsNotPresent) { ASSERT_EQ(ErrorCodes::FailedToParse, validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1)), - kTestNamespace, serverGlobalParams.featureCompatibility)); } -TEST(IndexSpecValidateTest, ReturnsAnErrorIfNamespaceIsNotAString) { - ASSERT_EQ(ErrorCodes::TypeMismatch, - validateIndexSpec(kDefaultOpCtx, - BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" << 1), - kTestNamespace, - serverGlobalParams.featureCompatibility)); - ASSERT_EQ(ErrorCodes::TypeMismatch, - validateIndexSpec(kDefaultOpCtx, - BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" << BSONObj()), - kTestNamespace, - serverGlobalParams.featureCompatibility)); -} - -TEST(IndexSpecValidateTest, ReturnsAnErrorIfNamespaceIsEmptyString) { - ASSERT_EQ(ErrorCodes::BadValue, - validateIndexSpec(kDefaultOpCtx, - BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" - << ""), - NamespaceString(), - serverGlobalParams.featureCompatibility)); -} - -TEST(IndexSpecValidateTest, ReturnsAnErrorIfNamespaceDoesNotMatch) { - ASSERT_EQ(ErrorCodes::BadValue, - validateIndexSpec(kDefaultOpCtx, - BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" - << "some string"), - kTestNamespace, - serverGlobalParams.featureCompatibility)); - - // Verify that we reject the index specification when the "ns" field only contains the - // collection name. - ASSERT_EQ(ErrorCodes::BadValue, - validateIndexSpec(kDefaultOpCtx, - BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" << kTestNamespace.coll()), - kTestNamespace, - serverGlobalParams.featureCompatibility)); -} - -TEST(IndexSpecValidateTest, ReturnsIndexSpecWithNamespaceFilledInIfItIsNotPresent) { +TEST(IndexSpecValidateTest, ReturnsIndexSpecUnchangedIfVersionIsPresent) { auto result = validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << 1), - kTestNamespace, - serverGlobalParams.featureCompatibility); - ASSERT_OK(result.getStatus()); - - // We don't care about the order of the fields in the resulting index specification. - ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 1)), - sorted(result.getValue())); - - // Verify that the index specification we returned is still considered valid. - ASSERT_OK(validateIndexSpec( - kDefaultOpCtx, result.getValue(), kTestNamespace, serverGlobalParams.featureCompatibility)); -} - -TEST(IndexSpecValidateTest, ReturnsIndexSpecUnchangedIfNamespaceAndVersionArePresent) { - auto result = validateIndexSpec(kDefaultOpCtx, - BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); // We don't care about the order of the fields in the resulting index specification. ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" - << "test.index_spec_validate" << "v" << 1)), sorted(result.getValue())); } @@ -229,14 +148,12 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfVersionIsNotANumber) { << "indexName" << "v" << "not a number"), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::TypeMismatch, validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << BSONObj()), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -246,28 +163,24 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfVersionIsNotRepresentableAsInt) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << 2.2), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::BadValue, validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << std::nan("1")), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::BadValue, validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << std::numeric_limits<double>::infinity()), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::BadValue, validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << std::numeric_limits<long long>::max()), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -277,7 +190,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfVersionIsV0) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << 0), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -289,7 +201,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfVersionIsUnsupported) { << "v" << 3 << "collation" << BSON("locale" << "en")), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::CannotCreateIndex, @@ -297,7 +208,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfVersionIsUnsupported) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << -3LL), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -306,49 +216,45 @@ TEST(IndexSpecValidateTest, AcceptsIndexVersionsThatAreAllowedForCreation) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); // We don't care about the order of the fields in the resulting index specification. ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 1)), + << "v" << 1)), sorted(result.getValue())); result = validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << 2LL), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); // We don't care about the order of the fields in the resulting index specification. ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2LL)), + << "v" << 2LL)), sorted(result.getValue())); } TEST(IndexSpecValidateTest, DefaultIndexVersionIsV2) { auto result = validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" << kTestNamespace.ns()), - kTestNamespace, + << "indexName"), serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); // We don't care about the order of the fields in the resulting index specification. ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2)), + << "v" << 2)), sorted(result.getValue())); // Verify that the index specification we returned is still considered valid. ASSERT_OK(validateIndexSpec( - kDefaultOpCtx, result.getValue(), kTestNamespace, serverGlobalParams.featureCompatibility)); + kDefaultOpCtx, result.getValue(), serverGlobalParams.featureCompatibility)); } TEST(IndexSpecValidateTest, AcceptsIndexVersionV1) { @@ -356,14 +262,13 @@ TEST(IndexSpecValidateTest, AcceptsIndexVersionV1) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); // We don't care about the order of the fields in the resulting index specification. ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 1)), + << "v" << 1)), sorted(result.getValue())); } @@ -373,7 +278,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfCollationIsNotAnObject) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "collation" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::TypeMismatch, validateIndexSpec(kDefaultOpCtx, @@ -381,14 +285,12 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfCollationIsNotAnObject) { << "indexName" << "collation" << "not an object"), - kTestNamespace, serverGlobalParams.featureCompatibility)); ASSERT_EQ(ErrorCodes::TypeMismatch, validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("field" << 1) << "name" << "indexName" << "collation" << BSONArray()), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -398,7 +300,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfCollationIsEmpty) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "collation" << BSONObj()), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -411,7 +312,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfCollationIsPresentAndVersionIsLessTh << BSON("locale" << "simple") << "v" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility)); } @@ -422,14 +322,13 @@ TEST(IndexSpecValidateTest, AcceptsAnyNonEmptyObjectValueForCollation) { << "v" << 2 << "collation" << BSON("locale" << "simple")), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); // We don't care about the order of the fields in the resulting index specification. ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2 << "collation" + << "v" << 2 << "collation" << BSON("locale" << "simple"))), sorted(result.getValue())); @@ -439,16 +338,15 @@ TEST(IndexSpecValidateTest, AcceptsAnyNonEmptyObjectValueForCollation) { << "indexName" << "v" << 2 << "collation" << BSON("unknownCollationOption" << true)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); // We don't care about the order of the fields in the resulting index specification. - ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" - << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2 << "collation" - << BSON("unknownCollationOption" << true))), - sorted(result.getValue())); + ASSERT_BSONOBJ_EQ( + sorted(BSON("key" << BSON("field" << 1) << "name" + << "indexName" + << "v" << 2 << "collation" << BSON("unknownCollationOption" << true))), + sorted(result.getValue())); } TEST(IndexSpecValidateTest, AcceptsIndexSpecIfCollationIsPresentAndVersionIsEqualToV2) { @@ -458,14 +356,13 @@ TEST(IndexSpecValidateTest, AcceptsIndexSpecIfCollationIsPresentAndVersionIsEqua << "v" << 2 << "collation" << BSON("locale" << "en")), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); // We don't care about the order of the fields in the resulting index specification. ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2 << "collation" + << "v" << 2 << "collation" << BSON("locale" << "en"))), sorted(result.getValue())); @@ -476,7 +373,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfUnknownFieldIsPresentInSpecV2) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << 2 << "unknownField" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(ErrorCodes::InvalidIndexSpecificationOption, result); } @@ -486,7 +382,6 @@ TEST(IndexSpecValidateTest, ReturnsAnErrorIfUnknownFieldIsPresentInSpecV1) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "v" << 1 << "unknownField" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(ErrorCodes::InvalidIndexSpecificationOption, result); } @@ -495,59 +390,53 @@ TEST(IdIndexSpecValidateTest, ReturnsAnErrorIfKeyPatternIsIncorrectForIdIndex) { ASSERT_EQ(ErrorCodes::BadValue, validateIdIndexSpec(BSON("key" << BSON("_id" << -1) << "name" << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2))); + << "v" << 2))); ASSERT_EQ(ErrorCodes::BadValue, validateIdIndexSpec(BSON("key" << BSON("a" << 1) << "name" << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2))); + << "v" << 2))); } TEST(IdIndexSpecValidateTest, ReturnsOKStatusIfKeyPatternCorrectForIdIndex) { ASSERT_OK(validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" << "anyname" - << "ns" << kTestNamespace.ns() << "v" << 2))); + << "v" << 2))); } TEST(IdIndexSpecValidateTest, ReturnsAnErrorIfFieldNotAllowedForIdIndex) { ASSERT_EQ(ErrorCodes::InvalidIndexSpecificationOption, validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2 - << "background" << false))); + << "v" << 2 << "background" << false))); ASSERT_EQ(ErrorCodes::InvalidIndexSpecificationOption, validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2 << "unique" - << true))); + << "v" << 2 << "unique" << true))); ASSERT_EQ(ErrorCodes::InvalidIndexSpecificationOption, validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2 - << "partialFilterExpression" << BSON("a" << 5)))); + << "v" << 2 << "partialFilterExpression" + << BSON("a" << 5)))); ASSERT_EQ(ErrorCodes::InvalidIndexSpecificationOption, validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2 << "sparse" - << false))); + << "v" << 2 << "sparse" << false))); ASSERT_EQ(ErrorCodes::InvalidIndexSpecificationOption, validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2 - << "expireAfterSeconds" << 3600))); + << "v" << 2 << "expireAfterSeconds" << 3600))); ASSERT_EQ(ErrorCodes::InvalidIndexSpecificationOption, validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2 - << "storageEngine" << BSONObj()))); + << "v" << 2 << "storageEngine" << BSONObj()))); } TEST(IdIndexSpecValidateTest, ReturnsOKStatusIfAllFieldsAllowedForIdIndex) { - ASSERT_OK( - validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" - << "_id_" - << "ns" << kTestNamespace.ns() << "v" << 2 << "collation" - << BSON("locale" - << "simple")))); + ASSERT_OK(validateIdIndexSpec(BSON("key" << BSON("_id" << 1) << "name" + << "_id_" + << "v" << 2 << "collation" + << BSON("locale" + << "simple")))); } TEST(IndexSpecCollationValidateTest, FillsInFullCollationSpec) { @@ -559,8 +448,7 @@ TEST(IndexSpecCollationValidateTest, FillsInFullCollationSpec) { auto result = validateIndexSpecCollation(opCtx.get(), BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2 - << "collation" + << "v" << 2 << "collation" << BSON("locale" << "mock_reverse_string")), defaultCollator); @@ -570,7 +458,7 @@ TEST(IndexSpecCollationValidateTest, FillsInFullCollationSpec) { ASSERT_BSONOBJ_EQ( sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2 << "collation" + << "v" << 2 << "collation" << BSON("locale" << "mock_reverse_string" << "caseLevel" << false << "caseFirst" @@ -593,8 +481,7 @@ TEST(IndexSpecCollationValidateTest, RemovesCollationFieldIfSimple) { auto result = validateIndexSpecCollation(opCtx.get(), BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2 - << "collation" + << "v" << 2 << "collation" << BSON("locale" << "simple")), defaultCollator); @@ -603,7 +490,7 @@ TEST(IndexSpecCollationValidateTest, RemovesCollationFieldIfSimple) { // We don't care about the order of the fields in the resulting index specification. ASSERT_BSONOBJ_EQ(sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2)), + << "v" << 2)), sorted(result.getValue())); } @@ -616,7 +503,7 @@ TEST(IndexSpecCollationValidateTest, FillsInCollationFieldWithCollectionDefaultI auto result = validateIndexSpecCollation(opCtx.get(), BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2), + << "v" << 2), &defaultCollator); ASSERT_OK(result.getStatus()); @@ -624,7 +511,7 @@ TEST(IndexSpecCollationValidateTest, FillsInCollationFieldWithCollectionDefaultI ASSERT_BSONOBJ_EQ( sorted(BSON("key" << BSON("field" << 1) << "name" << "indexName" - << "ns" << kTestNamespace.ns() << "v" << 2 << "collation" + << "v" << 2 << "collation" << BSON("locale" << "mock_reverse_string" << "caseLevel" << false << "caseFirst" @@ -643,7 +530,6 @@ TEST(IndexSpecPartialFilterTest, FailsIfPartialFilterIsNotAnObject) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "partialFilterExpression" << 1), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus(), ErrorCodes::TypeMismatch); } @@ -654,7 +540,6 @@ TEST(IndexSpecPartialFilterTest, FailsIfPartialFilterContainsBannedFeature) { << "indexName" << "partialFilterExpression" << BSON("$jsonSchema" << BSONObj())), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus(), ErrorCodes::QueryFeatureNotAllowed); } @@ -664,7 +549,6 @@ TEST(IndexSpecPartialFilterTest, AcceptsValidPartialFilterExpression) { BSON("key" << BSON("field" << 1) << "name" << "indexName" << "partialFilterExpression" << BSON("a" << 1)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); } @@ -676,7 +560,6 @@ TEST(IndexSpecWildcard, SucceedsWithInclusion) { BSON("key" << BSON("$**" << 1) << "name" << "indexName" << "wildcardProjection" << BSON("a" << 1 << "b" << 1)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); } @@ -688,7 +571,6 @@ TEST(IndexSpecWildcard, SucceedsWithExclusion) { BSON("key" << BSON("$**" << 1) << "name" << "indexName" << "wildcardProjection" << BSON("a" << 0 << "b" << 0)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); } @@ -700,7 +582,6 @@ TEST(IndexSpecWildcard, SucceedsWithExclusionIncludingId) { << "indexName" << "wildcardProjection" << BSON("_id" << 1 << "a" << 0 << "b" << 0)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); } @@ -712,7 +593,6 @@ TEST(IndexSpecWildcard, SucceedsWithInclusionExcludingId) { << "indexName" << "wildcardProjection" << BSON("_id" << 0 << "a" << 1 << "b" << 1)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_OK(result.getStatus()); } @@ -724,7 +604,6 @@ TEST(IndexSpecWildcard, FailsWithInclusionExcludingIdSubfield) { << "indexName" << "wildcardProjection" << BSON("_id.field" << 0 << "a" << 1 << "b" << 1)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), 40179); } @@ -736,7 +615,6 @@ TEST(IndexSpecWildcard, FailsWithExclusionIncludingIdSubfield) { << "indexName" << "wildcardProjection" << BSON("_id.field" << 1 << "a" << 0 << "b" << 0)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), 40178); } @@ -748,7 +626,6 @@ TEST(IndexSpecWildcard, FailsWithImproperFeatureCompatabilityVersion) { auto result = validateIndexSpec(kDefaultOpCtx, BSON("key" << BSON("$**" << 1) << "name" << "indexName"), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), ErrorCodes::CannotCreateIndex); } @@ -760,7 +637,6 @@ TEST(IndexSpecWildcard, FailsWithMixedProjection) { BSON("key" << BSON("$**" << 1) << "name" << "indexName" << "wildcardProjection" << BSON("a" << 1 << "b" << 0)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), 40178); } @@ -773,7 +649,6 @@ TEST(IndexSpecWildcard, FailsWithComputedFieldsInProjection) { << "wildcardProjection" << BSON("a" << 1 << "b" << "string")), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), ErrorCodes::FailedToParse); } @@ -784,7 +659,6 @@ TEST(IndexSpecWildcard, FailsWhenProjectionPluginNotWildcard) { BSON("key" << BSON("a" << 1) << "name" << "indexName" << "wildcardProjection" << BSON("a" << 1)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue); } @@ -795,7 +669,6 @@ TEST(IndexSpecWildcard, FailsWhenProjectionIsNotAnObject) { BSON("key" << BSON("$**" << 1) << "name" << "indexName" << "wildcardProjection" << 4), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), ErrorCodes::TypeMismatch); } @@ -806,7 +679,6 @@ TEST(IndexSpecWildcard, FailsWithEmptyProjection) { BSON("key" << BSON("$**" << 1) << "name" << "indexName" << "wildcardProjection" << BSONObj()), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), ErrorCodes::FailedToParse); } @@ -817,7 +689,6 @@ TEST(IndexSpecWildcard, FailsWhenInclusionWithSubpath) { BSON("key" << BSON("a.$**" << 1) << "name" << "indexName" << "wildcardProjection" << BSON("a" << 1)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), ErrorCodes::FailedToParse); } @@ -828,7 +699,6 @@ TEST(IndexSpecWildcard, FailsWhenExclusionWithSubpath) { BSON("key" << BSON("a.$**" << 1) << "name" << "indexName" << "wildcardProjection" << BSON("b" << 0)), - kTestNamespace, serverGlobalParams.featureCompatibility); ASSERT_EQ(result.getStatus().code(), ErrorCodes::FailedToParse); } diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp index 8506619312b..d1df31a6dba 100644 --- a/src/mongo/db/catalog/rename_collection.cpp +++ b/src/mongo/db/catalog/rename_collection.cpp @@ -536,34 +536,21 @@ Status renameBetweenDBs(OperationContext* opCtx, } }); - // Copy the index descriptions from the source collection, adjusting the ns field. + // Copy the index descriptions from the source collection. { std::vector<BSONObj> indexesToCopy; std::unique_ptr<IndexCatalog::IndexIterator> sourceIndIt = sourceColl->getIndexCatalog()->getIndexIterator(opCtx, true); while (sourceIndIt->more()) { auto descriptor = sourceIndIt->next()->descriptor(); - if (descriptor->isIdIndex()) { - continue; + if (!descriptor->isIdIndex()) { + indexesToCopy.push_back(descriptor->infoObj()); } - - const BSONObj currIndex = descriptor->infoObj(); - - // Process the source index, adding fields in the same order as they were originally. - BSONObjBuilder newIndex; - for (auto&& elem : currIndex) { - if (elem.fieldNameStringData() == "ns") { - newIndex.append("ns", tmpName.ns()); - } else { - newIndex.append(elem); - } - } - indexesToCopy.push_back(newIndex.obj()); } - // Create indexes using the namespace-adjusted index specs on the empty temporary collection - // that was just created. Since each index build is possibly replicated to downstream nodes, - // each createIndex oplog entry must have a distinct timestamp to support correct rollback + // Create indexes using the index specs on the empty temporary collection that was just + // created. Since each index build is possibly replicated to downstream nodes, each + // createIndex oplog entry must have a distinct timestamp to support correct rollback // operation. This is achieved by writing the createIndexes oplog entry *before* creating // the index. Using IndexCatalog::createIndexOnEmptyCollection() for the index creation // allows us to add and commit the index within a single WriteUnitOfWork and avoids the diff --git a/src/mongo/db/catalog/rename_collection_test.cpp b/src/mongo/db/catalog/rename_collection_test.cpp index 4c7e994f061..a27769d799b 100644 --- a/src/mongo/db/catalog/rename_collection_test.cpp +++ b/src/mongo/db/catalog/rename_collection_test.cpp @@ -415,7 +415,7 @@ void _createIndexOnEmptyCollection(OperationContext* opCtx, << " because collection " << nss << " does not exist."; auto indexInfoObj = BSON("v" << int(IndexDescriptor::kLatestIndexVersion) << "key" - << BSON("a" << 1) << "name" << indexName << "ns" << nss.ns()); + << BSON("a" << 1) << "name" << indexName); auto indexCatalog = collection->getIndexCatalog(); WriteUnitOfWork wuow(opCtx); |