diff options
Diffstat (limited to 'src/mongo/db/commands/create_indexes.cpp')
| -rw-r--r-- | src/mongo/db/commands/create_indexes.cpp | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index fd71731c664..167d5f3161b 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -234,6 +234,8 @@ std::vector<BSONObj> resolveDefaultsAndRemoveExistingIndexes(OperationContext* o return specs; } +} // namespace + /** * { createIndexes : "bar", indexes : [ { ns : "test.bar", key : { x : 1 }, name: "x_1" } ] } */ @@ -241,17 +243,16 @@ class CmdCreateIndex : public ErrmsgCommandDeprecated { public: CmdCreateIndex() : ErrmsgCommandDeprecated(kCommandName) {} - bool supportsWriteConcern(const BSONObj& cmd) const override { + virtual bool supportsWriteConcern(const BSONObj& cmd) const override { return true; } - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { return AllowedOnSecondary::kNever; } - Status checkAuthForCommand(Client* client, - const std::string& dbname, - const BSONObj& cmdObj) const override { + virtual Status checkAuthForCommand(Client* client, + const std::string& dbname, + const BSONObj& cmdObj) const { ActionSet actions; actions.addAction(ActionType::createIndex); Privilege p(parseResourcePattern(dbname, cmdObj), actions); @@ -260,22 +261,26 @@ public: return Status(ErrorCodes::Unauthorized, "Unauthorized"); } - bool errmsgRun(OperationContext* opCtx, - const string& dbname, - const BSONObj& cmdObj, - string& errmsg, - BSONObjBuilder& result) override { + virtual bool errmsgRun(OperationContext* opCtx, + const string& dbname, + const BSONObj& cmdObj, + string& errmsg, + BSONObjBuilder& result) { const NamespaceString ns(CommandHelpers::parseNsCollectionRequired(dbname, cmdObj)); - uassertStatusOK(userAllowedWriteNS(ns)); - // Disallow users from creating new indexes on config.transactions since the sessions code - // was optimized to not update indexes + Status status = userAllowedWriteNS(ns); + uassertStatusOK(status); + + // Disallow users from creating new indexes on config.transactions since the sessions + // code was optimized to not update indexes. uassert(ErrorCodes::IllegalOperation, str::stream() << "not allowed to create index on " << ns.ns(), ns != NamespaceString::kSessionTransactionsTableNamespace); - auto specs = uassertStatusOK( - parseAndValidateIndexSpecs(opCtx, ns, cmdObj, serverGlobalParams.featureCompatibility)); + auto specsWithStatus = + parseAndValidateIndexSpecs(opCtx, ns, cmdObj, serverGlobalParams.featureCompatibility); + uassertStatusOK(specsWithStatus.getStatus()); + auto specs = std::move(specsWithStatus.getValue()); // Do not use AutoGetOrCreateDb because we may relock the database in mode X. Lock::DBLock dbLock(opCtx, ns.db(), MODE_IX); @@ -330,7 +335,8 @@ public: uasserted(ErrorCodes::CommandNotSupportedOnView, errmsg); } - uassertStatusOK(userAllowedCreateNS(ns.db(), ns.coll())); + status = userAllowedCreateNS(ns.db(), ns.coll()); + uassertStatusOK(status); writeConflictRetry(opCtx, kCommandName, ns.ns(), [&] { WriteUnitOfWork wunit(opCtx); @@ -362,7 +368,8 @@ public: for (size_t i = 0; i < specs.size(); i++) { const BSONObj& spec = specs[i]; if (spec["unique"].trueValue()) { - _checkUniqueIndexConstraints(opCtx, ns, spec["key"].Obj()); + status = checkUniqueIndexConstraints(opCtx, ns, spec["key"].Obj()); + uassertStatusOK(status); } } @@ -428,24 +435,24 @@ public: } private: - static void _checkUniqueIndexConstraints(OperationContext* opCtx, - const NamespaceString& nss, - const BSONObj& newIdxKey) { + static Status checkUniqueIndexConstraints(OperationContext* opCtx, + const NamespaceString& nss, + const BSONObj& newIdxKey) { invariant(opCtx->lockState()->isCollectionLockedForMode(nss.ns(), MODE_X)); - const auto metadata = CollectionShardingState::get(opCtx, nss)->getCurrentMetadata(); - if (!metadata->isSharded()) - return; + auto metadata = CollectionShardingState::get(opCtx, nss)->getMetadata(opCtx); + if (metadata->isSharded()) { + ShardKeyPattern shardKeyPattern(metadata->getKeyPattern()); + if (!shardKeyPattern.isUniqueIndexCompatible(newIdxKey)) { + return Status(ErrorCodes::CannotCreateIndex, + str::stream() << "cannot create unique index over " << newIdxKey + << " with shard key pattern " + << shardKeyPattern.toBSON()); + } + } + - const ShardKeyPattern shardKeyPattern(metadata->getKeyPattern()); - uassert(ErrorCodes::CannotCreateIndex, - str::stream() << "cannot create unique index over " << newIdxKey - << " with shard key pattern " - << shardKeyPattern.toBSON(), - shardKeyPattern.isUniqueIndexCompatible(newIdxKey)); + return Status::OK(); } - } cmdCreateIndex; - -} // namespace -} // namespace mongo +} |
