diff options
author | Haley Connelly <haley.connelly@mongodb.com> | 2021-12-14 16:55:57 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-12-14 17:53:31 +0000 |
commit | aa3e4bb18dec429a7fdec60fa8a17e19045c398a (patch) | |
tree | ec117a87db78f0c8e6d0154973dc6e0df8eeee9d /jstests/core | |
parent | 1f87032345d910cba09516c09a340a08cb83cd3f (diff) | |
download | mongo-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.js | 36 | ||||
-rw-r--r-- | jstests/core/clustered_collection_creation.js | 56 | ||||
-rw-r--r-- | jstests/core/timeseries/timeseries_id_index.js | 13 |
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); })(); |