diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2016-10-24 18:09:28 -0400 |
---|---|---|
committer | Tess Avitabile <tess.avitabile@mongodb.com> | 2016-10-27 10:11:02 -0400 |
commit | 79c2bc2f73138a1859c5d8ea91dc6f60e67ae8b8 (patch) | |
tree | 9fc6537d0b7c52f4b6bb346fa241479399774c3d /src/mongo/db/commands | |
parent | cc75cf210c63a0c96c74e01f3919938ea64a0317 (diff) | |
download | mongo-79c2bc2f73138a1859c5d8ea91dc6f60e67ae8b8.tar.gz |
SERVER-26724 createIndexes command should reject invalid options for _id index
Diffstat (limited to 'src/mongo/db/commands')
-rw-r--r-- | src/mongo/db/commands/create_indexes.cpp | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index fbd131211b4..116a6248cc9 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -45,6 +45,7 @@ #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_global.h" #include "mongo/db/s/collection_metadata.h" @@ -97,12 +98,27 @@ StatusWith<std::vector<BSONObj>> parseAndValidateIndexSpecs( << typeName(indexesElem.type())}; } - auto indexSpec = index_key_validate::validateIndexSpec( + auto indexSpecStatus = index_key_validate::validateIndexSpec( indexesElem.Obj(), ns, featureCompatibility); - if (!indexSpec.isOK()) { - return indexSpec.getStatus(); + if (!indexSpecStatus.isOK()) { + return indexSpecStatus.getStatus(); } - indexSpecs.push_back(std::move(indexSpec.getValue())); + auto indexSpec = indexSpecStatus.getValue(); + + if (IndexDescriptor::isIdIndexPattern( + indexSpec[IndexDescriptor::kKeyPatternFieldName].Obj())) { + auto status = index_key_validate::validateIdIndexSpec(indexSpec); + if (!status.isOK()) { + return status; + } + } else if (indexSpec[IndexDescriptor::kIndexNameFieldName].String() == "_id_"_sd) { + return {ErrorCodes::BadValue, + str::stream() << "The index name '_id_' is reserved for the _id index, " + "which must have key pattern {_id: 1}, found " + << indexSpec[IndexDescriptor::kKeyPatternFieldName]}; + } + + indexSpecs.push_back(std::move(indexSpec)); } hasIndexesField = true; @@ -144,12 +160,39 @@ StatusWith<std::vector<BSONObj>> resolveCollectionDefaultProperties( std::vector<BSONObj> indexSpecsWithDefaults = std::move(indexSpecs); for (size_t i = 0, numIndexSpecs = indexSpecsWithDefaults.size(); i < numIndexSpecs; ++i) { - auto validatedSpec = index_key_validate::validateIndexSpecCollation( + auto indexSpecStatus = index_key_validate::validateIndexSpecCollation( txn, indexSpecsWithDefaults[i], collection->getDefaultCollator()); - if (!validatedSpec.isOK()) { - return validatedSpec.getStatus(); + if (!indexSpecStatus.isOK()) { + return indexSpecStatus.getStatus(); } - indexSpecsWithDefaults[i] = validatedSpec.getValue(); + 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(txn->getServiceContext()) + ->makeFromBSON(collationElem.Obj()); + // validateIndexSpecCollation() should have checked that the index collation spec is + // valid. + invariantOK(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; |