diff options
-rw-r--r-- | jstests/noPassthrough/shell_bson_unordered_fields_compare.js | 40 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/bson.cpp | 29 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/bson.h | 3 |
3 files changed, 67 insertions, 5 deletions
diff --git a/jstests/noPassthrough/shell_bson_unordered_fields_compare.js b/jstests/noPassthrough/shell_bson_unordered_fields_compare.js new file mode 100644 index 00000000000..9f9615525e2 --- /dev/null +++ b/jstests/noPassthrough/shell_bson_unordered_fields_compare.js @@ -0,0 +1,40 @@ +/** + * Tests the bsonUnorderedFieldsCompare function. + */ +(function() { +"use strict"; + +const tests = []; + +tests.push(function compareOrderedFieldsSameDoc() { + const doc = {_id: 1, field1: 1, field2: "a"}; + assert.eq(0, bsonUnorderedFieldsCompare(doc, doc), "identical docs were not equal"); +}); + +tests.push(function compareUnorderedFieldsSameDoc() { + const doc1 = {_id: 1, field1: 1, field2: "a"}; + const doc2 = {_id: 1, field2: "a", field1: 1}; + assert.eq(0, + bsonUnorderedFieldsCompare(doc1, doc2), + "docs with same fields but out of order were not equal"); +}); + +tests.push(function compareOrderedFieldsDifferentDoc() { + const doc1 = {_id: 1, field1: 1, field2: "a"}; + const doc2 = {_id: 1, field1: 1, field2: "b"}; + assert.neq(0, bsonUnorderedFieldsCompare(doc1, doc2), "docs with different fields were equal"); +}); + +tests.push(function compareUnorderedFieldsDifferentDoc() { + const doc1 = {_id: 1, field1: 1, field2: "a"}; + const doc2 = {_id: 1, field2: "b", field1: 1}; + assert.neq(0, + bsonUnorderedFieldsCompare(doc1, doc2), + "docs with different fields with different field orders were equal"); +}); + +// Run each test. +tests.forEach(test => { + test(); +}); +})(); diff --git a/src/mongo/scripting/mozjs/bson.cpp b/src/mongo/scripting/mozjs/bson.cpp index 7972cdbaca0..bb9273679dc 100644 --- a/src/mongo/scripting/mozjs/bson.cpp +++ b/src/mongo/scripting/mozjs/bson.cpp @@ -31,6 +31,7 @@ #include "mongo/scripting/mozjs/bson.h" #include <boost/optional.hpp> +#include <fmt/format.h> #include <set> #include "mongo/scripting/mozjs/idwrapper.h" @@ -44,10 +45,13 @@ namespace mongo { namespace mozjs { +using namespace fmt::literals; + const char* const BSONInfo::className = "BSON"; -const JSFunctionSpec BSONInfo::freeFunctions[3] = { +const JSFunctionSpec BSONInfo::freeFunctions[4] = { MONGO_ATTACH_JS_FUNCTION(bsonWoCompare), + MONGO_ATTACH_JS_FUNCTION(bsonUnorderedFieldsCompare), MONGO_ATTACH_JS_FUNCTION(bsonBinaryEqual), JS_FS_END, }; @@ -268,9 +272,13 @@ std::tuple<BSONObj*, bool> BSONInfo::originalBSON(JSContext* cx, JS::HandleObjec } -void BSONInfo::Functions::bsonWoCompare::call(JSContext* cx, JS::CallArgs args) { +namespace { +void bsonCompareCommon(JSContext* cx, + JS::CallArgs args, + StringData funcName, + BSONObj::ComparisonRulesSet rules) { if (args.length() != 2) - uasserted(ErrorCodes::BadValue, "bsonWoCompare needs 2 arguments"); + uasserted(ErrorCodes::BadValue, "{} needs 2 arguments"_format(funcName)); // If either argument is not proper BSON, then we wrap both objects. auto scope = getScope(cx); @@ -280,7 +288,20 @@ void BSONInfo::Functions::bsonWoCompare::call(JSContext* cx, JS::CallArgs args) BSONObj bsonObject1 = getBSONFromArg(cx, args.get(0), isBSON); BSONObj bsonObject2 = getBSONFromArg(cx, args.get(1), isBSON); - args.rval().setInt32(bsonObject1.woCompare(bsonObject2)); + args.rval().setInt32(bsonObject1.woCompare(bsonObject2, {}, rules)); +} +} // namespace + +void BSONInfo::Functions::bsonWoCompare::call(JSContext* cx, JS::CallArgs args) { + bsonCompareCommon(cx, args, "bsonWoCompare", BSONObj::ComparatorInterface::kConsiderFieldName); +} + +void BSONInfo::Functions::bsonUnorderedFieldsCompare::call(JSContext* cx, JS::CallArgs args) { + bsonCompareCommon(cx, + args, + "bsonWoCompare", + BSONObj::ComparatorInterface::kConsiderFieldName | + BSONObj::ComparatorInterface::kIgnoreFieldOrder); } void BSONInfo::Functions::bsonBinaryEqual::call(JSContext* cx, JS::CallArgs args) { diff --git a/src/mongo/scripting/mozjs/bson.h b/src/mongo/scripting/mozjs/bson.h index 79768283a58..30cea0bb776 100644 --- a/src/mongo/scripting/mozjs/bson.h +++ b/src/mongo/scripting/mozjs/bson.h @@ -72,10 +72,11 @@ struct BSONInfo : public BaseInfo { struct Functions { MONGO_DECLARE_JS_FUNCTION(bsonWoCompare); + MONGO_DECLARE_JS_FUNCTION(bsonUnorderedFieldsCompare); MONGO_DECLARE_JS_FUNCTION(bsonBinaryEqual); }; - static const JSFunctionSpec freeFunctions[3]; + static const JSFunctionSpec freeFunctions[4]; static std::tuple<BSONObj*, bool> originalBSON(JSContext* cx, JS::HandleObject obj); static void make( |