summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTess Avitabile <tess.avitabile@mongodb.com>2016-08-10 16:23:11 -0400
committerTess Avitabile <tess.avitabile@mongodb.com>2016-08-11 18:46:29 -0400
commit844007a979a51a1c7dd49c874f0c50cb66482360 (patch)
tree87556e2fa11e1713ca9dc584004c382c771094d3
parent52cd830b7186f218c296222b89bafe3f1abe932e (diff)
downloadmongo-844007a979a51a1c7dd49c874f0c50cb66482360.tar.gz
SERVER-24239 shardCollection should use simple collation when creating shard key index
-rw-r--r--jstests/sharding/shard_collection_basic.js49
-rw-r--r--src/mongo/s/cluster_write.cpp14
-rw-r--r--src/mongo/s/cluster_write.h3
-rw-r--r--src/mongo/s/commands/cluster_shard_collection_cmd.cpp7
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();