diff options
author | Davis Haupt <davis.haupt@mongodb.com> | 2022-01-06 22:17:46 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-01-06 23:18:25 +0000 |
commit | 0a1a88755daa504c67e13dd49667a06c3c606ee8 (patch) | |
tree | 5a0b162cf0d0773083b416e80ee06f9251617686 | |
parent | 9ce5ff8c50813185e3c7c4351ca775461022ca0e (diff) | |
download | mongo-0a1a88755daa504c67e13dd49667a06c3c606ee8.tar.gz |
SERVER-58358 validate arguments passed to dataSize command
-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"); |