diff options
-rw-r--r-- | jstests/core/datasize_validation.js | 53 | ||||
-rw-r--r-- | src/mongo/db/commands/dbcommands.cpp | 18 |
2 files changed, 70 insertions, 1 deletions
diff --git a/jstests/core/datasize_validation.js b/jstests/core/datasize_validation.js new file mode 100644 index 00000000000..c0f9c9d67b2 --- /dev/null +++ b/jstests/core/datasize_validation.js @@ -0,0 +1,53 @@ +// Cannot implicitly shard accessed collections because the "dataSize" command returns an +// "keyPattern must equal shard key" error response. +// @tags: [assumes_unsharded_collection, requires_fcv_53] + +// +// Test argument validation for dataSize command +// + +(function() { +let coll = db[jsTestName()]; +coll.drop(); +coll.insertOne({_id: 1}); +coll.insertOne({_id: 2}); +coll.insertOne({_id: 3}); +coll.insertOne({_id: 4}); + +assert.commandFailed(db.runCommand({ + 'dataSize': coll.getFullName(), + min: NumberLong("1"), + max: NumberLong("2"), + estimate: false +}), + "min and max should be objects"); + +assert.commandFailed( + db.runCommand({'dataSize': coll.getFullName(), min: {_id: NumberLong("1")}, estimate: false}), + "min and max should both be present"); +assert.commandFailed( + db.runCommand({'dataSize': coll.getFullName(), max: {_id: NumberLong("2")}, estimate: false}), + "min and max should both be present"); + +let resultWithKey = assert.commandWorked(db.runCommand({ + 'dataSize': coll.getFullName(), + keyPattern: {_id: 1}, + min: {_id: NumberLong("1")}, + max: {_id: NumberLong("2")}, + estimate: false +})); +assert.eq(1, resultWithKey.numObjects, "only 1 object should be inspected between min/max bounds."); + +let result = assert.commandWorked(db.runCommand({ + 'dataSize': coll.getFullName(), + min: {_id: NumberLong("1")}, + max: {_id: NumberLong("2")}, + estimate: false +})); +assert.eq(result.size, + resultWithKey.size, + "measured size should be equal after keyPattern properly inferred from min/max bounds."); +assert.eq(result.numObjects, + resultWithKey.numObjects, + "numObjects should be equal after keyPattern properly inferred from min/max bounds."); +})(); diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp index 9167dc0d18e..1addfe77936 100644 --- a/src/mongo/db/commands/dbcommands.cpp +++ b/src/mongo/db/commands/dbcommands.cpp @@ -304,8 +304,24 @@ public: const BSONObj& jsobj, std::string& errmsg, BSONObjBuilder& result) override { - Timer timer; + auto hasMin = jsobj.hasField("min"); + auto hasMax = jsobj.hasField("max"); + + uassert(ErrorCodes::BadValue, + hasMin ? "max must be set if min is set" : "min must be set if max is set", + hasMin == hasMax); + + if (hasMin) { + uassert(ErrorCodes::BadValue, + "min key must be an object", + jsobj["min"].type() == BSONType::Object); + uassert(ErrorCodes::BadValue, + "max key must be an object", + jsobj["max"].type() == BSONType::Object); + } + + Timer timer; std::string ns = jsobj.firstElement().String(); BSONObj min = jsobj.getObjectField("min"); BSONObj max = jsobj.getObjectField("max"); |