diff options
-rw-r--r-- | jstests/sharding/shard_collection_basic.js | 49 | ||||
-rw-r--r-- | src/mongo/s/cluster_write.cpp | 14 | ||||
-rw-r--r-- | src/mongo/s/cluster_write.h | 3 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_shard_collection_cmd.cpp | 7 |
4 files changed, 59 insertions, 14 deletions
diff --git a/jstests/sharding/shard_collection_basic.js b/jstests/sharding/shard_collection_basic.js index 0b99055ed6c..def763969c7 100644 --- a/jstests/sharding/shard_collection_basic.js +++ b/jstests/sharding/shard_collection_basic.js @@ -44,6 +44,14 @@ mongos.getDB(kDbName).dropDatabase(); } + function getIndexSpecByName(coll, indexName) { + var indexes = coll.getIndexes().filter(function(spec) { + return spec.name === indexName; + }); + assert.eq(1, indexes.length, 'index "' + indexName + '" not found"'); + return indexes[0]; + } + // Fail if db is not sharded. assert.commandFailed(mongos.adminCommand({shardCollection: kDbName + '.foo', key: {_id: 1}})); @@ -179,17 +187,40 @@ mongos.getDB(kDbName).foo.drop(); assert.commandWorked( mongos.getDB(kDbName).createCollection('foo', {collation: {locale: 'en_US'}})); - assert.commandFailed(mongos.adminCommand({shardCollection: kDbName + '.foo', key: {_id: 1}})); + assert.commandFailed(mongos.adminCommand({shardCollection: kDbName + '.foo', key: {a: 1}})); + + // shardCollection should fail for the key pattern {_id: 1} if the collection has a non-simple + // default collation. + mongos.getDB(kDbName).foo.drop(); + assert.commandWorked( + mongos.getDB(kDbName).createCollection('foo', {collation: {locale: 'en_US'}})); + assert.commandFailed(mongos.adminCommand( + {shardCollection: kDbName + '.foo', key: {_id: 1}, collation: {locale: 'simple'}})); - // TODO SERVER-24239: - // Test that shardCollection for the key pattern {_id: 1} fails if there is a non-simple - // collection default collation. - // Test that shardCollection for the key pattern {a: 1} fails if there is already an index 'a_1' + // shardCollection should fail for the key pattern {a: 1} if there is already an index 'a_1', // but it has a non-simple collation. - // Test that shardCollection for the key pattern {a: 1} and collation {locale: 'simple'} - // succeeds if there is no index 'a_1', but there is a non-simple collection default collation. - // Test that shardCollection for the key pattern {a: 1} and collation {locale: 'simple'} - // succeeds if there are two indexes on {a: 1} and one has the simple collation. + mongos.getDB(kDbName).foo.drop(); + assert.commandWorked( + mongos.getDB(kDbName).foo.createIndex({a: 1}, {collation: {locale: 'en_US'}})); + assert.commandFailed(mongos.adminCommand({shardCollection: kDbName + '.foo', key: {a: 1}})); + + // shardCollection should succeed for the key pattern {a: 1} and collation {locale: 'simple'} if + // there is no index 'a_1', but there is a non-simple collection default collation. + mongos.getDB(kDbName).foo.drop(); + assert.commandWorked( + mongos.getDB(kDbName).createCollection('foo', {collation: {locale: 'en_US'}})); + assert.commandWorked(mongos.adminCommand( + {shardCollection: kDbName + '.foo', key: {a: 1}, collation: {locale: 'simple'}})); + var indexSpec = getIndexSpecByName(mongos.getDB(kDbName).foo, 'a_1'); + assert(!indexSpec.hasOwnProperty('collation')); + + // shardCollection should succeed for the key pattern {a: 1} if there are two indexes on {a: 1} + // and one has the simple collation. + mongos.getDB(kDbName).foo.drop(); + assert.commandWorked(mongos.getDB(kDbName).foo.createIndex({a: 1}, {name: "a_1_simple"})); + assert.commandWorked(mongos.getDB(kDbName).foo.createIndex( + {a: 1}, {collation: {locale: 'en_US'}, name: "a_1_en_US"})); + assert.commandWorked(mongos.adminCommand({shardCollection: kDbName + '.foo', key: {a: 1}})); // shardCollection should fail on a non-empty collection when the only index available with the // shard key as a prefix has a non-simple collation. diff --git a/src/mongo/s/cluster_write.cpp b/src/mongo/s/cluster_write.cpp index c6e92ea4583..c45fffbf1ec 100644 --- a/src/mongo/s/cluster_write.cpp +++ b/src/mongo/s/cluster_write.cpp @@ -65,7 +65,10 @@ namespace { * Constructs the BSON specification document for the given namespace, index key * and options. */ -BSONObj createIndexDoc(const string& ns, const BSONObj& keys, bool unique) { +BSONObj createIndexDoc(const string& ns, + const BSONObj& keys, + const BSONObj& collation, + bool unique) { BSONObjBuilder indexDoc; indexDoc.append("ns", ns); indexDoc.append("key", keys); @@ -92,6 +95,10 @@ BSONObj createIndexDoc(const string& ns, const BSONObj& keys, bool unique) { indexDoc.append("name", indexName.str()); + if (!collation.isEmpty()) { + indexDoc.append("collation", collation); + } + if (unique) { indexDoc.appendBool("unique", unique); } @@ -146,11 +153,12 @@ void splitIfNeeded(OperationContext* txn, const NamespaceString& nss, const Targ } // namespace -Status clusterCreateIndex(OperationContext* txn, const string& ns, BSONObj keys, bool unique) { +Status clusterCreateIndex( + OperationContext* txn, const string& ns, BSONObj keys, BSONObj collation, bool unique) { const NamespaceString nss(ns); const std::string dbName = nss.db().toString(); - BSONObj indexDoc = createIndexDoc(ns, keys, unique); + BSONObj indexDoc = createIndexDoc(ns, keys, collation, unique); // Go through the shard insert path std::unique_ptr<BatchedInsertRequest> insert(new BatchedInsertRequest()); diff --git a/src/mongo/s/cluster_write.h b/src/mongo/s/cluster_write.h index 0af9615a47c..a0d5e931104 100644 --- a/src/mongo/s/cluster_write.h +++ b/src/mongo/s/cluster_write.h @@ -56,6 +56,7 @@ private: /** * Used only for writes to the config server, config and admin databases. */ -Status clusterCreateIndex(OperationContext* txn, const std::string& ns, BSONObj keys, bool unique); +Status clusterCreateIndex( + OperationContext* txn, const std::string& ns, BSONObj keys, BSONObj collation, bool unique); } // namespace mongo diff --git a/src/mongo/s/commands/cluster_shard_collection_cmd.cpp b/src/mongo/s/commands/cluster_shard_collection_cmd.cpp index 25d74323b5c..6b8eeb654db 100644 --- a/src/mongo/s/commands/cluster_shard_collection_cmd.cpp +++ b/src/mongo/s/commands/cluster_shard_collection_cmd.cpp @@ -400,7 +400,12 @@ public: // 5. If no useful index exists, and collection empty, create one on proposedKey. // Only need to call ensureIndex on primary shard, since indexes get copied to // receiving shard whenever a migrate occurs. - Status status = clusterCreateIndex(txn, nss.ns(), proposedKey, careAboutUnique); + Status status = clusterCreateIndex( + txn, + nss.ns(), + proposedKey, + BSON(CollationSpec::kLocaleField << CollationSpec::kSimpleBinaryComparison), + careAboutUnique); if (!status.isOK()) { errmsg = str::stream() << "ensureIndex failed to create index on " << "primary shard: " << status.reason(); |