summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/coll_mod.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/catalog/coll_mod.cpp')
-rw-r--r--src/mongo/db/catalog/coll_mod.cpp27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/mongo/db/catalog/coll_mod.cpp b/src/mongo/db/catalog/coll_mod.cpp
index 3e24be31e7e..4c8bbdbf40c 100644
--- a/src/mongo/db/catalog/coll_mod.cpp
+++ b/src/mongo/db/catalog/coll_mod.cpp
@@ -52,8 +52,10 @@
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/s/collection_sharding_state.h"
#include "mongo/db/s/database_sharding_state.h"
+#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
#include "mongo/db/storage/recovery_unit.h"
+#include "mongo/db/storage/storage_parameters_gen.h"
#include "mongo/db/timeseries/timeseries_options.h"
#include "mongo/db/ttl_collection_cache.h"
#include "mongo/db/views/view_catalog.h"
@@ -136,7 +138,7 @@ StatusWith<CollModRequest> parseCollModRequest(OperationContext* opCtx,
for (auto&& elem : indexObj) {
const auto field = elem.fieldNameStringData();
if (field != "name" && field != "keyPattern" && field != "expireAfterSeconds" &&
- field != "hidden") {
+ field != "hidden" && field != "unique") {
return {ErrorCodes::InvalidOptions,
str::stream()
<< "Unrecognized field '" << field << "' in 'index' option"};
@@ -172,9 +174,19 @@ StatusWith<CollModRequest> parseCollModRequest(OperationContext* opCtx,
auto cmrIndex = &cmr.indexRequest;
cmrIndex->indexExpireAfterSeconds = indexObj["expireAfterSeconds"];
cmrIndex->indexHidden = indexObj["hidden"];
+ cmrIndex->indexUnique = indexObj["unique"];
- if (cmrIndex->indexExpireAfterSeconds.eoo() && cmrIndex->indexHidden.eoo()) {
- return Status(ErrorCodes::InvalidOptions, "no expireAfterSeconds or hidden field");
+ if (cmrIndex->indexUnique) {
+ uassert(ErrorCodes::InvalidOptions,
+ "collMod does not support converting an index to unique",
+ feature_flags::gCollModIndexUnique.isEnabled(
+ serverGlobalParams.featureCompatibility));
+ }
+
+ if (cmrIndex->indexExpireAfterSeconds.eoo() && cmrIndex->indexHidden.eoo() &&
+ cmrIndex->indexUnique.eoo()) {
+ return Status(ErrorCodes::InvalidOptions,
+ "no expireAfterSeconds, hidden, or unique field");
}
if (!cmrIndex->indexExpireAfterSeconds.eoo()) {
if (isTimeseries) {
@@ -192,6 +204,9 @@ StatusWith<CollModRequest> parseCollModRequest(OperationContext* opCtx,
if (!cmrIndex->indexHidden.eoo() && !cmrIndex->indexHidden.isBoolean()) {
return Status(ErrorCodes::InvalidOptions, "hidden field must be a boolean");
}
+ if (!cmrIndex->indexUnique.eoo() && !cmrIndex->indexUnique.isBoolean()) {
+ return Status(ErrorCodes::InvalidOptions, "unique field must be a boolean");
+ }
if (!cmrIndex->indexHidden.eoo() && coll->isClustered() &&
!nss.isTimeseriesBucketsCollection()) {
auto clusteredInfo = coll->getClusteredInfo();
@@ -286,6 +301,12 @@ StatusWith<CollModRequest> parseCollModRequest(OperationContext* opCtx,
return Status(ErrorCodes::BadValue, "can't hide _id index");
}
}
+
+ if (cmrIndex->indexUnique) {
+ if (!cmrIndex->indexUnique.trueValue()) {
+ return Status(ErrorCodes::BadValue, "Cannot make index non-unique");
+ }
+ }
} else if (fieldName == "validator" && !isView && !isTimeseries) {
// If the feature compatibility version is not kLatest, and we are validating features
// as primary, ban the use of new agg features introduced in kLatest to prevent them