diff options
author | XueruiFa <xuerui.fa@mongodb.com> | 2022-11-14 20:52:14 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-16 15:37:17 +0000 |
commit | 9348dbff25128de576b94b76997fcefd997eb4b3 (patch) | |
tree | 0ecc664cd48cf129a6336c65ccf53dfa282cd0ba | |
parent | 26cf04e6fbfd3c6f37f81028b6f96fa80731bf14 (diff) | |
download | mongo-9348dbff25128de576b94b76997fcefd997eb4b3.tar.gz |
SERVER-52545: Add bsonUnorderedFieldsCompare
(partially cherry picked from commit b83bf99b6e48e2f41ea3b1e7ed6aeb4cf1eb0d31)
-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 0585022615a..efe78d2feab 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[4] = { +const JSFunctionSpec BSONInfo::freeFunctions[5] = { MONGO_ATTACH_JS_FUNCTION(bsonWoCompare), + MONGO_ATTACH_JS_FUNCTION(bsonUnorderedFieldsCompare), MONGO_ATTACH_JS_FUNCTION(bsonBinaryEqual), MONGO_ATTACH_JS_FUNCTION(bsonObjToArray), JS_FS_END, @@ -276,9 +280,13 @@ void BSONInfo::Functions::bsonObjToArray::call(JSContext* cx, JS::CallArgs args) ValueReader(cx, args.rval()).fromBSONArray(obj, nullptr, false); } -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); @@ -288,7 +296,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 f515c4fd32a..a2cc5f1d2d3 100644 --- a/src/mongo/scripting/mozjs/bson.h +++ b/src/mongo/scripting/mozjs/bson.h @@ -72,11 +72,12 @@ struct BSONInfo : public BaseInfo { struct Functions { MONGO_DECLARE_JS_FUNCTION(bsonWoCompare); + MONGO_DECLARE_JS_FUNCTION(bsonUnorderedFieldsCompare); MONGO_DECLARE_JS_FUNCTION(bsonBinaryEqual); MONGO_DECLARE_JS_FUNCTION(bsonObjToArray); }; - static const JSFunctionSpec freeFunctions[4]; + static const JSFunctionSpec freeFunctions[5]; static std::tuple<BSONObj*, bool> originalBSON(JSContext* cx, JS::HandleObject obj); static void make( |