summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-05-05 10:46:58 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-05-05 23:13:15 -0400
commit381995f9dcee3c538a3658da00bf49f40bf3af5d (patch)
tree3f6b16533def7e34e38173b9b03bf07c5552fadb
parentaa8ab6611d27a6a4b014d82a37eb658760fa7425 (diff)
downloadmongo-381995f9dcee3c538a3658da00bf49f40bf3af5d.tar.gz
SERVER-29066 Implicitly create the database in findAndModifyr3.4.5-rc0
-rw-r--r--jstests/sharding/findandmodify1.js71
-rw-r--r--src/mongo/s/commands/cluster_find_and_modify_cmd.cpp3
2 files changed, 44 insertions, 30 deletions
diff --git a/jstests/sharding/findandmodify1.js b/jstests/sharding/findandmodify1.js
index 08eb6602370..d1b707b0b01 100644
--- a/jstests/sharding/findandmodify1.js
+++ b/jstests/sharding/findandmodify1.js
@@ -1,66 +1,77 @@
(function() {
+ 'use strict';
- var s = new ShardingTest({name: "find_and_modify_sharded", shards: 2});
+ var s = new ShardingTest({shards: 2});
- s.adminCommand({enablesharding: "test"});
- db = s.getDB("test");
- s.ensurePrimaryShard('test', 'shard0001');
- primary = s.getPrimaryShard("test").getDB("test");
- secondary = s.getOther(primary).getDB("test");
+ // Make sure that findAndModify with upsert against a non-existent database and collection will
+ // implicitly create them both
+ assert.eq(undefined,
+ assert.commandWorked(s.s0.adminCommand({listDatabases: 1, nameOnly: 1}))
+ .databases.find((dbInfo) => {
+ return (dbInfo.name === 'NewUnshardedDB');
+ }));
- numObjs = 20;
+ var newlyCreatedDb = s.getDB('NewUnshardedDB');
+ assert.eq(0, newlyCreatedDb.unsharded_coll.find({}).itcount());
+ newlyCreatedDb.unsharded_coll.findAndModify(
+ {query: {_id: 1}, update: {$set: {Value: 'Value'}}, upsert: true});
+ assert.eq(1, newlyCreatedDb.unsharded_coll.find({}).itcount());
- // Turn balancer off - with small numbers of chunks the balancer tries to correct all
- // imbalances, not just < 8
- s.s.getDB("config").settings.update({_id: "balancer"}, {$set: {stopped: true}}, true);
+ // Tests with sharded database
+ assert.commandWorked(s.s0.adminCommand({enablesharding: "test"}));
+ s.ensurePrimaryShard('test', s.shard1.shardName);
+ assert.commandWorked(s.s0.adminCommand({shardcollection: "test.sharded_coll", key: {_id: 1}}));
- s.adminCommand({shardcollection: "test.stuff", key: {_id: 1}});
+ var db = s.getDB('test');
- // pre-split the collection so to avoid interference from balancer
- s.adminCommand({split: "test.stuff", middle: {_id: numObjs / 2}});
- s.adminCommand(
- {movechunk: "test.stuff", find: {_id: numObjs / 2}, to: secondary.getMongo().name});
+ var numObjs = 20;
- var bulk = db.stuff.initializeUnorderedBulkOp();
+ // Pre-split the collection so to avoid interference from auto-split
+ assert.commandWorked(
+ s.s0.adminCommand({split: "test.sharded_coll", middle: {_id: numObjs / 2}}));
+ assert.commandWorked(s.s0.adminCommand(
+ {movechunk: "test.sharded_coll", find: {_id: numObjs / 2}, to: s.shard0.shardName}));
+
+ var bulk = db.sharded_coll.initializeUnorderedBulkOp();
for (var i = 0; i < numObjs; i++) {
bulk.insert({_id: i});
}
assert.writeOK(bulk.execute());
- // put two docs in each chunk (avoid the split in 0, since there are no docs less than 0)
+ // Put two docs in each chunk (avoid the split in 0, since there are no docs less than 0)
for (var i = 2; i < numObjs; i += 2) {
if (i == numObjs / 2)
continue;
- s.adminCommand({split: "test.stuff", middle: {_id: i}});
+
+ assert.commandWorked(s.s0.adminCommand({split: "test.sharded_coll", middle: {_id: i}}));
}
s.printChunks();
- assert.eq(numObjs / 2, s.config.chunks.count(), "split failed");
- assert.eq(numObjs / 4, s.config.chunks.count({shard: "shard0000"}));
- assert.eq(numObjs / 4, s.config.chunks.count({shard: "shard0001"}));
+ assert.eq(numObjs / 2, s.config.chunks.count(), 'Split was incorrect');
+ assert.eq(numObjs / 4, s.config.chunks.count({shard: s.shard0.shardName}));
+ assert.eq(numObjs / 4, s.config.chunks.count({shard: s.shard1.shardName}));
// update
for (var i = 0; i < numObjs; i++) {
- assert.eq(db.stuff.count({b: 1}), i, "2 A");
+ assert.eq(db.sharded_coll.count({b: 1}), i, "2 A");
- var out = db.stuff.findAndModify({query: {_id: i, b: null}, update: {$set: {b: 1}}});
+ var out = db.sharded_coll.findAndModify({query: {_id: i, b: null}, update: {$set: {b: 1}}});
assert.eq(out._id, i, "2 E");
- assert.eq(db.stuff.count({b: 1}), i + 1, "2 B");
+ assert.eq(db.sharded_coll.count({b: 1}), i + 1, "2 B");
}
// remove
for (var i = 0; i < numObjs; i++) {
- assert.eq(db.stuff.count(), numObjs - i, "3 A");
- assert.eq(db.stuff.count({_id: i}), 1, "3 B");
+ assert.eq(db.sharded_coll.count(), numObjs - i, "3 A");
+ assert.eq(db.sharded_coll.count({_id: i}), 1, "3 B");
- var out = db.stuff.findAndModify({remove: true, query: {_id: i}});
+ var out = db.sharded_coll.findAndModify({remove: true, query: {_id: i}});
- assert.eq(db.stuff.count(), numObjs - i - 1, "3 C");
- assert.eq(db.stuff.count({_id: i}), 0, "3 D");
+ assert.eq(db.sharded_coll.count(), numObjs - i - 1, "3 C");
+ assert.eq(db.sharded_coll.count({_id: i}), 0, "3 D");
assert.eq(out._id, i, "3 E");
}
s.stop();
-
})();
diff --git a/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp b/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
index feae1fab5e2..a19fdc5c098 100644
--- a/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
+++ b/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
@@ -42,6 +42,7 @@
#include "mongo/s/catalog_cache.h"
#include "mongo/s/client/shard_connection.h"
#include "mongo/s/client/shard_registry.h"
+#include "mongo/s/commands/cluster_commands_common.h"
#include "mongo/s/commands/cluster_explain.h"
#include "mongo/s/commands/cluster_write.h"
#include "mongo/s/commands/sharded_command_processing.h"
@@ -167,6 +168,8 @@ public:
// findAndModify should only be creating database if upsert is true, but this would require
// that the parsing be pulled into this function.
+ uassertStatusOK(createShardDatabase(opCtx, nss.db()));
+
auto routingInfo =
uassertStatusOK(Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfo(opCtx, nss));
if (!routingInfo.cm()) {