summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXueruiFa <xuerui.fa@mongodb.com>2022-11-15 16:50:18 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-11-16 18:37:33 +0000
commit06d618d3d6dfa4423b574e029fed8b84779a45d1 (patch)
tree7f09297277feef4d7392117305d1d2cfdc737c6d
parent792f237975470ab61e3e9cd4b54ede87ed9377d8 (diff)
downloadmongo-06d618d3d6dfa4423b574e029fed8b84779a45d1.tar.gz
SERVER-52545 [v4.2] Add bsonUnorderedFieldsCompare
(partially cherry picked from commit b83bf99b6e48e2f41ea3b1e7ed6aeb4cf1eb0d31)
-rw-r--r--jstests/noPassthrough/shell_bson_unordered_fields_compare.js40
-rw-r--r--src/mongo/scripting/mozjs/bson.cpp29
-rw-r--r--src/mongo/scripting/mozjs/bson.h3
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(