summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2016-08-12 15:58:56 -0400
committerDavid Storch <david.storch@10gen.com>2016-08-18 11:14:17 -0400
commit26543060c852aac22f26143a04bf7789ec8fec53 (patch)
treedf3ae49e5c4745058be29b7ec8a8e4b528b50a9a /src/mongo/db/pipeline
parent13fa28982d008568f7620d73ddec0c61fad7cbc8 (diff)
downloadmongo-26543060c852aac22f26143a04bf7789ec8fec53.tar.gz
SERVER-24508 BSONObj::ComparatorInterface
BSONObj instances should now be compared via the comparator interface's evaluate() method. This preferred over using BSONObj::woCompare() directly. If the comparison doesn't require any database semantics (e.g. there is no collation), there is a global instance of the SimpleBSONObjComparator which should be used for BSONObj comparisons. If the comparison requires special semantics, then callers must instantiate their own comparator object.
Diffstat (limited to 'src/mongo/db/pipeline')
-rw-r--r--src/mongo/db/pipeline/aggregation_request_test.cpp6
-rw-r--r--src/mongo/db/pipeline/document_source_test.cpp104
-rw-r--r--src/mongo/db/pipeline/document_value_test.cpp14
-rw-r--r--src/mongo/db/pipeline/expression_test.cpp72
-rw-r--r--src/mongo/db/pipeline/lookup_set_cache_test.cpp4
-rw-r--r--src/mongo/db/pipeline/pipeline_d.cpp12
-rw-r--r--src/mongo/db/pipeline/pipeline_test.cpp4
7 files changed, 115 insertions, 101 deletions
diff --git a/src/mongo/db/pipeline/aggregation_request_test.cpp b/src/mongo/db/pipeline/aggregation_request_test.cpp
index b9fe685961f..acd38732522 100644
--- a/src/mongo/db/pipeline/aggregation_request_test.cpp
+++ b/src/mongo/db/pipeline/aggregation_request_test.cpp
@@ -60,9 +60,9 @@ TEST(AggregationRequestTest, ShouldParseAllKnownOptions) {
ASSERT_TRUE(request.shouldBypassDocumentValidation());
ASSERT_TRUE(request.isCursorCommand());
ASSERT_EQ(request.getBatchSize().get(), 10);
- ASSERT_EQ(request.getCollation(),
- BSON("locale"
- << "en_US"));
+ ASSERT_BSONOBJ_EQ(request.getCollation(),
+ BSON("locale"
+ << "en_US"));
}
//
diff --git a/src/mongo/db/pipeline/document_source_test.cpp b/src/mongo/db/pipeline/document_source_test.cpp
index 7b2a0e72c12..ba326b9c82d 100644
--- a/src/mongo/db/pipeline/document_source_test.cpp
+++ b/src/mongo/db/pipeline/document_source_test.cpp
@@ -134,50 +134,50 @@ public:
const char* array[] = {"a", "b"}; // basic
DepsTracker deps;
deps.fields = arrayToSet(array);
- ASSERT_EQUALS(deps.toProjection(), BSON("a" << 1 << "b" << 1 << "_id" << 0));
+ ASSERT_BSONOBJ_EQ(deps.toProjection(), BSON("a" << 1 << "b" << 1 << "_id" << 0));
}
{
const char* array[] = {"a", "ab"}; // prefixed but not subfield
DepsTracker deps;
deps.fields = arrayToSet(array);
- ASSERT_EQUALS(deps.toProjection(), BSON("a" << 1 << "ab" << 1 << "_id" << 0));
+ ASSERT_BSONOBJ_EQ(deps.toProjection(), BSON("a" << 1 << "ab" << 1 << "_id" << 0));
}
{
const char* array[] = {"a", "b", "a.b"}; // a.b included by a
DepsTracker deps;
deps.fields = arrayToSet(array);
- ASSERT_EQUALS(deps.toProjection(), BSON("a" << 1 << "b" << 1 << "_id" << 0));
+ ASSERT_BSONOBJ_EQ(deps.toProjection(), BSON("a" << 1 << "b" << 1 << "_id" << 0));
}
{
const char* array[] = {"a", "_id"}; // _id now included
DepsTracker deps;
deps.fields = arrayToSet(array);
- ASSERT_EQUALS(deps.toProjection(), BSON("a" << 1 << "_id" << 1));
+ ASSERT_BSONOBJ_EQ(deps.toProjection(), BSON("a" << 1 << "_id" << 1));
}
{
const char* array[] = {"a", "_id.a"}; // still include whole _id (SERVER-7502)
DepsTracker deps;
deps.fields = arrayToSet(array);
- ASSERT_EQUALS(deps.toProjection(), BSON("a" << 1 << "_id" << 1));
+ ASSERT_BSONOBJ_EQ(deps.toProjection(), BSON("a" << 1 << "_id" << 1));
}
{
const char* array[] = {"a", "_id", "_id.a"}; // handle both _id and subfield
DepsTracker deps;
deps.fields = arrayToSet(array);
- ASSERT_EQUALS(deps.toProjection(), BSON("a" << 1 << "_id" << 1));
+ ASSERT_BSONOBJ_EQ(deps.toProjection(), BSON("a" << 1 << "_id" << 1));
}
{
const char* array[] = {"a", "_id", "_id_a"}; // _id prefixed but non-subfield
DepsTracker deps;
deps.fields = arrayToSet(array);
- ASSERT_EQUALS(deps.toProjection(), BSON("_id_a" << 1 << "a" << 1 << "_id" << 1));
+ ASSERT_BSONOBJ_EQ(deps.toProjection(), BSON("_id_a" << 1 << "a" << 1 << "_id" << 1));
}
{
const char* array[] = {"a"}; // fields ignored with needWholeDocument
DepsTracker deps;
deps.fields = arrayToSet(array);
deps.needWholeDocument = true;
- ASSERT_EQUALS(deps.toProjection(), BSONObj());
+ ASSERT_BSONOBJ_EQ(deps.toProjection(), BSONObj());
}
{
const char* array[] = {"a"}; // needTextScore with needWholeDocument
@@ -185,14 +185,15 @@ public:
deps.fields = arrayToSet(array);
deps.needWholeDocument = true;
deps.setNeedTextScore(true);
- ASSERT_EQUALS(deps.toProjection(), BSON(Document::metaFieldTextScore << metaTextScore));
+ ASSERT_BSONOBJ_EQ(deps.toProjection(),
+ BSON(Document::metaFieldTextScore << metaTextScore));
}
{
const char* array[] = {"a"}; // needTextScore without needWholeDocument
DepsTracker deps(DepsTracker::MetadataAvailable::kTextScore);
deps.fields = arrayToSet(array);
deps.setNeedTextScore(true);
- ASSERT_EQUALS(
+ ASSERT_BSONOBJ_EQ(
deps.toProjection(),
BSON(Document::metaFieldTextScore << metaTextScore << "a" << 1 << "_id" << 0));
}
@@ -402,7 +403,7 @@ TEST(MakeMatchStageFromInput, NonArrayValueUsesEqQuery) {
Document input = DOC("local" << 1);
BSONObj matchStage = DocumentSourceLookUp::makeMatchStageFromInput(
input, FieldPath("local"), "foreign", BSONObj());
- ASSERT_EQ(matchStage, fromjson("{$match: {$and: [{foreign: {$eq: 1}}, {}]}}"));
+ ASSERT_BSONOBJ_EQ(matchStage, fromjson("{$match: {$and: [{foreign: {$eq: 1}}, {}]}}"));
}
TEST(MakeMatchStageFromInput, RegexValueUsesEqQuery) {
@@ -410,9 +411,10 @@ TEST(MakeMatchStageFromInput, RegexValueUsesEqQuery) {
Document input = DOC("local" << Value(regex));
BSONObj matchStage = DocumentSourceLookUp::makeMatchStageFromInput(
input, FieldPath("local"), "foreign", BSONObj());
- ASSERT_EQ(matchStage,
- BSON("$match" << BSON("$and" << BSON_ARRAY(BSON("foreign" << BSON("$eq" << regex))
- << BSONObj()))));
+ ASSERT_BSONOBJ_EQ(
+ matchStage,
+ BSON("$match" << BSON(
+ "$and" << BSON_ARRAY(BSON("foreign" << BSON("$eq" << regex)) << BSONObj()))));
}
TEST(MakeMatchStageFromInput, ArrayValueUsesInQuery) {
@@ -420,7 +422,7 @@ TEST(MakeMatchStageFromInput, ArrayValueUsesInQuery) {
Document input = DOC("local" << Value(inputArray));
BSONObj matchStage = DocumentSourceLookUp::makeMatchStageFromInput(
input, FieldPath("local"), "foreign", BSONObj());
- ASSERT_EQ(matchStage, fromjson("{$match: {$and: [{foreign: {$in: [1, 2]}}, {}]}}"));
+ ASSERT_BSONOBJ_EQ(matchStage, fromjson("{$match: {$and: [{foreign: {$in: [1, 2]}}, {}]}}"));
}
TEST(MakeMatchStageFromInput, ArrayValueWithRegexUsesOrQuery) {
@@ -429,13 +431,14 @@ TEST(MakeMatchStageFromInput, ArrayValueWithRegexUsesOrQuery) {
Document input = DOC("local" << Value(inputArray));
BSONObj matchStage = DocumentSourceLookUp::makeMatchStageFromInput(
input, FieldPath("local"), "foreign", BSONObj());
- ASSERT_EQ(matchStage,
- BSON("$match" << BSON(
- "$and" << BSON_ARRAY(
- BSON("$or" << BSON_ARRAY(BSON("foreign" << BSON("$eq" << Value(1)))
- << BSON("foreign" << BSON("$eq" << regex))
- << BSON("foreign" << BSON("$eq" << Value(2)))))
- << BSONObj()))));
+ ASSERT_BSONOBJ_EQ(
+ matchStage,
+ BSON("$match" << BSON(
+ "$and" << BSON_ARRAY(
+ BSON("$or" << BSON_ARRAY(BSON("foreign" << BSON("$eq" << Value(1)))
+ << BSON("foreign" << BSON("$eq" << regex))
+ << BSON("foreign" << BSON("$eq" << Value(2)))))
+ << BSONObj()))));
}
} // namespace DocumentSourceLookUp
@@ -485,7 +488,7 @@ private:
BSONElement specElement = spec.firstElement();
intrusive_ptr<DocumentSource> generated =
DocumentSourceGroup::createFromBson(specElement, ctx());
- ASSERT_EQUALS(spec, toBson(generated));
+ ASSERT_BSONOBJ_EQ(spec, toBson(generated));
}
intrusive_ptr<DocumentSource> _group;
TempDir _tempDir;
@@ -513,7 +516,7 @@ public:
boost::optional<Document> next = group()->getNext();
ASSERT(bool(next));
// The constant _id value from the $group spec is passed through.
- ASSERT_EQUALS(expected(), next->toBson());
+ ASSERT_BSONOBJ_EQ(expected(), next->toBson());
}
protected:
@@ -803,7 +806,7 @@ protected:
bsonResultSet << i->second;
}
// Check the result set.
- ASSERT_EQUALS(expectedResultSet(), bsonResultSet.arr());
+ ASSERT_BSONOBJ_EQ(expectedResultSet(), bsonResultSet.arr());
}
};
@@ -1419,8 +1422,8 @@ TEST_F(ProjectStageTest, ShouldOptimizeInnerExpressions) {
// The $and should have been replaced with its only argument.
vector<Value> serializedArray;
project()->serializeToArray(serializedArray);
- ASSERT_EQUALS(serializedArray[0].getDocument().toBson(),
- fromjson("{$project: {_id: true, a: {$const: true}}}"));
+ ASSERT_BSONOBJ_EQ(serializedArray[0].getDocument().toBson(),
+ fromjson("{$project: {_id: true, a: {$const: true}}}"));
};
TEST_F(ProjectStageTest, ShouldErrorOnNonObjectSpec) {
@@ -1882,7 +1885,7 @@ private:
void checkBsonRepresentation(const BSONObj& spec) {
Value serialized = static_cast<DocumentSourceSample*>(sample())->serialize(false);
auto generatedSpec = serialized.getDocument().toBson();
- ASSERT_EQUALS(spec, generatedSpec);
+ ASSERT_BSONOBJ_EQ(spec, generatedSpec);
}
};
@@ -2161,7 +2164,7 @@ private:
vector<Value> arr;
_sort->serializeToArray(arr);
BSONObj generatedSpec = arr[0].getDocument().toBson();
- ASSERT_EQUALS(spec, generatedSpec);
+ ASSERT_BSONOBJ_EQ(spec, generatedSpec);
}
intrusive_ptr<DocumentSource> _sort;
};
@@ -2178,7 +2181,7 @@ public:
{ // pre-limit checks
vector<Value> arr;
sort()->serializeToArray(arr);
- ASSERT_EQUALS(arr[0].getDocument().toBson(), BSON("$sort" << BSON("a" << 1)));
+ ASSERT_BSONOBJ_EQ(arr[0].getDocument().toBson(), BSON("$sort" << BSON("a" << 1)));
ASSERT(sort()->getShardSource() == NULL);
ASSERT(sort()->getMergeSource() != NULL);
@@ -2242,7 +2245,7 @@ public:
bsonResultSet << *i;
}
// Check the result set.
- ASSERT_EQUALS(expectedResultSet(), bsonResultSet.arr());
+ ASSERT_BSONOBJ_EQ(expectedResultSet(), bsonResultSet.arr());
}
protected:
@@ -2695,7 +2698,7 @@ private:
bsonResultSet << *i;
}
// Check the result set.
- ASSERT_EQUALS(expectedResults, bsonResultSet.arr());
+ ASSERT_BSONOBJ_EQ(expectedResults, bsonResultSet.arr());
}
/**
@@ -2706,8 +2709,8 @@ private:
vector<Value> arr;
_unwind->serializeToArray(arr);
BSONObj generatedSpec = Value(arr[0]).getDocument().toBson();
- ASSERT_EQUALS(expectedSerialization(preserveNullAndEmptyArrays, includeArrayIndex),
- generatedSpec);
+ ASSERT_BSONOBJ_EQ(expectedSerialization(preserveNullAndEmptyArrays, includeArrayIndex),
+ generatedSpec);
}
BSONObj expectedSerialization(bool preserveNullAndEmptyArrays, bool includeArrayIndex) const {
@@ -3356,7 +3359,7 @@ public:
void test(string input, string safePortion) {
try {
intrusive_ptr<DocumentSourceMatch> match = makeMatch(input);
- ASSERT_EQUALS(match->redactSafePortion(), fromjson(safePortion));
+ ASSERT_BSONOBJ_EQ(match->redactSafePortion(), fromjson(safePortion));
} catch (...) {
unittest::log() << "Problem with redactSafePortion() of: " << input;
throw;
@@ -3612,60 +3615,61 @@ public:
Pipeline::SourceContainer container;
// Check initial state
- ASSERT_EQUALS(match1->getQuery(), BSON("a" << 1));
- ASSERT_EQUALS(match2->getQuery(), BSON("b" << 1));
- ASSERT_EQUALS(match3->getQuery(), BSON("c" << 1));
+ ASSERT_BSONOBJ_EQ(match1->getQuery(), BSON("a" << 1));
+ ASSERT_BSONOBJ_EQ(match2->getQuery(), BSON("b" << 1));
+ ASSERT_BSONOBJ_EQ(match3->getQuery(), BSON("c" << 1));
container.push_back(match1);
container.push_back(match2);
match1->optimizeAt(container.begin(), &container);
ASSERT_EQUALS(container.size(), 1U);
- ASSERT_EQUALS(match1->getQuery(), fromjson("{'$and': [{a:1}, {b:1}]}"));
+ ASSERT_BSONOBJ_EQ(match1->getQuery(), fromjson("{'$and': [{a:1}, {b:1}]}"));
container.push_back(match3);
match1->optimizeAt(container.begin(), &container);
ASSERT_EQUALS(container.size(), 1U);
- ASSERT_EQUALS(match1->getQuery(),
- fromjson("{'$and': [{'$and': [{a:1}, {b:1}]},"
- "{c:1}]}"));
+ ASSERT_BSONOBJ_EQ(match1->getQuery(),
+ fromjson("{'$and': [{'$and': [{a:1}, {b:1}]},"
+ "{c:1}]}"));
}
};
TEST(ObjectForMatch, ShouldExtractTopLevelFieldIfDottedFieldNeeded) {
Document input(fromjson("{a: 1, b: {c: 1, d: 1}}"));
BSONObj expected = fromjson("{b: {c: 1, d: 1}}");
- ASSERT_EQUALS(expected, DocumentSourceMatch::getObjectForMatch(input, {"b.c"}));
+ ASSERT_BSONOBJ_EQ(expected, DocumentSourceMatch::getObjectForMatch(input, {"b.c"}));
}
TEST(ObjectForMatch, ShouldExtractEntireArray) {
Document input(fromjson("{a: [1, 2, 3], b: 1}"));
BSONObj expected = fromjson("{a: [1, 2, 3]}");
- ASSERT_EQUALS(expected, DocumentSourceMatch::getObjectForMatch(input, {"a"}));
+ ASSERT_BSONOBJ_EQ(expected, DocumentSourceMatch::getObjectForMatch(input, {"a"}));
}
TEST(ObjectForMatch, ShouldOnlyAddPrefixedFieldOnceIfTwoDottedSubfields) {
Document input(fromjson("{a: 1, b: {c: 1, f: {d: {e: 1}}}}"));
BSONObj expected = fromjson("{b: {c: 1, f: {d: {e: 1}}}}");
- ASSERT_EQUALS(expected, DocumentSourceMatch::getObjectForMatch(input, {"b.f", "b.f.d.e"}));
+ ASSERT_BSONOBJ_EQ(expected, DocumentSourceMatch::getObjectForMatch(input, {"b.f", "b.f.d.e"}));
}
TEST(ObjectForMatch, MissingFieldShouldNotAppearInResult) {
Document input(fromjson("{a: 1}"));
BSONObj expected;
- ASSERT_EQUALS(expected, DocumentSourceMatch::getObjectForMatch(input, {"b", "c"}));
+ ASSERT_BSONOBJ_EQ(expected, DocumentSourceMatch::getObjectForMatch(input, {"b", "c"}));
}
TEST(ObjectForMatch, ShouldSerializeNothingIfNothingIsNeeded) {
Document input(fromjson("{a: 1, b: {c: 1}}"));
BSONObj expected;
- ASSERT_EQUALS(expected, DocumentSourceMatch::getObjectForMatch(input, std::set<std::string>{}));
+ ASSERT_BSONOBJ_EQ(expected,
+ DocumentSourceMatch::getObjectForMatch(input, std::set<std::string>{}));
}
TEST(ObjectForMatch, ShouldExtractEntireArrayFromPrefixOfDottedField) {
Document input(fromjson("{a: [{b: 1}, {b: 2}], c: 1}"));
BSONObj expected = fromjson("{a: [{b: 1}, {b: 2}]}");
- ASSERT_EQUALS(expected, DocumentSourceMatch::getObjectForMatch(input, {"a.b"}));
+ ASSERT_BSONOBJ_EQ(expected, DocumentSourceMatch::getObjectForMatch(input, {"a.b"}));
}
@@ -4812,8 +4816,8 @@ TEST_F(AddFieldsTest, OptimizesInnerExpressions) {
// The $and should have been replaced with its only argument.
vector<Value> serializedArray;
addFields()->serializeToArray(serializedArray);
- ASSERT_EQUALS(serializedArray[0].getDocument().toBson(),
- fromjson("{$addFields: {a: {$const: true}}}"));
+ ASSERT_BSONOBJ_EQ(serializedArray[0].getDocument().toBson(),
+ fromjson("{$addFields: {a: {$const: true}}}"));
}
// Verify that the addFields stage requires a valid object specification.
diff --git a/src/mongo/db/pipeline/document_value_test.cpp b/src/mongo/db/pipeline/document_value_test.cpp
index 8c5f9a755c0..adec442f7b8 100644
--- a/src/mongo/db/pipeline/document_value_test.cpp
+++ b/src/mongo/db/pipeline/document_value_test.cpp
@@ -69,7 +69,7 @@ void assertRoundTrips(const Document& document1) {
BSONObj obj1 = toBson(document1);
Document document2 = fromBson(obj1);
BSONObj obj2 = toBson(document2);
- ASSERT_EQUALS(obj1, obj2);
+ ASSERT_BSONOBJ_EQ(obj1, obj2);
ASSERT_DOCUMENT_EQ(document1, document2);
}
@@ -407,7 +407,7 @@ public:
const Document doc2 = fromBson(obj);
// logical equality
- ASSERT_EQUALS(obj, obj2);
+ ASSERT_BSONOBJ_EQ(obj, obj2);
ASSERT_DOCUMENT_EQ(doc, doc2);
// binary equality
@@ -567,7 +567,7 @@ void assertRoundTrips(const Value& value1) {
BSONObj obj1 = toBson(value1);
Value value2 = fromBson(obj1);
BSONObj obj2 = toBson(value2);
- ASSERT_EQUALS(obj1, obj2);
+ ASSERT_BSONOBJ_EQ(obj1, obj2);
ASSERT_VALUE_EQ(value1, value2);
ASSERT_EQUALS(value1.getType(), value2.getType());
}
@@ -1428,9 +1428,9 @@ public:
Value(4.4).addToBsonObj(&bob, "a");
Value(22).addToBsonObj(&bob, "b");
Value("astring").addToBsonObj(&bob, "c");
- ASSERT_EQUALS(BSON("a" << 4.4 << "b" << 22 << "c"
- << "astring"),
- bob.obj());
+ ASSERT_BSONOBJ_EQ(BSON("a" << 4.4 << "b" << 22 << "c"
+ << "astring"),
+ bob.obj());
}
};
@@ -1442,7 +1442,7 @@ public:
Value(4.4).addToBsonArray(&bab);
Value(22).addToBsonArray(&bab);
Value("astring").addToBsonArray(&bab);
- ASSERT_EQUALS(BSON_ARRAY(4.4 << 22 << "astring"), bab.arr());
+ ASSERT_BSONOBJ_EQ(BSON_ARRAY(4.4 << 22 << "astring"), bab.arr());
}
};
diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp
index 144f2538723..ed579bd3bc3 100644
--- a/src/mongo/db/pipeline/expression_test.cpp
+++ b/src/mongo/db/pipeline/expression_test.cpp
@@ -99,7 +99,7 @@ static BSONObj constify(const BSONObj& obj, bool parentIsArray = false) {
/** Check binary equality, ensuring use of the same numeric types. */
static void assertBinaryEqual(const BSONObj& expected, const BSONObj& actual) {
- ASSERT_EQUALS(expected, actual);
+ ASSERT_BSONOBJ_EQ(expected, actual);
ASSERT(expected.binaryEqual(actual));
}
@@ -212,13 +212,13 @@ protected:
++i) {
dependenciesBson << *i;
}
- ASSERT_EQUALS(expectedDependencies, dependenciesBson.arr());
+ ASSERT_BSONOBJ_EQ(expectedDependencies, dependenciesBson.arr());
ASSERT_EQUALS(false, dependencies.needWholeDocument);
ASSERT_EQUALS(false, dependencies.getNeedTextScore());
}
void assertContents(const intrusive_ptr<Testable>& expr, const BSONArray& expectedContents) {
- ASSERT_EQUALS(constify(BSON("$testable" << expectedContents)), expressionToBson(expr));
+ ASSERT_BSONOBJ_EQ(constify(BSON("$testable" << expectedContents)), expressionToBson(expr));
}
void addOperandArrayToExpr(const intrusive_ptr<Testable>& expr, const BSONArray& operands) {
@@ -276,14 +276,14 @@ TEST_F(ExpressionNaryTest, ValidateObjectExpressionDependency) {
TEST_F(ExpressionNaryTest, SerializationToBsonObj) {
_notAssociativeNorCommutative->addOperand(ExpressionConstant::create(nullptr, Value(5)));
- ASSERT_EQUALS(BSON("foo" << BSON("$testable" << BSON_ARRAY(BSON("$const" << 5)))),
- BSON("foo" << _notAssociativeNorCommutative->serialize(false)));
+ ASSERT_BSONOBJ_EQ(BSON("foo" << BSON("$testable" << BSON_ARRAY(BSON("$const" << 5)))),
+ BSON("foo" << _notAssociativeNorCommutative->serialize(false)));
}
TEST_F(ExpressionNaryTest, SerializationToBsonArr) {
_notAssociativeNorCommutative->addOperand(ExpressionConstant::create(nullptr, Value(5)));
- ASSERT_EQUALS(constify(BSON_ARRAY(BSON("$testable" << BSON_ARRAY(5)))),
- BSON_ARRAY(_notAssociativeNorCommutative->serialize(false)));
+ ASSERT_BSONOBJ_EQ(constify(BSON_ARRAY(BSON("$testable" << BSON_ARRAY(5)))),
+ BSON_ARRAY(_notAssociativeNorCommutative->serialize(false)));
}
// Verify that the internal operands are optimized
@@ -303,7 +303,7 @@ TEST_F(ExpressionNaryTest, AllConstantOperandOptimization) {
assertContents(_notAssociativeNorCommutative, spec);
intrusive_ptr<Expression> optimized = _notAssociativeNorCommutative->optimize();
ASSERT(_notAssociativeNorCommutative != optimized);
- ASSERT_EQUALS(BSON("$const" << BSON_ARRAY(1 << 2)), expressionToBson(optimized));
+ ASSERT_BSONOBJ_EQ(BSON("$const" << BSON_ARRAY(1 << 2)), expressionToBson(optimized));
}
// Verify that the optimization of grouping constant and non-constant operands
@@ -917,7 +917,7 @@ public:
void run() {
intrusive_ptr<ExpressionNary> expression = new ExpressionAdd();
populateOperands(expression);
- ASSERT_EQUALS(expectedResult(), toBson(expression->evaluate(Document())));
+ ASSERT_BSONOBJ_EQ(expectedResult(), toBson(expression->evaluate(Document())));
}
protected:
@@ -932,7 +932,7 @@ public:
void run() {
intrusive_ptr<ExpressionNary> expression = new ExpressionAdd();
expression->addOperand(ExpressionConstant::create(nullptr, Value(2)));
- ASSERT_EQUALS(BSON("" << 2), toBson(expression->evaluate(Document())));
+ ASSERT_BSONOBJ_EQ(BSON("" << 2), toBson(expression->evaluate(Document())));
}
};
@@ -1198,12 +1198,12 @@ public:
VariablesParseState vps(&idGenerator);
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
expression->injectExpressionContext(expCtx);
- ASSERT_EQUALS(constify(spec()), expressionToBson(expression));
- ASSERT_EQUALS(BSON("" << expectedResult()),
- toBson(expression->evaluate(fromBson(BSON("a" << 1)))));
+ ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
+ toBson(expression->evaluate(fromBson(BSON("a" << 1)))));
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_EQUALS(BSON("" << expectedResult()),
- toBson(optimized->evaluate(fromBson(BSON("a" << 1)))));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
+ toBson(optimized->evaluate(fromBson(BSON("a" << 1)))));
}
protected:
@@ -1222,9 +1222,9 @@ public:
VariablesParseState vps(&idGenerator);
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
expression->injectExpressionContext(expCtx);
- ASSERT_EQUALS(constify(spec()), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_EQUALS(expectedOptimized(), expressionToBson(optimized));
+ ASSERT_BSONOBJ_EQ(expectedOptimized(), expressionToBson(optimized));
}
protected:
@@ -1579,7 +1579,7 @@ public:
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
expression->injectExpressionContext(expCtx);
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_EQUALS(constify(expectedOptimized()), expressionToBson(optimized));
+ ASSERT_BSONOBJ_EQ(constify(expectedOptimized()), expressionToBson(optimized));
}
protected:
@@ -1612,12 +1612,12 @@ public:
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
expression->injectExpressionContext(expCtx);
// Check expression spec round trip.
- ASSERT_EQUALS(constify(spec()), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
// Check evaluation result.
- ASSERT_EQUALS(expectedResult(), toBson(expression->evaluate(Document())));
+ ASSERT_BSONOBJ_EQ(expectedResult(), toBson(expression->evaluate(Document())));
// Check that the result is the same after optimizing.
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_EQUALS(expectedResult(), toBson(optimized->evaluate(Document())));
+ ASSERT_BSONOBJ_EQ(expectedResult(), toBson(optimized->evaluate(Document())));
}
protected:
@@ -2575,12 +2575,12 @@ public:
VariablesIdGenerator idGenerator;
VariablesParseState vps(&idGenerator);
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
- ASSERT_EQUALS(constify(spec()), expressionToBson(expression));
- ASSERT_EQUALS(BSON("" << expectedResult()),
- toBson(expression->evaluate(fromBson(BSON("a" << 1)))));
+ ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
+ toBson(expression->evaluate(fromBson(BSON("a" << 1)))));
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_EQUALS(BSON("" << expectedResult()),
- toBson(optimized->evaluate(fromBson(BSON("a" << 1)))));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
+ toBson(optimized->evaluate(fromBson(BSON("a" << 1)))));
}
protected:
@@ -2597,9 +2597,9 @@ public:
VariablesIdGenerator idGenerator;
VariablesParseState vps(&idGenerator);
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
- ASSERT_EQUALS(constify(spec()), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_EQUALS(expectedOptimized(), expressionToBson(optimized));
+ ASSERT_BSONOBJ_EQ(expectedOptimized(), expressionToBson(optimized));
}
protected:
@@ -3400,8 +3400,8 @@ private:
VariablesParseState vps(&idGenerator);
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
expression->injectExpressionContext(expCtx);
- ASSERT_EQUALS(constify(spec), expressionToBson(expression));
- ASSERT_EQUALS(BSON("" << expectedResult), toBson(expression->evaluate(Document())));
+ ASSERT_BSONOBJ_EQ(constify(spec), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult), toBson(expression->evaluate(Document())));
}
};
@@ -3528,8 +3528,8 @@ public:
VariablesParseState vps(&idGenerator);
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
expression->injectExpressionContext(expCtx);
- ASSERT_EQUALS(constify(spec()), expressionToBson(expression));
- ASSERT_EQUALS(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
+ ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
}
protected:
@@ -3785,8 +3785,8 @@ public:
VariablesParseState vps(&idGenerator);
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
expression->injectExpressionContext(expCtx);
- ASSERT_EQUALS(constify(spec()), expressionToBson(expression));
- ASSERT_EQUALS(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
+ ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
}
protected:
@@ -3844,8 +3844,8 @@ public:
VariablesParseState vps(&idGenerator);
intrusive_ptr<Expression> expression = Expression::parseOperand(specElement, vps);
expression->injectExpressionContext(expCtx);
- ASSERT_EQUALS(constify(spec()), expressionToBson(expression));
- ASSERT_EQUALS(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
+ ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
}
protected:
diff --git a/src/mongo/db/pipeline/lookup_set_cache_test.cpp b/src/mongo/db/pipeline/lookup_set_cache_test.cpp
index 13f445e67c3..cd27aab99a9 100644
--- a/src/mongo/db/pipeline/lookup_set_cache_test.cpp
+++ b/src/mongo/db/pipeline/lookup_set_cache_test.cpp
@@ -43,7 +43,9 @@ namespace mongo {
bool vectorContains(const boost::optional<std::vector<BSONObj>>& vector,
const BSONObj& expectedObj) {
ASSERT_TRUE(vector);
- return std::find(vector->begin(), vector->end(), expectedObj) != vector->end();
+ return std::find_if(vector->begin(), vector->end(), [&expectedObj](const BSONObj& obj) {
+ return SimpleBSONObjComparator::kInstance.evaluate(expectedObj == obj);
+ }) != vector->end();
}
BSONObj intToObj(int value) {
diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp
index e4e2e6bb67c..5dd74393a92 100644
--- a/src/mongo/db/pipeline/pipeline_d.cpp
+++ b/src/mongo/db/pipeline/pipeline_d.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/pipeline/pipeline_d.h"
+#include "mongo/bson/simple_bsonobj_comparator.h"
#include "mongo/client/dbclientinterface.h"
#include "mongo/db/catalog/collection.h"
#include "mongo/db/catalog/database.h"
@@ -138,7 +139,8 @@ public:
const std::list<BSONObj>& originalIndexes) final {
Lock::GlobalWrite globalLock(_ctx->opCtx->lockState());
- if (originalCollectionOptions != getCollectionOptions(targetNs)) {
+ if (SimpleBSONObjComparator::kInstance.evaluate(originalCollectionOptions !=
+ getCollectionOptions(targetNs))) {
return {ErrorCodes::CommandFailed,
str::stream() << "collection options of target collection " << targetNs.ns()
<< " changed during processing. Original options: "
@@ -146,7 +148,13 @@ public:
<< ", new options: "
<< getCollectionOptions(targetNs)};
}
- if (originalIndexes != _client.getIndexSpecs(targetNs.ns())) {
+
+ auto currentIndexes = _client.getIndexSpecs(targetNs.ns());
+ if (originalIndexes.size() != currentIndexes.size() ||
+ !std::equal(originalIndexes.begin(),
+ originalIndexes.end(),
+ currentIndexes.begin(),
+ SimpleBSONObjComparator::kInstance.makeEqualTo())) {
return {ErrorCodes::CommandFailed,
str::stream() << "indexes of target collection " << targetNs.ns()
<< " changed during processing."};
diff --git a/src/mongo/db/pipeline/pipeline_test.cpp b/src/mongo/db/pipeline/pipeline_test.cpp
index 864680bcbb9..16625527383 100644
--- a/src/mongo/db/pipeline/pipeline_test.cpp
+++ b/src/mongo/db/pipeline/pipeline_test.cpp
@@ -1071,7 +1071,7 @@ TEST(PipelineInitialSource, GeoNearInitialQuery) {
intrusive_ptr<ExpressionContext> ctx = new ExpressionContext(
&_opCtx, AggregationRequest(NamespaceString("a.collection"), rawPipeline));
auto pipe = uassertStatusOK(Pipeline::parse(rawPipeline, ctx));
- ASSERT_EQ(pipe->getInitialQuery(), BSON("a" << 1));
+ ASSERT_BSONOBJ_EQ(pipe->getInitialQuery(), BSON("a" << 1));
}
TEST(PipelineInitialSource, MatchInitialQuery) {
@@ -1081,7 +1081,7 @@ TEST(PipelineInitialSource, MatchInitialQuery) {
&_opCtx, AggregationRequest(NamespaceString("a.collection"), rawPipeline));
auto pipe = uassertStatusOK(Pipeline::parse(rawPipeline, ctx));
- ASSERT_EQ(pipe->getInitialQuery(), BSON("a" << 4));
+ ASSERT_BSONOBJ_EQ(pipe->getInitialQuery(), BSON("a" << 4));
}
TEST(PipelineInitialSource, ParseCollation) {