summaryrefslogtreecommitdiff
path: root/jstests/core
diff options
context:
space:
mode:
authorHaley Connelly <haley.connelly@mongodb.com>2021-12-14 16:55:57 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-12-14 17:53:31 +0000
commitaa3e4bb18dec429a7fdec60fa8a17e19045c398a (patch)
treeec117a87db78f0c8e6d0154973dc6e0df8eeee9d /jstests/core
parent1f87032345d910cba09516c09a340a08cb83cd3f (diff)
downloadmongo-aa3e4bb18dec429a7fdec60fa8a17e19045c398a.tar.gz
SERVER-61009 Make createIndex a no-op on a cluster key and allow 'clustered' on cluster key
Diffstat (limited to 'jstests/core')
-rw-r--r--jstests/core/clustered_collection_create_index_clustered.js36
-rw-r--r--jstests/core/clustered_collection_creation.js56
-rw-r--r--jstests/core/timeseries/timeseries_id_index.js13
3 files changed, 85 insertions, 20 deletions
diff --git a/jstests/core/clustered_collection_create_index_clustered.js b/jstests/core/clustered_collection_create_index_clustered.js
new file mode 100644
index 00000000000..3aefaa8821b
--- /dev/null
+++ b/jstests/core/clustered_collection_create_index_clustered.js
@@ -0,0 +1,36 @@
+/**
+ * Tests createIndexes with the 'clustered' option on a replicated collection. Note: there are
+ * different restrictions for non-replicated versus replicated clustered collections - eg replicated
+ * collections can only be created with cluster key _id whereas non-replicated collections can be
+ * created with arbitrary single field cluster keys.
+ *
+ * @tags: [
+ * requires_fcv_52,
+ * assumes_no_implicit_collection_creation_after_drop,
+ * # Does not support sharding
+ * assumes_against_mongod_not_mongos,
+ * ]
+ */
+(function() {
+"use strict";
+
+load("jstests/libs/clustered_collections/clustered_collection_util.js");
+load("jstests/libs/clustered_collections/clustered_collection_create_index_clustered_common.js");
+
+if (!ClusteredCollectionUtil.areClusteredIndexesEnabled(db.getMongo())) {
+ jsTestLog('Skipping test because the clustered indexes feature flag is disabled');
+ return;
+}
+
+const replicatedDB = db.getSiblingDB("create_index_clustered");
+const collName = "coll";
+
+CreateIndexesClusteredTest.runBaseTests(replicatedDB, collName);
+
+// Only cluster key _id is valid for creating replicated clustered collections.
+CreateIndexesClusteredTest.assertCreateIndexesImplicitCreateFails(
+ replicatedDB,
+ collName,
+ {createIndexes: collName, indexes: [{key: {a: 1}, name: "a_1", clustered: true, unique: true}]},
+ 5979701);
+})();
diff --git a/jstests/core/clustered_collection_creation.js b/jstests/core/clustered_collection_creation.js
index cfa5c326c76..7b3e02db552 100644
--- a/jstests/core/clustered_collection_creation.js
+++ b/jstests/core/clustered_collection_creation.js
@@ -6,7 +6,7 @@
* non-replicated collections.
*
* @tags: [
- * requires_fcv_51,
+ * requires_fcv_52,
* assumes_against_mongod_not_mongos,
* assumes_no_implicit_collection_creation_after_drop,
* does_not_support_stepdowns,
@@ -38,17 +38,43 @@ const validateCompoundSecondaryIndexes = function(db, coll, clusterKey) {
coll.drop();
};
-// Cannot create an index with the same key as the cluster key.
-const validateClusteredIndexAlreadyExists = function(db, collName, fullCreateOptions) {
+// Tests it is legal to call createIndex on the cluster key with or without {'clustered': true} as
+// an option. Additionally, confirms it is illegal to call createIndex with the 'clustered' option
+// on a pattern that is not the cluster key.
+const validateCreateIndexOnClusterKey = function(db, collName, fullCreateOptions) {
const clusterKey = fullCreateOptions.clusteredIndex.key;
- const res = db[collName].createIndex(clusterKey);
- assert.commandFailedWithCode(res, ErrorCodes.CannotCreateIndex);
- const clusterKeyField = Object.keys(clusterKey)[0];
- if (clusterKeyField == "_id") {
- assert(res.errmsg.includes("cannot create the _id index on a clustered collection"));
- } else {
- assert(res.errmsg.includes("cannot create an index with the same key as the cluster key"));
- }
+
+ const listIndexes0 = assert.commandWorked(db[collName].runCommand("listIndexes"));
+ const listIndexesClusteredIndex = listIndexes0.cursor.firstBatch[0];
+
+ // Expect listIndexes to append the 'clustered' field to it's clusteredIndex output.
+ assert.docEq(listIndexesClusteredIndex.key, clusterKey);
+ assert.eq(listIndexesClusteredIndex.clustered, true);
+
+ // no-op with the 'clustered' option.
+ assert.commandWorked(
+ db[collName].runCommand({createIndexes: collName, indexes: [listIndexesClusteredIndex]}));
+
+ // no-op without the 'clustered' option.
+ assert.commandWorked(db[collName].createIndex(clusterKey));
+
+ // 'clustered' is not a valid option for an index not on the cluster key.
+ assert.commandFailedWithCode(
+ db[collName].createIndex({notMyIndex: 1}, {clustered: true, unique: true}), 6100904);
+
+ assert.commandFailedWithCode(db[collName].runCommand({
+ createIndexes: collName,
+ indexes: [
+ {key: {a: 1}, name: "a_1"},
+ {key: {b: 1}, name: "b_1_clustered", clustered: true, unique: true}
+ ]
+ }),
+ 6100904);
+
+ // The listIndexes output should be unchanged.
+ const listIndexes1 = assert.commandWorked(db[collName].runCommand("listIndexes"));
+ assert.eq(listIndexes1.cursor.firstBatch.length, 1);
+ assert.docEq(listIndexes1.cursor.firstBatch[0], listIndexes0.cursor.firstBatch[0]);
};
// It is illegal to drop the clusteredIndex. Verify that the various ways of dropping the
@@ -66,15 +92,15 @@ const validateClusteredIndexUndroppable = function(db, collName, fullCreateOptio
};
const validateCreatedCollection = function(db, collName, createOptions) {
- // Upon creating a collection, fields absent in the user provided create options are filled in
- // with default values. The fullCreateOptions should contain default values for the fields not
- // specified by the user.
+ // Upon creating a collection, fields absent in the user provided create options are filled
+ // in with default values. The fullCreateOptions should contain default values for the
+ // fields not specified by the user.
const fullCreateOptions = ClusteredCollectionUtil.constructFullCreateOptions(createOptions);
ClusteredCollectionUtil.validateListCollections(db, collName, fullCreateOptions);
ClusteredCollectionUtil.validateListIndexes(db, collName, fullCreateOptions);
- validateClusteredIndexAlreadyExists(db, collName, fullCreateOptions);
+ validateCreateIndexOnClusterKey(db, collName, fullCreateOptions);
validateClusteredIndexUndroppable(db, collName, fullCreateOptions);
};
diff --git a/jstests/core/timeseries/timeseries_id_index.js b/jstests/core/timeseries/timeseries_id_index.js
index 824a0ff1550..e3bc20d6648 100644
--- a/jstests/core/timeseries/timeseries_id_index.js
+++ b/jstests/core/timeseries/timeseries_id_index.js
@@ -1,7 +1,8 @@
/**
- * Verifies that the _id index cannot be created on a time-series collection.
+ * Verifies that the _id index can be created on a timeseries collection.
*
* @tags: [
+ * requires_fcv_52,
* does_not_support_stepdowns,
* does_not_support_transactions,
* requires_getmore,
@@ -18,8 +19,10 @@ assert.commandWorked(db.createCollection(coll.getName(), {timeseries: {timeField
const bucketsColl = db.getCollection("system.buckets." + coll.getName());
-const res = bucketsColl.createIndex({"_id": 1});
-assert.commandFailedWithCode(res, ErrorCodes.CannotCreateIndex);
-assert(res.errmsg.includes("cannot create the _id index on a clustered collection") ||
- res.errmsg.includes("cannot create an _id index on a collection already clustered by _id"));
+assert.commandWorked(bucketsColl.createIndex({"_id": 1}));
+assert.commandWorked(bucketsColl.createIndex({"_id": 1}, {clustered: true, unique: true}));
+
+// Passing 'clustered' without unique, regardless of the type of clustered collection, is illegal.
+assert.commandFailedWithCode(bucketsColl.createIndex({"_id": 1}, {clustered: true}),
+ ErrorCodes.CannotCreateIndex);
})();