summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands/create_indexes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/commands/create_indexes.cpp')
-rw-r--r--src/mongo/db/commands/create_indexes.cpp73
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
+}