diff options
author | Benety Goh <benety@mongodb.com> | 2019-01-13 12:32:18 -0500 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2019-01-13 12:32:18 -0500 |
commit | 1e699ce684d988008ec944f8c82d301f9a5cac2b (patch) | |
tree | e3e4b840108ef1435a90aed95d8c8046fa70a325 | |
parent | 299bf76a07f7b0af9585ae22b9ae3cf2b340debe (diff) | |
download | mongo-1e699ce684d988008ec944f8c82d301f9a5cac2b.tar.gz |
SERVER-37643 add Collection::addCollationDefaultsToIndexSpecsForCreate()
-rw-r--r-- | src/mongo/db/catalog/collection.h | 14 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.cpp | 51 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.h | 4 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_mock.h | 6 | ||||
-rw-r--r-- | src/mongo/db/commands/create_indexes.cpp | 55 |
5 files changed, 72 insertions, 58 deletions
diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h index 29c23c55c41..41ce7a9fc74 100644 --- a/src/mongo/db/catalog/collection.h +++ b/src/mongo/db/catalog/collection.h @@ -1,4 +1,3 @@ - /** * Copyright (C) 2018-present MongoDB, Inc. * @@ -33,6 +32,7 @@ #include <cstdint> #include <memory> #include <string> +#include <vector> #include "mongo/base/status.h" #include "mongo/base/status_with.h" @@ -431,6 +431,18 @@ public: virtual const CollatorInterface* getDefaultCollator() const = 0; /** + * Fills in each index specification with collation information from this collection and returns + * the new index specifications. + * + * The returned index specifications will not be equivalent to the ones specified in + * 'indexSpecs' if any missing collation information were filled in; however, the returned index + * specifications will match the form stored in the IndexCatalog should any of these indexes + * already exist. + */ + virtual StatusWith<std::vector<BSONObj>> addCollationDefaultsToIndexSpecsForCreate( + OperationContext* opCtx, const std::vector<BSONObj>& indexSpecs) const = 0; + + /** * Returns a plan executor for a collection scan over this collection. */ virtual std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> makePlanExecutor( diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp index 79503488959..a1e0153720e 100644 --- a/src/mongo/db/catalog/collection_impl.cpp +++ b/src/mongo/db/catalog/collection_impl.cpp @@ -1,4 +1,3 @@ - /** * Copyright (C) 2018-present MongoDB, Inc. * @@ -50,6 +49,7 @@ #include "mongo/db/catalog/document_validation.h" #include "mongo/db/catalog/index_catalog_impl.h" #include "mongo/db/catalog/index_consistency.h" +#include "mongo/db/catalog/index_key_validate.h" #include "mongo/db/catalog/namespace_uuid_cache.h" #include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/clientcursor.h" @@ -57,12 +57,14 @@ #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/curop.h" #include "mongo/db/index/index_access_method.h" +#include "mongo/db/index/index_descriptor.h" #include "mongo/db/keypattern.h" #include "mongo/db/matcher/expression_parser.h" #include "mongo/db/op_observer.h" #include "mongo/db/operation_context.h" #include "mongo/db/ops/update_request.h" #include "mongo/db/query/collation/collator_factory_interface.h" +#include "mongo/db/query/collation/collator_interface.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/repl/oplog.h" #include "mongo/db/repl/replication_coordinator.h" @@ -959,6 +961,53 @@ const CollatorInterface* CollectionImpl::getDefaultCollator() const { return _collator.get(); } +StatusWith<std::vector<BSONObj>> CollectionImpl::addCollationDefaultsToIndexSpecsForCreate( + OperationContext* opCtx, const std::vector<BSONObj>& originalIndexSpecs) const { + std::vector<BSONObj> newIndexSpecs; + + auto collator = getDefaultCollator(); // could be null. + auto collatorFactory = CollatorFactoryInterface::get(opCtx->getServiceContext()); + + for (const auto& originalIndexSpec : originalIndexSpecs) { + auto validateResult = + index_key_validate::validateIndexSpecCollation(opCtx, originalIndexSpec, collator); + if (!validateResult.isOK()) { + return validateResult.getStatus().withContext( + str::stream() + << "failed to add collation information to index spec for index creation: " + << originalIndexSpec); + } + const auto& newIndexSpec = validateResult.getValue(); + + auto keyPattern = newIndexSpec[IndexDescriptor::kKeyPatternFieldName].Obj(); + if (IndexDescriptor::isIdIndexPattern(keyPattern)) { + std::unique_ptr<CollatorInterface> indexCollator; + if (auto collationElem = newIndexSpec[IndexDescriptor::kCollationFieldName]) { + auto indexCollatorResult = collatorFactory->makeFromBSON(collationElem.Obj()); + // validateIndexSpecCollation() should have checked that the index collation spec is + // valid. + invariant(indexCollatorResult.getStatus(), + str::stream() << "invalid collation in index spec: " << newIndexSpec); + indexCollator = std::move(indexCollatorResult.getValue()); + } + if (!CollatorInterface::collatorsMatch(collator, indexCollator.get())) { + return {ErrorCodes::BadValue, + str::stream() << "The _id index must have the same collation as the " + "collection. Index collation: " + << (indexCollator.get() ? indexCollator->getSpec().toBSON() + : CollationSpec::kSimpleSpec) + << ", collection collation: " + << (collator ? collator->getSpec().toBSON() + : CollationSpec::kSimpleSpec)}; + } + } + + newIndexSpecs.push_back(newIndexSpec); + } + + return newIndexSpecs; +} + namespace { using ValidateResultsMap = std::map<std::string, ValidateResults>; diff --git a/src/mongo/db/catalog/collection_impl.h b/src/mongo/db/catalog/collection_impl.h index 19ec048b572..149c77d75f6 100644 --- a/src/mongo/db/catalog/collection_impl.h +++ b/src/mongo/db/catalog/collection_impl.h @@ -1,4 +1,3 @@ - /** * Copyright (C) 2018-present MongoDB, Inc. * @@ -353,6 +352,9 @@ public: */ const CollatorInterface* getDefaultCollator() const final; + StatusWith<std::vector<BSONObj>> addCollationDefaultsToIndexSpecsForCreate( + OperationContext* opCtx, const std::vector<BSONObj>& indexSpecs) const final; + std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> makePlanExecutor( OperationContext* opCtx, PlanExecutor::YieldPolicy yieldPolicy, diff --git a/src/mongo/db/catalog/collection_mock.h b/src/mongo/db/catalog/collection_mock.h index 4b82f16f378..30e2ee1fee6 100644 --- a/src/mongo/db/catalog/collection_mock.h +++ b/src/mongo/db/catalog/collection_mock.h @@ -1,4 +1,3 @@ - /** * Copyright (C) 2018-present MongoDB, Inc. * @@ -267,6 +266,11 @@ public: std::abort(); } + StatusWith<std::vector<BSONObj>> addCollationDefaultsToIndexSpecsForCreate( + OperationContext* opCtx, const std::vector<BSONObj>& indexSpecs) const { + std::abort(); + } + std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> makePlanExecutor( OperationContext* opCtx, PlanExecutor::YieldPolicy yieldPolicy, diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index f613c0d6b1f..ae73af62bb7 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -52,7 +52,6 @@ #include "mongo/db/index/index_descriptor.h" #include "mongo/db/op_observer.h" #include "mongo/db/ops/insert.h" -#include "mongo/db/query/collation/collator_factory_interface.h" #include "mongo/db/repl/repl_client_info.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/s/collection_metadata.h" @@ -164,57 +163,6 @@ StatusWith<std::vector<BSONObj>> parseAndValidateIndexSpecs( } /** - * Returns index specifications with attributes (such as "collation") that are inherited from the - * collection filled in. - * - * The returned index specifications will not be equivalent to the ones specified as 'indexSpecs' if - * any missing attributes were filled in; however, the returned index specifications will match the - * form stored in the IndexCatalog should any of these indexes already exist. - */ -StatusWith<std::vector<BSONObj>> resolveCollectionDefaultProperties( - OperationContext* opCtx, const Collection* collection, std::vector<BSONObj> indexSpecs) { - std::vector<BSONObj> indexSpecsWithDefaults = std::move(indexSpecs); - - for (size_t i = 0, numIndexSpecs = indexSpecsWithDefaults.size(); i < numIndexSpecs; ++i) { - auto indexSpecStatus = index_key_validate::validateIndexSpecCollation( - opCtx, indexSpecsWithDefaults[i], collection->getDefaultCollator()); - if (!indexSpecStatus.isOK()) { - return indexSpecStatus.getStatus(); - } - auto indexSpec = indexSpecStatus.getValue(); - - if (IndexDescriptor::isIdIndexPattern( - indexSpec[IndexDescriptor::kKeyPatternFieldName].Obj())) { - std::unique_ptr<CollatorInterface> indexCollator; - if (auto collationElem = indexSpec[IndexDescriptor::kCollationFieldName]) { - auto collatorStatus = CollatorFactoryInterface::get(opCtx->getServiceContext()) - ->makeFromBSON(collationElem.Obj()); - // validateIndexSpecCollation() should have checked that the index collation spec is - // valid. - invariant(collatorStatus.getStatus()); - indexCollator = std::move(collatorStatus.getValue()); - } - if (!CollatorInterface::collatorsMatch(collection->getDefaultCollator(), - indexCollator.get())) { - return {ErrorCodes::BadValue, - str::stream() << "The _id index must have the same collation as the " - "collection. Index collation: " - << (indexCollator.get() ? indexCollator->getSpec().toBSON() - : CollationSpec::kSimpleSpec) - << ", collection collation: " - << (collection->getDefaultCollator() - ? collection->getDefaultCollator()->getSpec().toBSON() - : CollationSpec::kSimpleSpec)}; - } - } - - indexSpecsWithDefaults[i] = indexSpec; - } - - return indexSpecsWithDefaults; -} - -/** * Returns a vector of index specs with the filled in collection default options and removes any * indexes that already exist on the collection. If the returned vector is empty after returning, no * new indexes need to be built. Throws on error. @@ -222,8 +170,7 @@ StatusWith<std::vector<BSONObj>> resolveCollectionDefaultProperties( std::vector<BSONObj> resolveDefaultsAndRemoveExistingIndexes(OperationContext* opCtx, const Collection* collection, std::vector<BSONObj> validatedSpecs) { - auto swDefaults = - resolveCollectionDefaultProperties(opCtx, collection, std::move(validatedSpecs)); + auto swDefaults = collection->addCollationDefaultsToIndexSpecsForCreate(opCtx, validatedSpecs); uassertStatusOK(swDefaults.getStatus()); auto indexCatalog = collection->getIndexCatalog(); |