summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/aggregation/sources/lookup/lookup.js86
-rw-r--r--jstests/aggregation/variables/layered_variables.js3
-rw-r--r--src/mongo/db/matcher/SConscript1
-rw-r--r--src/mongo/db/matcher/expression_leaf.cpp101
-rw-r--r--src/mongo/db/matcher/expression_leaf.h34
-rw-r--r--src/mongo/db/matcher/expression_leaf_test.cpp108
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp222
-rw-r--r--src/mongo/db/matcher/expression_parser.h70
-rw-r--r--src/mongo/db/matcher/expression_parser_geo_test.cpp14
-rw-r--r--src/mongo/db/matcher/expression_parser_leaf_test.cpp541
-rw-r--r--src/mongo/db/matcher/expression_parser_tree.cpp17
-rw-r--r--src/mongo/db/matcher/expression_text_base.h1
-rw-r--r--src/mongo/db/pipeline/document_source_match.cpp8
-rw-r--r--src/mongo/db/pipeline/expression.cpp8
-rw-r--r--src/mongo/db/pipeline/expression_test.cpp50
-rw-r--r--src/mongo/db/pipeline/pipeline_d.cpp2
-rw-r--r--src/mongo/db/pipeline/pipeline_test.cpp3
-rw-r--r--src/mongo/db/pipeline/variables.cpp14
-rw-r--r--src/mongo/db/pipeline/variables.h18
-rw-r--r--src/mongo/db/query/canonical_query.cpp13
-rw-r--r--src/mongo/db/query/canonical_query.h14
-rw-r--r--src/mongo/db/update/addtoset_node_test.cpp37
-rw-r--r--src/mongo/db/update/arithmetic_node_test.cpp114
-rw-r--r--src/mongo/db/update/bit_node_test.cpp19
-rw-r--r--src/mongo/db/update/compare_node_test.cpp39
-rw-r--r--src/mongo/db/update/current_date_node_test.cpp15
-rw-r--r--src/mongo/db/update/log_builder.cpp3
-rw-r--r--src/mongo/db/update/object_replace_node_test.cpp37
-rw-r--r--src/mongo/db/update/path_support_test.cpp18
-rw-r--r--src/mongo/db/update/pull_node_test.cpp67
-rw-r--r--src/mongo/db/update/pullall_node_test.cpp27
-rw-r--r--src/mongo/db/update/push_node_test.cpp73
-rw-r--r--src/mongo/db/update/push_sorter_test.cpp3
-rw-r--r--src/mongo/db/update/rename_node_test.cpp55
-rw-r--r--src/mongo/db/update/set_node_test.cpp151
-rw-r--r--src/mongo/db/update/unset_node_test.cpp45
-rw-r--r--src/mongo/db/update/update_array_node_test.cpp47
-rw-r--r--src/mongo/db/update/update_driver_test.cpp7
-rw-r--r--src/mongo/db/update/update_object_node_test.cpp53
-rw-r--r--src/mongo/dbtests/extensions_callback_real_test.cpp9
40 files changed, 1480 insertions, 667 deletions
diff --git a/jstests/aggregation/sources/lookup/lookup.js b/jstests/aggregation/sources/lookup/lookup.js
index b93691aa27f..def8cadfd42 100644
--- a/jstests/aggregation/sources/lookup/lookup.js
+++ b/jstests/aggregation/sources/lookup/lookup.js
@@ -463,7 +463,7 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode.
assert.writeOK(from.insert({_id: 2}));
assert.writeOK(from.insert({_id: 3}));
- // Basic non-equi theta join.
+ // Basic non-equi theta join via $project.
pipeline = [
{
$lookup: {
@@ -495,6 +495,90 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode.
];
testPipeline(pipeline, expectedResults, coll);
+ // Basic non-equi theta join via $match.
+ pipeline = [
+ {
+ $lookup: {
+ let : {var1: "$_id"},
+ pipeline: [
+ {$match: {_id: {$lt: {$expr: "$$var1"}}}},
+ ],
+ from: "from",
+ as: "c",
+ }
+ },
+ ];
+
+ expectedResults = [
+ {"_id": 1, x: 1, "c": []},
+ {"_id": 2, x: 2, "c": [{"_id": 1}]},
+ {
+ "_id": 3,
+ x: 3,
+ "c": [
+ {"_id": 1},
+ {
+ "_id": 2,
+ }
+ ]
+ }
+ ];
+ testPipeline(pipeline, expectedResults, coll);
+
+ // Multi-level join using $match.
+ pipeline = [
+ {
+ $lookup: {
+ let : {var1: "$_id"},
+ pipeline: [
+ {$match: {_id: {$eq: {$expr: "$$var1"}}}},
+ {
+ $lookup: {
+ let : {var2: "$_id"},
+ pipeline: [
+ {$match: {_id: {$gt: {$expr: "$$var2"}}}},
+ ],
+ from: "from",
+ as: "d"
+ }
+ },
+ ],
+ from: "from",
+ as: "c",
+ }
+ },
+ ];
+
+ expectedResults = [
+ {"_id": 1, "x": 1, "c": [{"_id": 1, "d": [{"_id": 2}, {"_id": 3}]}]},
+ {"_id": 2, "x": 2, "c": [{"_id": 2, "d": [{"_id": 3}]}]},
+ {"_id": 3, "x": 3, "c": [{"_id": 3, "d": []}]}
+ ];
+ testPipeline(pipeline, expectedResults, coll);
+
+ // Equijoin with $match that can't be delegated to the query subsystem.
+ pipeline = [
+ {
+ $lookup: {
+ let : {var1: "$x"},
+ pipeline: [
+ {$addFields: {newField: 2}},
+ {$match: {newField: {$expr: "$$var1"}}},
+ {$project: {newField: 0}}
+ ],
+ from: "from",
+ as: "c",
+ }
+ },
+ ];
+
+ expectedResults = [
+ {"_id": 1, "x": 1, "c": []},
+ {"_id": 2, "x": 2, "c": [{"_id": 1}, {"_id": 2}, {"_id": 3}]},
+ {"_id": 3, "x": 3, "c": []}
+ ];
+ testPipeline(pipeline, expectedResults, coll);
+
// Multiple variables.
pipeline = [
{
diff --git a/jstests/aggregation/variables/layered_variables.js b/jstests/aggregation/variables/layered_variables.js
index 5e5f2f94c05..e0e10494b29 100644
--- a/jstests/aggregation/variables/layered_variables.js
+++ b/jstests/aggregation/variables/layered_variables.js
@@ -53,5 +53,6 @@
assert.eq(
{_id: 1, has_permissions: 1, my_array: [2, 3], a: 1, b: 6, c: [2, 3], d: 3000, e: [3, 4]},
- res.cursor.firstBatch[0]);
+ res.cursor.firstBatch[0],
+ tojson(res));
})();
diff --git a/src/mongo/db/matcher/SConscript b/src/mongo/db/matcher/SConscript
index fe025b6b8ad..4f7af21e9a1 100644
--- a/src/mongo/db/matcher/SConscript
+++ b/src/mongo/db/matcher/SConscript
@@ -66,6 +66,7 @@ env.Library(
'$BUILD_DIR/mongo/db/geo/geometry',
'$BUILD_DIR/mongo/db/geo/geoparser',
'$BUILD_DIR/mongo/db/query/collation/collator_interface',
+ '$BUILD_DIR/mongo/db/pipeline/expression',
'$BUILD_DIR/third_party/shim_pcrecpp',
'path',
],
diff --git a/src/mongo/db/matcher/expression_leaf.cpp b/src/mongo/db/matcher/expression_leaf.cpp
index 4a0a4598927..5b995614df0 100644
--- a/src/mongo/db/matcher/expression_leaf.cpp
+++ b/src/mongo/db/matcher/expression_leaf.cpp
@@ -59,18 +59,15 @@ bool ComparisonMatchExpression::equivalent(const MatchExpression* other) const {
const StringData::ComparatorInterface* stringComparator = nullptr;
BSONElementComparator eltCmp(BSONElementComparator::FieldNamesMode::kIgnore, stringComparator);
- return path() == realOther->path() && eltCmp.evaluate(_rhs == realOther->_rhs);
+ return path() == realOther->path() && eltCmp.evaluate(_rhsElem == realOther->_rhsElem);
}
-
-Status ComparisonMatchExpression::init(StringData path, const BSONElement& rhs) {
- _rhs = rhs;
-
- if (rhs.eoo()) {
+Status ComparisonMatchExpression::_validate() {
+ if (!_rhsElem) {
return Status(ErrorCodes::BadValue, "need a real operand");
}
- if (rhs.type() == Undefined) {
+ if (_rhsElem.type() == BSONType::Undefined) {
return Status(ErrorCodes::BadValue, "cannot compare to undefined");
}
@@ -85,31 +82,59 @@ Status ComparisonMatchExpression::init(StringData path, const BSONElement& rhs)
return Status(ErrorCodes::BadValue, "bad match type for ComparisonMatchExpression");
}
+ return Status::OK();
+}
+
+Status ComparisonMatchExpression::init(StringData path,
+ const boost::intrusive_ptr<Expression>& rhsExpr) {
+ auto exprConstant = dynamic_cast<ExpressionConstant*>(rhsExpr.get());
+ if (exprConstant) {
+ BSONObjBuilder bob;
+ bob << path << exprConstant->getValue();
+ _resolvedRhsExpr = bob.obj();
+ _rhsElem = _resolvedRhsExpr.firstElement();
+ } else {
+ return Status(ErrorCodes::BadValue, "$expr does not yet handle non-constant expressions");
+ }
+
+ auto status = _validate();
+ if (!status.isOK()) {
+ return status;
+ }
+
return setPath(path);
}
+Status ComparisonMatchExpression::init(StringData path, const BSONElement& rhs) {
+ _rhsElem = rhs;
+
+ auto status = _validate();
+ if (!status.isOK()) {
+ return status;
+ }
+
+ return setPath(path);
+}
bool ComparisonMatchExpression::matchesSingleElement(const BSONElement& e,
MatchDetails* details) const {
-
- if (e.canonicalType() != _rhs.canonicalType()) {
+ if (e.canonicalType() != _rhsElem.canonicalType()) {
// some special cases
// jstNULL and undefined are treated the same
- if (e.canonicalType() + _rhs.canonicalType() == 5) {
+ if (e.canonicalType() + _rhsElem.canonicalType() == 5) {
return matchType() == EQ || matchType() == LTE || matchType() == GTE;
}
- if (_rhs.type() == MaxKey || _rhs.type() == MinKey) {
+ if (_rhsElem.type() == MaxKey || _rhsElem.type() == MinKey) {
return matchType() != EQ;
}
-
return false;
}
// Special case handling for NaN. NaN is equal to NaN but
// otherwise always compares to false.
- if (std::isnan(e.numberDouble()) || std::isnan(_rhs.numberDouble())) {
- bool bothNaN = std::isnan(e.numberDouble()) && std::isnan(_rhs.numberDouble());
+ if (std::isnan(e.numberDouble()) || std::isnan(_rhsElem.numberDouble())) {
+ bool bothNaN = std::isnan(e.numberDouble()) && std::isnan(_rhsElem.numberDouble());
switch (matchType()) {
case LT:
return false;
@@ -128,7 +153,7 @@ bool ComparisonMatchExpression::matchesSingleElement(const BSONElement& e,
}
}
- int x = compareElementValues(e, _rhs, _collator);
+ int x = compareElementValues(e, _rhsElem, _collator);
switch (matchType()) {
case LT:
@@ -170,7 +195,7 @@ void ComparisonMatchExpression::debugString(StringBuilder& debug, int level) con
default:
invariant(false);
}
- debug << " " << _rhs.toString(false);
+ debug << " " << _rhsElem.toString(false);
MatchExpression::TagData* td = getTag();
if (NULL != td) {
@@ -203,7 +228,7 @@ void ComparisonMatchExpression::serialize(BSONObjBuilder* out) const {
invariant(false);
}
- out->append(path(), BSON(opString << _rhs));
+ out->append(path(), BSON(opString << _rhsElem));
}
// ---------------
@@ -398,27 +423,27 @@ bool ExistsMatchExpression::equivalent(const MatchExpression* other) const {
const std::string TypeMatchExpression::kMatchesAllNumbersAlias = "number";
const stdx::unordered_map<std::string, BSONType> TypeMatchExpression::typeAliasMap = {
- {typeName(NumberDouble), NumberDouble},
- {typeName(String), String},
- {typeName(Object), Object},
- {typeName(Array), Array},
- {typeName(BinData), BinData},
- {typeName(Undefined), Undefined},
- {typeName(jstOID), jstOID},
- {typeName(Bool), Bool},
- {typeName(Date), Date},
- {typeName(jstNULL), jstNULL},
- {typeName(RegEx), RegEx},
- {typeName(DBRef), DBRef},
- {typeName(Code), Code},
- {typeName(Symbol), Symbol},
- {typeName(CodeWScope), CodeWScope},
- {typeName(NumberInt), NumberInt},
- {typeName(bsonTimestamp), bsonTimestamp},
- {typeName(NumberLong), NumberLong},
- {typeName(NumberDecimal), NumberDecimal},
- {typeName(MaxKey), MaxKey},
- {typeName(MinKey), MinKey}};
+ {typeName(BSONType::NumberDouble), BSONType::NumberDouble},
+ {typeName(BSONType::String), BSONType::String},
+ {typeName(BSONType::Object), BSONType::Object},
+ {typeName(BSONType::Array), BSONType::Array},
+ {typeName(BSONType::BinData), BSONType::BinData},
+ {typeName(BSONType::Undefined), BSONType::Undefined},
+ {typeName(BSONType::jstOID), BSONType::jstOID},
+ {typeName(BSONType::Bool), BSONType::Bool},
+ {typeName(BSONType::Date), BSONType::Date},
+ {typeName(BSONType::jstNULL), BSONType::jstNULL},
+ {typeName(BSONType::RegEx), BSONType::RegEx},
+ {typeName(BSONType::DBRef), BSONType::DBRef},
+ {typeName(BSONType::Code), BSONType::Code},
+ {typeName(BSONType::Symbol), BSONType::Symbol},
+ {typeName(BSONType::CodeWScope), BSONType::CodeWScope},
+ {typeName(BSONType::NumberInt), BSONType::NumberInt},
+ {typeName(BSONType::bsonTimestamp), BSONType::bsonTimestamp},
+ {typeName(BSONType::NumberLong), BSONType::NumberLong},
+ {typeName(BSONType::NumberDecimal), BSONType::NumberDecimal},
+ {typeName(BSONType::MaxKey), BSONType::MaxKey},
+ {typeName(BSONType::MinKey), BSONType::MinKey}};
Status TypeMatchExpression::init(StringData path, Type type) {
_type = std::move(type);
diff --git a/src/mongo/db/matcher/expression_leaf.h b/src/mongo/db/matcher/expression_leaf.h
index 984fc4653ca..49754b5c2bd 100644
--- a/src/mongo/db/matcher/expression_leaf.h
+++ b/src/mongo/db/matcher/expression_leaf.h
@@ -33,6 +33,7 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_path.h"
+#include "mongo/db/pipeline/expression.h"
#include "mongo/db/query/collation/collator_interface.h"
#include "mongo/stdx/memory.h"
#include "mongo/stdx/unordered_map.h"
@@ -47,7 +48,7 @@ class CollatorInterface;
class LeafMatchExpression : public PathMatchExpression {
public:
- LeafMatchExpression(MatchType matchType) : PathMatchExpression(matchType) {}
+ explicit LeafMatchExpression(MatchType matchType) : PathMatchExpression(matchType) {}
virtual ~LeafMatchExpression() {}
@@ -65,9 +66,10 @@ public:
*/
class ComparisonMatchExpression : public LeafMatchExpression {
public:
- ComparisonMatchExpression(MatchType type) : LeafMatchExpression(type) {}
+ explicit ComparisonMatchExpression(MatchType type) : LeafMatchExpression(type) {}
Status init(StringData path, const BSONElement& rhs);
+ Status init(StringData path, const boost::intrusive_ptr<Expression>& rhsExpr);
virtual ~ComparisonMatchExpression() {}
@@ -87,7 +89,7 @@ public:
virtual bool equivalent(const MatchExpression* other) const;
const BSONElement& getData() const {
- return _rhs;
+ return _rhsElem;
}
const CollatorInterface* getCollator() const {
@@ -111,7 +113,11 @@ public:
}
protected:
- BSONElement _rhs;
+ Status _validate();
+
+ BSONElement _rhsElem;
+
+ BSONObj _resolvedRhsExpr;
// Collator used to compare elements. By default, simple binary comparison will be used.
const CollatorInterface* _collator = nullptr;
@@ -122,7 +128,7 @@ public:
EqualityMatchExpression() : ComparisonMatchExpression(EQ) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<EqualityMatchExpression>();
- e->init(path(), _rhs).transitional_ignore();
+ invariantOK(e->init(path(), _rhsElem));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -136,7 +142,7 @@ public:
LTEMatchExpression() : ComparisonMatchExpression(LTE) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<LTEMatchExpression>();
- e->init(path(), _rhs).transitional_ignore();
+ invariantOK(e->init(path(), _rhsElem));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -150,7 +156,7 @@ public:
LTMatchExpression() : ComparisonMatchExpression(LT) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<LTMatchExpression>();
- e->init(path(), _rhs).transitional_ignore();
+ invariantOK(e->init(path(), _rhsElem));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -164,7 +170,7 @@ public:
GTMatchExpression() : ComparisonMatchExpression(GT) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<GTMatchExpression>();
- e->init(path(), _rhs).transitional_ignore();
+ invariantOK(e->init(path(), _rhsElem));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -178,7 +184,7 @@ public:
GTEMatchExpression() : ComparisonMatchExpression(GTE) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<GTEMatchExpression>();
- e->init(path(), _rhs).transitional_ignore();
+ invariantOK(e->init(path(), _rhsElem));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -204,7 +210,7 @@ public:
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<RegexMatchExpression> e = stdx::make_unique<RegexMatchExpression>();
- e->init(path(), _regex, _flags).transitional_ignore();
+ invariantOK(e->init(path(), _regex, _flags));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -244,7 +250,7 @@ public:
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ModMatchExpression> m = stdx::make_unique<ModMatchExpression>();
- m->init(path(), _divisor, _remainder).transitional_ignore();
+ invariantOK(m->init(path(), _divisor, _remainder));
if (getTag()) {
m->setTag(getTag()->clone());
}
@@ -279,7 +285,7 @@ public:
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ExistsMatchExpression> e = stdx::make_unique<ExistsMatchExpression>();
- e->init(path()).transitional_ignore();
+ invariantOK(e->init(path()));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -439,7 +445,7 @@ private:
*/
class BitTestMatchExpression : public LeafMatchExpression {
public:
- BitTestMatchExpression(MatchType type) : LeafMatchExpression(type) {}
+ explicit BitTestMatchExpression(MatchType type) : LeafMatchExpression(type) {}
virtual ~BitTestMatchExpression() {}
/**
@@ -472,7 +478,7 @@ protected:
* ownership.
*/
void initClone(BitTestMatchExpression* clone) const {
- clone->init(path(), _bitPositions).transitional_ignore();
+ invariantOK(clone->init(path(), _bitPositions));
if (getTag()) {
clone->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/expression_leaf_test.cpp b/src/mongo/db/matcher/expression_leaf_test.cpp
index 3d1c87fbd26..af279e5d933 100644
--- a/src/mongo/db/matcher/expression_leaf_test.cpp
+++ b/src/mongo/db/matcher/expression_leaf_test.cpp
@@ -35,6 +35,7 @@
#include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/expression_parser.h"
+#include "mongo/db/pipeline/aggregation_context_fixture.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
namespace mongo {
@@ -96,10 +97,31 @@ TEST(EqOp, MatchesElement) {
ASSERT(eq.equivalent(&eq));
}
+TEST(EqOp, ConstantAggExprMatchesElement) {
+ BSONObj operand = BSON("a" << BSON("$expr"
+ << "$$userVar"));
+ BSONObj match = BSON("a" << 5);
+ BSONObj notMatch = BSON("a" << 6);
+
+ const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(5));
+ auto expr = Expression::parseOperand(
+ expCtx, operand.firstElement()["$expr"], expCtx->variablesParseState);
+ expr = expr->optimize();
+
+ EqualityMatchExpression eq;
+ ASSERT_OK(eq.init("a", expr));
+ ASSERT(eq.matchesSingleElement(match.firstElement()));
+ ASSERT_FALSE(eq.matchesSingleElement(notMatch.firstElement()));
+
+ ASSERT(eq.equivalent(&eq));
+}
+
TEST(EqOp, InvalidEooOperand) {
BSONObj operand;
EqualityMatchExpression eq;
- ASSERT(!eq.init("", operand.firstElement()).isOK());
+ ASSERT_FALSE(eq.init("", operand.firstElement()).isOK());
}
TEST(EqOp, MatchesScalar) {
@@ -418,6 +440,27 @@ TEST(LtOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
+TEST(LtOp, ConstantAggExprMatchesElement) {
+ BSONObj operand = BSON("a" << BSON("$lt" << BSON("$expr"
+ << "$$userVar")));
+ BSONObj match = BSON("a" << 5);
+ BSONObj notMatch = BSON("a" << 10);
+
+ const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(6));
+ auto expr = Expression::parseOperand(
+ expCtx, operand.firstElement()["$lt"]["$expr"], expCtx->variablesParseState);
+ expr = expr->optimize();
+
+ LTMatchExpression lt;
+ ASSERT_OK(lt.init("a", expr));
+ ASSERT(lt.matchesSingleElement(match.firstElement()));
+ ASSERT_FALSE(lt.matchesSingleElement(notMatch.firstElement()));
+
+ ASSERT(lt.equivalent(&lt));
+}
+
/**
TEST( LtOp, MatchesIndexKeyScalar ) {
BSONObj operand = BSON( "$lt" << 6 );
@@ -483,6 +526,27 @@ TEST(LteOp, MatchesElement) {
ASSERT(!lte.matchesSingleElement(notMatchWrongType.firstElement()));
}
+TEST(LteOp, ConstantAggExprMatchesElement) {
+ BSONObj operand = BSON("a" << BSON("$lte" << BSON("$expr"
+ << "$$userVar")));
+ BSONObj match = BSON("a" << 5);
+ BSONObj notMatch = BSON("a" << 10);
+
+ const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(6));
+ auto expr = Expression::parseOperand(
+ expCtx, operand.firstElement()["$lte"]["$expr"], expCtx->variablesParseState);
+ expr = expr->optimize();
+
+ LTEMatchExpression lte;
+ ASSERT_OK(lte.init("a", expr));
+ ASSERT(lte.matchesSingleElement(match.firstElement()));
+ ASSERT_FALSE(lte.matchesSingleElement(notMatch.firstElement()));
+
+ ASSERT(lte.equivalent(&lte));
+}
+
TEST(LteOp, InvalidEooOperand) {
BSONObj operand;
LTEMatchExpression lte;
@@ -737,6 +801,27 @@ TEST(GtOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
+TEST(GtOp, ConstantAggExprMatchesElement) {
+ BSONObj operand = BSON("a" << BSON("$gt" << BSON("$expr"
+ << "$$userVar")));
+ BSONObj match = BSON("a" << 10);
+ BSONObj notMatch = BSON("a" << 0);
+
+ const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(5));
+ auto expr = Expression::parseOperand(
+ expCtx, operand.firstElement()["$gt"]["$expr"], expCtx->variablesParseState);
+ expr = expr->optimize();
+
+ GTMatchExpression gt;
+ ASSERT_OK(gt.init("a", expr));
+ ASSERT(gt.matchesSingleElement(match.firstElement()));
+ ASSERT_FALSE(gt.matchesSingleElement(notMatch.firstElement()));
+
+ ASSERT(gt.equivalent(&gt));
+}
+
/**
TEST( GtOp, MatchesIndexKeyScalar ) {
BSONObj operand = BSON( "$gt" << 6 );
@@ -897,6 +982,27 @@ TEST(GteOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
+TEST(GteOp, ConstantAggExprMatchesElement) {
+ BSONObj operand = BSON("a" << BSON("$gte" << BSON("$expr"
+ << "$$userVar")));
+ BSONObj match = BSON("a" << 10);
+ BSONObj notMatch = BSON("a" << 0);
+
+ const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(5));
+ auto expr = Expression::parseOperand(
+ expCtx, operand.firstElement()["$gte"]["$expr"], expCtx->variablesParseState);
+ expr = expr->optimize();
+
+ GTEMatchExpression gte;
+ ASSERT_OK(gte.init("a", expr));
+ ASSERT(gte.matchesSingleElement(match.firstElement()));
+ ASSERT_FALSE(gte.matchesSingleElement(notMatch.firstElement()));
+
+ ASSERT(gte.equivalent(&gte));
+}
+
TEST(RegexMatchExpression, MatchesElementExact) {
BSONObj match = BSON("a"
<< "b");
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp
index 85c21e13bfc..1eff1a1138a 100644
--- a/src/mongo/db/matcher/expression_parser.cpp
+++ b/src/mongo/db/matcher/expression_parser.cpp
@@ -81,6 +81,8 @@ bool hasNode(const MatchExpression* root, MatchExpression::MatchType type) {
namespace mongo {
+constexpr StringData MatchExpressionParser::kAggExpression;
+
using std::string;
using stdx::make_unique;
@@ -91,7 +93,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseComparison(
const char* name,
ComparisonMatchExpression* cmp,
const BSONElement& e,
- const CollatorInterface* collator) {
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx) {
std::unique_ptr<ComparisonMatchExpression> temp(cmp);
// Non-equality comparison match expressions cannot have
@@ -102,25 +105,37 @@ StatusWithMatchExpression MatchExpressionParser::_parseComparison(
return {Status(ErrorCodes::BadValue, ss)};
}
- Status s = temp->init(name, e);
- if (!s.isOK())
- return s;
+ if (_isAggExpression(e, expCtx)) {
+ auto expr = _parseAggExpression(e, expCtx);
+ auto s = temp->init(name, expr);
+ if (!s.isOK()) {
+ return s;
+ }
+ } else {
+ auto s = temp->init(name, e);
+ if (!s.isOK()) {
+ return s;
+ }
+ }
+
temp->setCollator(collator);
return {std::move(temp)};
}
-StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& context,
- const AndMatchExpression* andSoFar,
- const char* name,
- const BSONElement& e,
- const CollatorInterface* collator,
- bool topLevel) {
+StatusWithMatchExpression MatchExpressionParser::_parseSubField(
+ const BSONObj& context,
+ const AndMatchExpression* andSoFar,
+ const char* name,
+ const BSONElement& e,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ bool topLevel) {
if (mongoutils::str::equals("$eq", e.fieldName()))
- return _parseComparison(name, new EqualityMatchExpression(), e, collator);
+ return _parseComparison(name, new EqualityMatchExpression(), e, collator, expCtx);
if (mongoutils::str::equals("$not", e.fieldName())) {
- return _parseNot(name, e, collator, topLevel);
+ return _parseNot(name, e, collator, expCtx, topLevel);
}
auto parseExpMatchType = MatchExpressionParser::parsePathAcceptingKeyword(e);
@@ -136,13 +151,13 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
switch (*parseExpMatchType) {
case PathAcceptingKeyword::LESS_THAN:
- return _parseComparison(name, new LTMatchExpression(), e, collator);
+ return _parseComparison(name, new LTMatchExpression(), e, collator, expCtx);
case PathAcceptingKeyword::LESS_THAN_OR_EQUAL:
- return _parseComparison(name, new LTEMatchExpression(), e, collator);
+ return _parseComparison(name, new LTEMatchExpression(), e, collator, expCtx);
case PathAcceptingKeyword::GREATER_THAN:
- return _parseComparison(name, new GTMatchExpression(), e, collator);
+ return _parseComparison(name, new GTMatchExpression(), e, collator, expCtx);
case PathAcceptingKeyword::GREATER_THAN_OR_EQUAL:
- return _parseComparison(name, new GTEMatchExpression(), e, collator);
+ return _parseComparison(name, new GTEMatchExpression(), e, collator, expCtx);
case PathAcceptingKeyword::NOT_EQUAL: {
if (RegEx == e.type()) {
// Just because $ne can be rewritten as the negation of an
@@ -150,7 +165,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
return {Status(ErrorCodes::BadValue, "Can't have regex as arg to $ne.")};
}
StatusWithMatchExpression s =
- _parseComparison(name, new EqualityMatchExpression(), e, collator);
+ _parseComparison(name, new EqualityMatchExpression(), e, collator, expCtx);
if (!s.isOK())
return s;
std::unique_ptr<NotMatchExpression> n = stdx::make_unique<NotMatchExpression>();
@@ -160,7 +175,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
return {std::move(n)};
}
case PathAcceptingKeyword::EQUALITY:
- return _parseComparison(name, new EqualityMatchExpression(), e, collator);
+ return _parseComparison(name, new EqualityMatchExpression(), e, collator, expCtx);
case PathAcceptingKeyword::IN_EXPR: {
if (e.type() != Array)
@@ -169,7 +184,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
Status s = temp->init(name);
if (!s.isOK())
return s;
- s = _parseInExpression(temp.get(), e.Obj(), collator);
+ s = _parseInExpression(temp.get(), e.Obj(), collator, expCtx);
if (!s.isOK())
return s;
return {std::move(temp)};
@@ -182,7 +197,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
Status s = temp->init(name);
if (!s.isOK())
return s;
- s = _parseInExpression(temp.get(), e.Obj(), collator);
+ s = _parseInExpression(temp.get(), e.Obj(), collator, expCtx);
if (!s.isOK())
return s;
@@ -243,10 +258,10 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
}
case PathAcceptingKeyword::TYPE:
- return _parseType(name, e);
+ return _parseType(name, e, expCtx);
case PathAcceptingKeyword::MOD:
- return _parseMOD(name, e);
+ return _parseMOD(name, e, expCtx);
case PathAcceptingKeyword::OPTIONS: {
// TODO: try to optimize this
@@ -264,14 +279,14 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
}
case PathAcceptingKeyword::REGEX: {
- return _parseRegexDocument(name, context);
+ return _parseRegexDocument(name, context, expCtx);
}
case PathAcceptingKeyword::ELEM_MATCH:
- return _parseElemMatch(name, e, collator, topLevel);
+ return _parseElemMatch(name, e, collator, expCtx, topLevel);
case PathAcceptingKeyword::ALL:
- return _parseAll(name, e, collator, topLevel);
+ return _parseAll(name, e, collator, expCtx, topLevel);
case PathAcceptingKeyword::WITHIN:
case PathAcceptingKeyword::GEO_INTERSECTS:
@@ -284,19 +299,19 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
// Handles bitwise query operators.
case PathAcceptingKeyword::BITS_ALL_SET: {
- return _parseBitTest<BitsAllSetMatchExpression>(name, e);
+ return _parseBitTest<BitsAllSetMatchExpression>(name, e, expCtx);
}
case PathAcceptingKeyword::BITS_ALL_CLEAR: {
- return _parseBitTest<BitsAllClearMatchExpression>(name, e);
+ return _parseBitTest<BitsAllClearMatchExpression>(name, e, expCtx);
}
case PathAcceptingKeyword::BITS_ANY_SET: {
- return _parseBitTest<BitsAnySetMatchExpression>(name, e);
+ return _parseBitTest<BitsAnySetMatchExpression>(name, e, expCtx);
}
case PathAcceptingKeyword::BITS_ANY_CLEAR: {
- return _parseBitTest<BitsAnyClearMatchExpression>(name, e);
+ return _parseBitTest<BitsAnyClearMatchExpression>(name, e, expCtx);
}
case PathAcceptingKeyword::INTERNAL_SCHEMA_FMOD:
@@ -318,7 +333,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
str::stream() << "$_internalSchemaObjectMatch must be an object");
}
- auto parsedSubObjExpr = _parse(e.Obj(), collator, topLevel);
+ auto parsedSubObjExpr = _parse(e.Obj(), collator, expCtx, topLevel);
if (!parsedSubObjExpr.isOK()) {
return parsedSubObjExpr;
}
@@ -363,9 +378,11 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
mongoutils::str::stream() << "not handled: " << e.fieldName())};
}
-StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj,
- const CollatorInterface* collator,
- bool topLevel) {
+StatusWithMatchExpression MatchExpressionParser::_parse(
+ const BSONObj& obj,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ bool topLevel) {
std::unique_ptr<AndMatchExpression> root = stdx::make_unique<AndMatchExpression>();
const bool childIsTopLevel = false;
@@ -380,7 +397,7 @@ StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj,
if (e.type() != Array)
return {Status(ErrorCodes::BadValue, "$or must be an array")};
std::unique_ptr<OrMatchExpression> temp = stdx::make_unique<OrMatchExpression>();
- Status s = _parseTreeList(e.Obj(), temp.get(), collator, childIsTopLevel);
+ Status s = _parseTreeList(e.Obj(), temp.get(), collator, expCtx, childIsTopLevel);
if (!s.isOK())
return s;
root->add(temp.release());
@@ -388,7 +405,7 @@ StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj,
if (e.type() != Array)
return {Status(ErrorCodes::BadValue, "$and must be an array")};
std::unique_ptr<AndMatchExpression> temp = stdx::make_unique<AndMatchExpression>();
- Status s = _parseTreeList(e.Obj(), temp.get(), collator, childIsTopLevel);
+ Status s = _parseTreeList(e.Obj(), temp.get(), collator, expCtx, childIsTopLevel);
if (!s.isOK())
return s;
root->add(temp.release());
@@ -396,7 +413,7 @@ StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj,
if (e.type() != Array)
return {Status(ErrorCodes::BadValue, "$nor must be an array")};
std::unique_ptr<NorMatchExpression> temp = stdx::make_unique<NorMatchExpression>();
- Status s = _parseTreeList(e.Obj(), temp.get(), collator, childIsTopLevel);
+ Status s = _parseTreeList(e.Obj(), temp.get(), collator, expCtx, childIsTopLevel);
if (!s.isOK())
return s;
root->add(temp.release());
@@ -434,7 +451,7 @@ StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj,
} else if (mongoutils::str::equals("_internalSchemaCond", rest)) {
auto condExpr =
_parseInternalSchemaFixedArityArgument<InternalSchemaCondMatchExpression>(
- InternalSchemaCondMatchExpression::kName, e, collator);
+ InternalSchemaCondMatchExpression::kName, e, collator, expCtx);
if (!condExpr.isOK()) {
return condExpr.getStatus();
}
@@ -445,7 +462,8 @@ StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj,
return {
Status(ErrorCodes::TypeMismatch, "$_internalSchemaXor must be an array")};
auto xorExpr = stdx::make_unique<InternalSchemaXorMatchExpression>();
- Status s = _parseTreeList(e.Obj(), xorExpr.get(), collator, childIsTopLevel);
+ Status s =
+ _parseTreeList(e.Obj(), xorExpr.get(), collator, expCtx, childIsTopLevel);
if (!s.isOK())
return s;
root->add(xorExpr.release());
@@ -493,29 +511,28 @@ StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj,
continue;
}
- if (_isExpressionDocument(e, false)) {
- Status s = _parseSub(e.fieldName(), e.Obj(), root.get(), collator, childIsTopLevel);
+ if (_isExpressionDocument(e, false, expCtx)) {
+ Status s =
+ _parseSub(e.fieldName(), e.Obj(), root.get(), collator, expCtx, childIsTopLevel);
if (!s.isOK())
return s;
continue;
}
if (e.type() == RegEx) {
- StatusWithMatchExpression result = _parseRegexElement(e.fieldName(), e);
+ StatusWithMatchExpression result = _parseRegexElement(e.fieldName(), e, expCtx);
if (!result.isOK())
return result;
root->add(result.getValue().release());
continue;
}
- std::unique_ptr<ComparisonMatchExpression> eq =
- stdx::make_unique<EqualityMatchExpression>();
- Status s = eq->init(e.fieldName(), e);
- if (!s.isOK())
- return s;
- eq->setCollator(collator);
+ auto eq =
+ _parseComparison(e.fieldName(), new EqualityMatchExpression(), e, collator, expCtx);
+ if (!eq.isOK())
+ return eq;
- root->add(eq.release());
+ root->add(eq.getValue().release());
}
if (root->numChildren() == 1) {
@@ -531,6 +548,7 @@ Status MatchExpressionParser::_parseSub(const char* name,
const BSONObj& sub,
AndMatchExpression* root,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel) {
// The one exception to {field : {fully contained argument} } is, of course, geo. Example:
// sub == { field : {$near[Sphere]: [0,0], $maxDistance: 1000, $minDistance: 10 } }
@@ -572,7 +590,7 @@ Status MatchExpressionParser::_parseSub(const char* name,
const bool childIsTopLevel = false;
StatusWithMatchExpression s =
- _parseSubField(sub, root, name, deep, collator, childIsTopLevel);
+ _parseSubField(sub, root, name, deep, collator, expCtx, childIsTopLevel);
if (!s.isOK())
return s.getStatus();
@@ -583,7 +601,10 @@ Status MatchExpressionParser::_parseSub(const char* name,
return Status::OK();
}
-bool MatchExpressionParser::_isExpressionDocument(const BSONElement& e, bool allowIncompleteDBRef) {
+bool MatchExpressionParser::_isExpressionDocument(
+ const BSONElement& e,
+ bool allowIncompleteDBRef,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx) {
if (e.type() != Object)
return false;
@@ -599,6 +620,10 @@ bool MatchExpressionParser::_isExpressionDocument(const BSONElement& e, bool all
return false;
}
+ if (_isAggExpression(e, expCtx)) {
+ return false;
+ }
+
return true;
}
@@ -643,7 +668,8 @@ bool MatchExpressionParser::_isDBRefDocument(const BSONObj& obj, bool allowIncom
return hasRef && hasID;
}
-StatusWithMatchExpression MatchExpressionParser::_parseMOD(const char* name, const BSONElement& e) {
+StatusWithMatchExpression MatchExpressionParser::_parseMOD(
+ const char* name, const BSONElement& e, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
if (e.type() != Array)
return {Status(ErrorCodes::BadValue, "malformed mod, needs to be an array")};
@@ -671,8 +697,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseMOD(const char* name, con
return {std::move(temp)};
}
-StatusWithMatchExpression MatchExpressionParser::_parseRegexElement(const char* name,
- const BSONElement& e) {
+StatusWithMatchExpression MatchExpressionParser::_parseRegexElement(
+ const char* name, const BSONElement& e, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
if (e.type() != RegEx)
return {Status(ErrorCodes::BadValue, "not a regex")};
@@ -683,8 +709,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseRegexElement(const char*
return {std::move(temp)};
}
-StatusWithMatchExpression MatchExpressionParser::_parseRegexDocument(const char* name,
- const BSONObj& doc) {
+StatusWithMatchExpression MatchExpressionParser::_parseRegexDocument(
+ const char* name, const BSONObj& doc, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
string regex;
string regexOptions;
@@ -725,9 +751,11 @@ StatusWithMatchExpression MatchExpressionParser::_parseRegexDocument(const char*
return {std::move(temp)};
}
-Status MatchExpressionParser::_parseInExpression(InMatchExpression* inExpression,
- const BSONObj& theArray,
- const CollatorInterface* collator) {
+Status MatchExpressionParser::_parseInExpression(
+ InMatchExpression* inExpression,
+ const BSONObj& theArray,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx) {
inExpression->setCollator(collator);
std::vector<BSONElement> equalities;
BSONObjIterator i(theArray);
@@ -735,7 +763,7 @@ Status MatchExpressionParser::_parseInExpression(InMatchExpression* inExpression
BSONElement e = i.next();
// Allow DBRefs, but reject all fields with names starting with $.
- if (_isExpressionDocument(e, false)) {
+ if (_isExpressionDocument(e, false, expCtx)) {
return Status(ErrorCodes::BadValue, "cannot nest $ under $in");
}
@@ -748,6 +776,10 @@ Status MatchExpressionParser::_parseInExpression(InMatchExpression* inExpression
if (!s.isOK())
return s;
} else {
+ if (_isAggExpression(e, expCtx)) {
+ return Status(ErrorCodes::BadValue, "$expr not supported for $in");
+ }
+
equalities.push_back(e);
}
}
@@ -783,8 +815,10 @@ StatusWith<std::unique_ptr<TypeMatchExpression>> MatchExpressionParser::parseTyp
return {std::move(typeExpr)};
}
-StatusWithMatchExpression MatchExpressionParser::_parseType(const char* name,
- const BSONElement& elt) {
+StatusWithMatchExpression MatchExpressionParser::_parseType(
+ const char* name,
+ const BSONElement& elt,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx) {
if (!elt.isNumber() && elt.type() != BSONType::String) {
return Status(ErrorCodes::TypeMismatch, "argument to $type is not a number or a string");
}
@@ -818,10 +852,12 @@ StatusWithMatchExpression MatchExpressionParser::_parseType(const char* name,
return {std::move(typeExpr)};
}
-StatusWithMatchExpression MatchExpressionParser::_parseElemMatch(const char* name,
- const BSONElement& e,
- const CollatorInterface* collator,
- bool topLevel) {
+StatusWithMatchExpression MatchExpressionParser::_parseElemMatch(
+ const char* name,
+ const BSONElement& e,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ bool topLevel) {
if (e.type() != Object)
return {Status(ErrorCodes::BadValue, "$elemMatch needs an Object")};
@@ -836,7 +872,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseElemMatch(const char* nam
// 3) expression is not a WHERE operator. WHERE works on objects instead
// of specific field.
bool isElemMatchValue = false;
- if (_isExpressionDocument(e, true)) {
+ if (_isExpressionDocument(e, true, expCtx)) {
BSONObj o = e.Obj();
BSONElement elt = o.firstElement();
invariant(!elt.eoo());
@@ -854,7 +890,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseElemMatch(const char* nam
// value case
AndMatchExpression theAnd;
- Status s = _parseSub("", obj, &theAnd, collator, topLevel);
+ Status s = _parseSub("", obj, &theAnd, collator, expCtx, topLevel);
if (!s.isOK())
return s;
@@ -878,7 +914,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseElemMatch(const char* nam
// object case
- StatusWithMatchExpression subRaw = _parse(obj, collator, topLevel);
+ StatusWithMatchExpression subRaw = _parse(obj, collator, expCtx, topLevel);
if (!subRaw.isOK())
return subRaw;
std::unique_ptr<MatchExpression> sub = std::move(subRaw.getValue());
@@ -898,10 +934,12 @@ StatusWithMatchExpression MatchExpressionParser::_parseElemMatch(const char* nam
return {std::move(temp)};
}
-StatusWithMatchExpression MatchExpressionParser::_parseAll(const char* name,
- const BSONElement& e,
- const CollatorInterface* collator,
- bool topLevel) {
+StatusWithMatchExpression MatchExpressionParser::_parseAll(
+ const char* name,
+ const BSONElement& e,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ bool topLevel) {
if (e.type() != Array)
return {Status(ErrorCodes::BadValue, "$all needs an array")};
@@ -931,7 +969,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseAll(const char* name,
const bool childIsTopLevel = false;
StatusWithMatchExpression inner = _parseElemMatch(
- name, hopefullyElemMatchObj.firstElement(), collator, childIsTopLevel);
+ name, hopefullyElemMatchObj.firstElement(), collator, expCtx, childIsTopLevel);
if (!inner.isOK())
return inner;
myAnd->add(inner.getValue().release());
@@ -971,8 +1009,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseAll(const char* name,
}
template <class T>
-StatusWithMatchExpression MatchExpressionParser::_parseBitTest(const char* name,
- const BSONElement& e) {
+StatusWithMatchExpression MatchExpressionParser::_parseBitTest(
+ const char* name, const BSONElement& e, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
std::unique_ptr<BitTestMatchExpression> bitTestMatchExpression = stdx::make_unique<T>();
if (e.type() == BSONType::Array) {
@@ -1179,7 +1217,10 @@ StatusWithMatchExpression MatchExpressionParser::_parseInternalSchemaFmod(const
template <class T>
StatusWithMatchExpression MatchExpressionParser::_parseInternalSchemaFixedArityArgument(
- StringData name, const BSONElement& input, const CollatorInterface* collator) {
+ StringData name,
+ const BSONElement& input,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx) {
constexpr auto arity = T::arity();
if (input.type() != BSONType::Array) {
return {ErrorCodes::FailedToParse,
@@ -1208,7 +1249,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseInternalSchemaFixedArityA
}
const bool isTopLevel = false;
- auto subexpr = _parse(elem.embeddedObject(), collator, isTopLevel);
+ auto subexpr = _parse(elem.embeddedObject(), collator, expCtx, isTopLevel);
if (!subexpr.isOK()) {
return subexpr.getStatus();
}
@@ -1355,6 +1396,33 @@ StatusWithMatchExpression MatchExpressionParser::_parseGeo(const char* name,
}
}
+bool MatchExpressionParser::_isAggExpression(
+ BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+ if (!expCtx) {
+ return false;
+ }
+
+ if (BSONType::Object != elem.type()) {
+ return false;
+ }
+
+ auto obj = elem.embeddedObject();
+ if (obj.nFields() != 1) {
+ return false;
+ }
+
+ return obj.firstElementFieldName() == kAggExpression;
+}
+
+boost::intrusive_ptr<Expression> MatchExpressionParser::_parseAggExpression(
+ BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+ invariant(expCtx);
+
+ auto expr = Expression::parseOperand(
+ expCtx, elem.embeddedObject().firstElement(), expCtx->variablesParseState);
+ return expr->optimize();
+}
+
namespace {
// Maps from query operator string name to operator PathAcceptingKeyword.
std::unique_ptr<StringMap<PathAcceptingKeyword>> queryOperatorMap;
diff --git a/src/mongo/db/matcher/expression_parser.h b/src/mongo/db/matcher/expression_parser.h
index a39410a99b0..88ac25551a9 100644
--- a/src/mongo/db/matcher/expression_parser.h
+++ b/src/mongo/db/matcher/expression_parser.h
@@ -36,6 +36,7 @@
#include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/expression_tree.h"
#include "mongo/db/matcher/extensions_callback.h"
+#include "mongo/db/pipeline/expression_context.h"
#include "mongo/stdx/functional.h"
namespace mongo {
@@ -84,6 +85,8 @@ public:
*/
static const double kLongLongMaxPlusOneAsDouble;
+ static constexpr StringData kAggExpression = "$expr"_sd;
+
/**
* Parses PathAcceptingKeyword from 'typeElem'. Returns 'defaultKeyword' if 'typeElem'
* doesn't represent a known type, or represents PathAcceptingKeyword::EQUALITY which is not
@@ -96,11 +99,14 @@ public:
* caller has to maintain ownership obj
* the tree has views (BSONElement) into obj
*/
- static StatusWithMatchExpression parse(const BSONObj& obj,
- const ExtensionsCallback& extensionsCallback,
- const CollatorInterface* collator) {
+ static StatusWithMatchExpression parse(
+ const BSONObj& obj,
+ const ExtensionsCallback& extensionsCallback,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx = nullptr) {
const bool topLevelCall = true;
- return MatchExpressionParser(&extensionsCallback)._parse(obj, collator, topLevelCall);
+ return MatchExpressionParser(&extensionsCallback)
+ ._parse(obj, collator, expCtx, topLevelCall);
}
/**
@@ -145,7 +151,9 @@ private:
* { $id : "x" } = false (if incomplete DBRef is allowed)
* { $db : "mydb" } = false (if incomplete DBRef is allowed)
*/
- bool _isExpressionDocument(const BSONElement& e, bool allowIncompleteDBRef);
+ bool _isExpressionDocument(const BSONElement& e,
+ bool allowIncompleteDBRef,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
/**
* { $ref: "s", $id: "x" } = true
@@ -166,6 +174,7 @@ private:
*/
StatusWithMatchExpression _parse(const BSONObj& obj,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel);
/**
@@ -177,6 +186,7 @@ private:
const BSONObj& obj,
AndMatchExpression* root,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel);
/**
@@ -189,24 +199,38 @@ private:
const char* name,
const BSONElement& e,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel);
- StatusWithMatchExpression _parseComparison(const char* name,
- ComparisonMatchExpression* cmp,
- const BSONElement& e,
- const CollatorInterface* collator);
+ StatusWithMatchExpression _parseComparison(
+ const char* name,
+ ComparisonMatchExpression* cmp,
+ const BSONElement& e,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
- StatusWithMatchExpression _parseMOD(const char* name, const BSONElement& e);
+ StatusWithMatchExpression _parseMOD(const char* name,
+ const BSONElement& e,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
- StatusWithMatchExpression _parseRegexElement(const char* name, const BSONElement& e);
+ StatusWithMatchExpression _parseRegexElement(
+ const char* name,
+ const BSONElement& e,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
- StatusWithMatchExpression _parseRegexDocument(const char* name, const BSONObj& doc);
+ StatusWithMatchExpression _parseRegexDocument(
+ const char* name,
+ const BSONObj& doc,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
Status _parseInExpression(InMatchExpression* entries,
const BSONObj& theArray,
- const CollatorInterface* collator);
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
- StatusWithMatchExpression _parseType(const char* name, const BSONElement& elt);
+ StatusWithMatchExpression _parseType(const char* name,
+ const BSONElement& elt,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
StatusWithMatchExpression _parseGeo(const char* name,
PathAcceptingKeyword type,
@@ -217,11 +241,13 @@ private:
StatusWithMatchExpression _parseElemMatch(const char* name,
const BSONElement& e,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel);
StatusWithMatchExpression _parseAll(const char* name,
const BSONElement& e,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel);
// tree
@@ -229,18 +255,22 @@ private:
Status _parseTreeList(const BSONObj& arr,
ListOfMatchExpression* out,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel);
StatusWithMatchExpression _parseNot(const char* name,
const BSONElement& e,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel);
/**
* Parses 'e' into a BitTestMatchExpression.
*/
template <class T>
- StatusWithMatchExpression _parseBitTest(const char* name, const BSONElement& e);
+ StatusWithMatchExpression _parseBitTest(const char* name,
+ const BSONElement& e,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
/**
* Converts 'theArray', a BSONArray of integers, into a std::vector of integers.
@@ -254,7 +284,10 @@ private:
*/
template <class T>
StatusWithMatchExpression _parseInternalSchemaFixedArityArgument(
- StringData name, const BSONElement& elem, const CollatorInterface* collator);
+ StringData name,
+ const BSONElement& elem,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx);
/**
* Parses the given BSONElement into a single integer argument and creates a MatchExpression
@@ -278,6 +311,11 @@ private:
StatusWithMatchExpression _parseInternalSchemaMatchArrayIndex(
const char* path, const BSONElement& elem, const CollatorInterface* collator);
+ bool _isAggExpression(BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx);
+
+ boost::intrusive_ptr<Expression> _parseAggExpression(
+ BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx);
+
// Performs parsing for the match extensions. We do not own this pointer - it has to live
// as long as the parser is active.
const ExtensionsCallback* _extensionsCallback;
diff --git a/src/mongo/db/matcher/expression_parser_geo_test.cpp b/src/mongo/db/matcher/expression_parser_geo_test.cpp
index 63008393ad6..4e4197a422d 100644
--- a/src/mongo/db/matcher/expression_parser_geo_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_geo_test.cpp
@@ -35,6 +35,7 @@
#include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_geo.h"
#include "mongo/db/matcher/extensions_callback_disallow_extensions.h"
+#include "mongo/db/pipeline/aggregation_context_fixture.h"
namespace mongo {
@@ -53,6 +54,19 @@ TEST(MatchExpressionParserGeo, WithinBox) {
ASSERT(result.getValue()->matchesBSON(fromjson("{a: {x: 5, y:5.1}}")));
}
+TEST(MatchExpressionParserGeo, RejectsExprAsGeometry) {
+ const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(fromjson("{type: 'Point', coordinates:[0,0]}}")));
+
+ BSONObj query = fromjson("{a:{$geoIntersects:{$geometry: {$expr: '$$userVar'} }}}");
+
+ const CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_NOT_OK(result.getStatus());
+}
+
TEST(MatchExpressionParserGeoNear, ParseNear) {
BSONObj query = fromjson(
"{loc:{$near:{$maxDistance:100, "
diff --git a/src/mongo/db/matcher/expression_parser_leaf_test.cpp b/src/mongo/db/matcher/expression_parser_leaf_test.cpp
index c9bae20aac7..90b4c80dfc4 100644
--- a/src/mongo/db/matcher/expression_parser_leaf_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_leaf_test.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/expression_parser.h"
#include "mongo/db/matcher/extensions_callback_disallow_extensions.h"
+#include "mongo/db/pipeline/expression_context_for_test.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/platform/decimal128.h"
#include "mongo/unittest/unittest.h"
@@ -49,7 +50,7 @@ TEST(MatchExpressionParserLeafTest, NullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == collator);
@@ -62,18 +63,69 @@ TEST(MatchExpressionParserLeafTest, Collation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, ConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$expr"
+ << "$$userVar"));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+
+ ASSERT_OK(result.getStatus());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+
+ auto expr = result.getValue().get();
+
+ BSONObj match = BSON("x" << 123);
+ BSONObj notMatch = BSON("x" << 321);
+
+ ASSERT_TRUE(expr->matchesBSON(match));
+ ASSERT_FALSE(expr->matchesBSON(notMatch));
+}
+
+TEST(MatchExpressionParserLeafTest, ConstantExprFailsWithMissingVariable) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$expr"
+ << "$$userVar"));
+
+ ASSERT_THROWS_CODE(auto sw = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx),
+ UserException,
+ 17276);
+}
+
+TEST(MatchExpressionParserLeafTest, ConstantExprFailsWithMissingExpressionContext) {
+ boost::intrusive_ptr<ExpressionContextForTest> nullExpCtx;
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$expr"
+ << "$$userVar"));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, nullExpCtx);
+
+ ASSERT_NOT_OK(result.getStatus());
+}
+
TEST(MatchExpressionParserLeafTest, SimpleEQ2) {
BSONObj query = BSON("x" << BSON("$eq" << 2));
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
ASSERT(result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -85,7 +137,7 @@ TEST(MatchExpressionParserLeafTest, SimpleEQUndefined) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, EQNullCollation) {
@@ -94,7 +146,7 @@ TEST(MatchExpressionParserLeafTest, EQNullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == collator);
@@ -107,18 +159,43 @@ TEST(MatchExpressionParserLeafTest, EQCollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, EQConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$eq" << BSON("$expr"
+ << "$$userVar")));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+
+ ASSERT_OK(result.getStatus());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+
+ auto expr = result.getValue().get();
+
+ BSONObj match = BSON("x" << 123);
+ BSONObj notMatch = BSON("x" << 321);
+
+ ASSERT_TRUE(expr->matchesBSON(match));
+ ASSERT_FALSE(expr->matchesBSON(notMatch));
+}
+
TEST(MatchExpressionParserLeafTest, SimpleGT1) {
BSONObj query = BSON("x" << BSON("$gt" << 2));
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 2)));
ASSERT(result.getValue()->matchesBSON(BSON("x" << 3)));
@@ -130,7 +207,7 @@ TEST(MatchExpressionParserLeafTest, GTNullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::GT, result.getValue()->matchType());
GTMatchExpression* match = static_cast<GTMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == collator);
@@ -143,18 +220,43 @@ TEST(MatchExpressionParserLeafTest, GTCollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::GT, result.getValue()->matchType());
GTMatchExpression* match = static_cast<GTMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, GTConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$gt" << BSON("$expr"
+ << "$$userVar")));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+
+ ASSERT_OK(result.getStatus());
+ ASSERT_EQUALS(MatchExpression::GT, result.getValue()->matchType());
+
+ auto expr = result.getValue().get();
+
+ BSONObj match = BSON("x" << 500);
+ BSONObj notMatch = BSON("x" << 0);
+
+ ASSERT_TRUE(expr->matchesBSON(match));
+ ASSERT_FALSE(expr->matchesBSON(notMatch));
+}
+
TEST(MatchExpressionParserLeafTest, SimpleLT1) {
BSONObj query = BSON("x" << BSON("$lt" << 2));
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -167,7 +269,7 @@ TEST(MatchExpressionParserLeafTest, LTNullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::LT, result.getValue()->matchType());
LTMatchExpression* match = static_cast<LTMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == collator);
@@ -180,18 +282,43 @@ TEST(MatchExpressionParserLeafTest, LTCollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::LT, result.getValue()->matchType());
LTMatchExpression* match = static_cast<LTMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, LTConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$lt" << BSON("$expr"
+ << "$$userVar")));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+
+ ASSERT_OK(result.getStatus());
+ ASSERT_EQUALS(MatchExpression::LT, result.getValue()->matchType());
+
+ auto expr = result.getValue().get();
+
+ BSONObj match = BSON("x" << 0);
+ BSONObj notMatch = BSON("x" << 500);
+
+ ASSERT_TRUE(expr->matchesBSON(match));
+ ASSERT_FALSE(expr->matchesBSON(notMatch));
+}
+
TEST(MatchExpressionParserLeafTest, SimpleGTE1) {
BSONObj query = BSON("x" << BSON("$gte" << 2));
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
ASSERT(result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -204,7 +331,7 @@ TEST(MatchExpressionParserLeafTest, GTENullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::GTE, result.getValue()->matchType());
GTEMatchExpression* match = static_cast<GTEMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == collator);
@@ -217,18 +344,45 @@ TEST(MatchExpressionParserLeafTest, GTECollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::GTE, result.getValue()->matchType());
GTEMatchExpression* match = static_cast<GTEMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, GTEConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$gte" << BSON("$expr"
+ << "$$userVar")));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+
+ ASSERT_OK(result.getStatus());
+ ASSERT_EQUALS(MatchExpression::GTE, result.getValue()->matchType());
+
+ auto expr = result.getValue().get();
+
+ BSONObj matchEq = BSON("x" << 123);
+ BSONObj matchGt = BSON("x" << 500);
+ BSONObj notMatch = BSON("x" << 0);
+
+ ASSERT_TRUE(expr->matchesBSON(matchEq));
+ ASSERT_TRUE(expr->matchesBSON(matchGt));
+ ASSERT_FALSE(expr->matchesBSON(notMatch));
+}
+
TEST(MatchExpressionParserLeafTest, SimpleLTE1) {
BSONObj query = BSON("x" << BSON("$lte" << 2));
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
ASSERT(result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -241,7 +395,7 @@ TEST(MatchExpressionParserLeafTest, LTENullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::LTE, result.getValue()->matchType());
LTEMatchExpression* match = static_cast<LTEMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == collator);
@@ -254,18 +408,45 @@ TEST(MatchExpressionParserLeafTest, LTECollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::LTE, result.getValue()->matchType());
LTEMatchExpression* match = static_cast<LTEMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, LTEConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$lte" << BSON("$expr"
+ << "$$userVar")));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+
+ ASSERT_OK(result.getStatus());
+ ASSERT_EQUALS(MatchExpression::LTE, result.getValue()->matchType());
+
+ auto expr = result.getValue().get();
+
+ BSONObj matchEq = BSON("x" << 123);
+ BSONObj matchLt = BSON("x" << 0);
+ BSONObj notMatch = BSON("x" << 500);
+
+ ASSERT_TRUE(expr->matchesBSON(matchEq));
+ ASSERT_TRUE(expr->matchesBSON(matchLt));
+ ASSERT_FALSE(expr->matchesBSON(notMatch));
+}
+
TEST(MatchExpressionParserLeafTest, SimpleNE1) {
BSONObj query = BSON("x" << BSON("$ne" << 2));
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -278,7 +459,7 @@ TEST(MatchExpressionParserLeafTest, NENullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
MatchExpression* child = result.getValue()->getChild(0);
ASSERT_EQUALS(MatchExpression::EQ, child->matchType());
@@ -293,7 +474,7 @@ TEST(MatchExpressionParserLeafTest, NECollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
MatchExpression* child = result.getValue()->getChild(0);
ASSERT_EQUALS(MatchExpression::EQ, child->matchType());
@@ -301,32 +482,57 @@ TEST(MatchExpressionParserLeafTest, NECollation) {
ASSERT_TRUE(eqMatch->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, NEConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$ne" << BSON("$expr"
+ << "$$userVar")));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+
+ ASSERT_OK(result.getStatus());
+ ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
+
+ auto expr = result.getValue().get();
+
+ BSONObj match = BSON("x" << 0);
+ BSONObj notMatch = BSON("x" << 123);
+
+ ASSERT_TRUE(expr->matchesBSON(match));
+ ASSERT_FALSE(expr->matchesBSON(notMatch));
+}
+
TEST(MatchExpressionParserLeafTest, SimpleModBad1) {
BSONObj query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2)));
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
query = BSON("x" << BSON("$mod" << BSON_ARRAY(3)));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(!result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2 << 4)));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(!result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
query = BSON("x" << BSON("$mod" << BSON_ARRAY("q" << 2)));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(!result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
query = BSON("x" << BSON("$mod" << 3));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(!result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
query = BSON("x" << BSON("$mod" << BSON("a" << 1 << "b" << 2)));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(!result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, SimpleMod1) {
@@ -334,7 +540,7 @@ TEST(MatchExpressionParserLeafTest, SimpleMod1) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 5)));
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 4)));
@@ -346,7 +552,7 @@ TEST(MatchExpressionParserLeafTest, SimpleModNotNumber) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 2)));
ASSERT(result.getValue()->matchesBSON(BSON("x" << 4)));
@@ -355,13 +561,29 @@ TEST(MatchExpressionParserLeafTest, SimpleModNotNumber) {
<< "a")));
}
+TEST(MatchExpressionParserLeafTest, ModConstantExprFails) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$mod" << BSON("$expr"
+ << "$$userVar")));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(BSON_ARRAY(10 << 2)));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+ ASSERT_NOT_OK(result.getStatus());
+ ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
+}
+
TEST(MatchExpressionParserLeafTest, IdCollation) {
BSONObj query = BSON("$id"
<< "string");
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == collator);
@@ -373,42 +595,93 @@ TEST(MatchExpressionParserLeafTest, IdNullCollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, IdConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("$id" << BSON("$expr"
+ << "$$userVar"));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+ ASSERT_OK(result.getStatus());
+
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+}
+
TEST(MatchExpressionParserLeafTest, RefCollation) {
BSONObj query = BSON("$ref"
<< "coll");
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == nullptr);
}
+TEST(MatchExpressionParserLeafTest, RefConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("$ref" << BSON("$expr"
+ << "$$userVar"));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(std::string("colName")));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+ ASSERT_OK(result.getStatus());
+
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+}
+
TEST(MatchExpressionParserLeafTest, DbCollation) {
BSONObj query = BSON("$db"
<< "db");
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == nullptr);
}
+TEST(MatchExpressionParserLeafTest, DbConstantExpr) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("$db" << BSON("$expr"
+ << "$$userVar"));
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(std::string("dbName")));
+
+ auto result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), collator, expCtx);
+ ASSERT_OK(result.getStatus());
+
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+}
+
TEST(MatchExpressionParserLeafTest, SimpleIN1) {
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(2 << 3)));
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
ASSERT(result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -420,7 +693,7 @@ TEST(MatchExpressionParserLeafTest, INNullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::MATCH_IN, result.getValue()->matchType());
InMatchExpression* match = static_cast<InMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == collator);
@@ -431,12 +704,39 @@ TEST(MatchExpressionParserLeafTest, INCollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::MATCH_IN, result.getValue()->matchType());
InMatchExpression* match = static_cast<InMatchExpression*>(result.getValue().get());
ASSERT_TRUE(match->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, INConstantExprFails) {
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+
+ // $expr represents entire $in array.
+ BSONObj query = BSON("x" << BSON("$in" << BSON("$expr"
+ << "userVar")));
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(BSON_ARRAY(1 << 2)));
+
+ StatusWithMatchExpression result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), &collator, expCtx);
+ ASSERT_NOT_OK(result.getStatus());
+ ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
+
+ // $expr represents a single element of the $in array.
+ query = BSON("x" << BSON("$in" << BSON_ARRAY(1 << BSON("$expr"
+ << "userVar"))));
+ varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), &collator, expCtx);
+ ASSERT_NOT_OK(result.getStatus());
+ ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
+}
+
TEST(MatchExpressionParserLeafTest, INSingleDBRef) {
OID oid = OID::gen();
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref"
@@ -448,7 +748,7 @@ TEST(MatchExpressionParserLeafTest, INSingleDBRef) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
OID oidx = OID::gen();
ASSERT(!result.getValue()->matchesBSON(BSON("x" << BSON("$ref"
@@ -531,7 +831,7 @@ TEST(MatchExpressionParserLeafTest, INMultipleDBRef) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
OID oidx = OID::gen();
ASSERT(!result.getValue()->matchesBSON(BSON("x" << BSON("$ref"
@@ -673,7 +973,7 @@ TEST(MatchExpressionParserLeafTest, INDBRefWithOptionalField1) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
OID oidx = OID::gen();
ASSERT(!result.getValue()->matchesBSON(BSON("x" << BSON("$ref"
@@ -717,14 +1017,14 @@ TEST(MatchExpressionParserLeafTest, INInvalidDBRefs) {
<< "$foo"
<< 1))));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
OID oid = OID::gen();
// missing $ref field
query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$id" << oid << "foo" << 3))));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
// missing $id and $ref field
query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$db"
@@ -732,7 +1032,7 @@ TEST(MatchExpressionParserLeafTest, INInvalidDBRefs) {
<< "foo"
<< 3))));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, INExpressionDocument) {
@@ -740,7 +1040,7 @@ TEST(MatchExpressionParserLeafTest, INExpressionDocument) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, INNotArray) {
@@ -748,7 +1048,7 @@ TEST(MatchExpressionParserLeafTest, INNotArray) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, INUndefined) {
@@ -756,7 +1056,7 @@ TEST(MatchExpressionParserLeafTest, INUndefined) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, INNotElemMatch) {
@@ -764,7 +1064,7 @@ TEST(MatchExpressionParserLeafTest, INNotElemMatch) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, INRegexTooLong) {
@@ -777,7 +1077,7 @@ TEST(MatchExpressionParserLeafTest, INRegexTooLong) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, INRegexTooLong2) {
@@ -786,7 +1086,7 @@ TEST(MatchExpressionParserLeafTest, INRegexTooLong2) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, INRegexStuff) {
@@ -801,7 +1101,7 @@ TEST(MatchExpressionParserLeafTest, INRegexStuff) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
BSONObj matchFirst = BSON("a"
<< "ax");
@@ -828,7 +1128,7 @@ TEST(MatchExpressionParserLeafTest, SimpleNIN1) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -840,7 +1140,7 @@ TEST(MatchExpressionParserLeafTest, NINNotArray) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, NINNullCollation) {
@@ -848,7 +1148,7 @@ TEST(MatchExpressionParserLeafTest, NINNullCollation) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
MatchExpression* child = result.getValue()->getChild(0);
ASSERT_EQUALS(MatchExpression::MATCH_IN, child->matchType());
@@ -861,7 +1161,7 @@ TEST(MatchExpressionParserLeafTest, NINCollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
MatchExpression* child = result.getValue()->getChild(0);
ASSERT_EQUALS(MatchExpression::MATCH_IN, child->matchType());
@@ -869,6 +1169,33 @@ TEST(MatchExpressionParserLeafTest, NINCollation) {
ASSERT_TRUE(inMatch->getCollator() == &collator);
}
+TEST(MatchExpressionParserLeafTest, NINConstantExprFails) {
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+
+ // $expr represents entire $in array.
+ BSONObj query = BSON("x" << BSON("$nin" << BSON("$expr"
+ << "userVar")));
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(BSON_ARRAY(1 << 2)));
+
+ StatusWithMatchExpression result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), &collator, expCtx);
+ ASSERT_NOT_OK(result.getStatus());
+ ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
+
+ // $expr represents a single element of the $in array.
+ query = BSON("x" << BSON("$nin" << BSON_ARRAY(1 << BSON("$expr"
+ << "userVar"))));
+ varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ result = MatchExpressionParser::parse(
+ query, ExtensionsCallbackDisallowExtensions(), &collator, expCtx);
+ ASSERT_NOT_OK(result.getStatus());
+ ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
+}
+
TEST(MatchExpressionParserLeafTest, Regex1) {
BSONObjBuilder b;
b.appendRegex("x", "abc", "i");
@@ -876,7 +1203,7 @@ TEST(MatchExpressionParserLeafTest, Regex1) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x"
<< "abc")));
@@ -894,7 +1221,7 @@ TEST(MatchExpressionParserLeafTest, Regex2) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x"
<< "abc")));
@@ -912,7 +1239,7 @@ TEST(MatchExpressionParserLeafTest, Regex3) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x"
<< "abc")));
@@ -931,26 +1258,26 @@ TEST(MatchExpressionParserLeafTest, RegexBad) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
// $regex does not with numbers
query = BSON("x" << BSON("$regex" << 123));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
query = BSON("x" << BSON("$regex" << BSON_ARRAY("abc")));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
query = BSON("x" << BSON("$optionas"
<< "i"));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
query = BSON("x" << BSON("$options"
<< "i"));
result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, RegexEmbeddedNULByte) {
@@ -959,7 +1286,7 @@ TEST(MatchExpressionParserLeafTest, RegexEmbeddedNULByte) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
const auto value = "a\0b"_sd;
ASSERT(result.getValue()->matchesBSON(BSON("x" << value)));
@@ -967,6 +1294,34 @@ TEST(MatchExpressionParserLeafTest, RegexEmbeddedNULByte) {
<< "a")));
}
+TEST(MatchExpressionParserLeafTest, RegexWithConstantExprFails) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$options" << BSON("$expr"
+ << "userVar")
+ << "$regex"
+ << "abc"));
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(std::string("i")));
+
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_NOT_OK(result.getStatus());
+
+
+ query = BSON("x" << BSON("$options"
+ << "i"
+ << "$regex"
+ << BSON("$expr"
+ << "userVar")));
+ varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(std::string("abc")));
+
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_NOT_OK(result.getStatus());
+}
+
TEST(MatchExpressionParserLeafTest, ExistsYes1) {
BSONObjBuilder b;
b.appendBool("$exists", true);
@@ -974,7 +1329,7 @@ TEST(MatchExpressionParserLeafTest, ExistsYes1) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x"
<< "abc")));
@@ -989,7 +1344,7 @@ TEST(MatchExpressionParserLeafTest, ExistsNO1) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(!result.getValue()->matchesBSON(BSON("x"
<< "abc")));
@@ -1002,7 +1357,7 @@ TEST(MatchExpressionParserLeafTest, Type1) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x"
<< "abc")));
@@ -1014,7 +1369,7 @@ TEST(MatchExpressionParserLeafTest, Type2) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 5.3)));
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 5)));
@@ -1025,7 +1380,7 @@ TEST(MatchExpressionParserLeafTest, TypeDoubleOperator) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 5.3)));
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 5)));
@@ -1036,7 +1391,7 @@ TEST(MatchExpressionParserLeafTest, TypeDecimalOperator) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT_FALSE(result.getValue()->matchesBSON(BSON("x" << 5.3)));
ASSERT_TRUE(result.getValue()->matchesBSON(BSON("x" << mongo::Decimal128("1"))));
@@ -1047,7 +1402,7 @@ TEST(MatchExpressionParserLeafTest, TypeNull) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_TRUE(result.isOK());
+ ASSERT_OK(result.getStatus());
ASSERT(!result.getValue()->matchesBSON(BSONObj()));
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 5)));
@@ -1071,7 +1426,7 @@ TEST(MatchExpressionParserLeafTest, TypeBad) {
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
- ASSERT_FALSE(result.isOK());
+ ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, TypeBadString) {
@@ -1264,6 +1619,20 @@ TEST(MatchExpressionParserLeafTest, ValidTypeCodesParseSuccessfully) {
}
}
+TEST(MatchExpressionParserLeafTest, TypeWithConstantExprFails) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ BSONObj query = BSON("x" << BSON("$type" << BSON("$expr"
+ << "userVar")));
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(static_cast<int>(BSONType::NumberDouble)));
+
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_NOT_OK(result.getStatus());
+}
+
TEST(MatchExpressionParserTest, BitTestMatchExpressionValidMask) {
const double k2Power53 = scalbn(1, 32);
@@ -1947,4 +2316,36 @@ TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidArrayValue) {
collator)
.getStatus());
}
+
+TEST(MatchExpressionParserLeafTest, BitTestWithConstantExprFails) {
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ const CollatorInterface* collator = nullptr;
+
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(BSON_ARRAY(1 << 5)));
+
+ ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [{$expr: 'userVar'}]}}"),
+ ExtensionsCallbackDisallowExtensions(),
+ collator,
+ expCtx)
+ .getStatus());
+
+ ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: {$expr: 'userVar'}}}"),
+ ExtensionsCallbackDisallowExtensions(),
+ collator,
+ expCtx)
+ .getStatus());
+
+ ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: {$expr: 'userVar'}}}"),
+ ExtensionsCallbackDisallowExtensions(),
+ collator,
+ expCtx)
+ .getStatus());
+
+ ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: {$expr: 'userVar'}}}"),
+ ExtensionsCallbackDisallowExtensions(),
+ collator,
+ expCtx)
+ .getStatus());
}
+} // namespace mongo
diff --git a/src/mongo/db/matcher/expression_parser_tree.cpp b/src/mongo/db/matcher/expression_parser_tree.cpp
index 91abc73cbfa..b7ba5964253 100644
--- a/src/mongo/db/matcher/expression_parser_tree.cpp
+++ b/src/mongo/db/matcher/expression_parser_tree.cpp
@@ -42,6 +42,7 @@ namespace mongo {
Status MatchExpressionParser::_parseTreeList(const BSONObj& arr,
ListOfMatchExpression* out,
const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
bool topLevel) {
if (arr.isEmpty())
return Status(ErrorCodes::BadValue, "$and/$or/$nor must be a nonempty array");
@@ -53,7 +54,7 @@ Status MatchExpressionParser::_parseTreeList(const BSONObj& arr,
if (e.type() != Object)
return Status(ErrorCodes::BadValue, "$or/$and/$nor entries need to be full objects");
- StatusWithMatchExpression sub = _parse(e.Obj(), collator, topLevel);
+ StatusWithMatchExpression sub = _parse(e.Obj(), collator, expCtx, topLevel);
if (!sub.isOK())
return sub.getStatus();
@@ -62,12 +63,14 @@ Status MatchExpressionParser::_parseTreeList(const BSONObj& arr,
return Status::OK();
}
-StatusWithMatchExpression MatchExpressionParser::_parseNot(const char* name,
- const BSONElement& e,
- const CollatorInterface* collator,
- bool topLevel) {
+StatusWithMatchExpression MatchExpressionParser::_parseNot(
+ const char* name,
+ const BSONElement& e,
+ const CollatorInterface* collator,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ bool topLevel) {
if (e.type() == RegEx) {
- StatusWithMatchExpression s = _parseRegexElement(name, e);
+ StatusWithMatchExpression s = _parseRegexElement(name, e, expCtx);
if (!s.isOK())
return s;
std::unique_ptr<NotMatchExpression> n = stdx::make_unique<NotMatchExpression>();
@@ -85,7 +88,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseNot(const char* name,
return StatusWithMatchExpression(ErrorCodes::BadValue, "$not cannot be empty");
std::unique_ptr<AndMatchExpression> theAnd = stdx::make_unique<AndMatchExpression>();
- Status s = _parseSub(name, notObject, theAnd.get(), collator, topLevel);
+ Status s = _parseSub(name, notObject, theAnd.get(), collator, expCtx, topLevel);
if (!s.isOK())
return StatusWithMatchExpression(s);
diff --git a/src/mongo/db/matcher/expression_text_base.h b/src/mongo/db/matcher/expression_text_base.h
index 0f75e40b412..65b38f90b43 100644
--- a/src/mongo/db/matcher/expression_text_base.h
+++ b/src/mongo/db/matcher/expression_text_base.h
@@ -52,6 +52,7 @@ public:
static const bool kDiacriticSensitiveDefault;
TextMatchExpressionBase();
+ virtual ~TextMatchExpressionBase() {}
/**
* Returns a reference to the parsed text query that this TextMatchExpressionBase owns.
diff --git a/src/mongo/db/pipeline/document_source_match.cpp b/src/mongo/db/pipeline/document_source_match.cpp
index 38c78d8ad30..250aa387c01 100644
--- a/src/mongo/db/pipeline/document_source_match.cpp
+++ b/src/mongo/db/pipeline/document_source_match.cpp
@@ -359,8 +359,8 @@ bool DocumentSourceMatch::isTextQuery(const BSONObj& query) {
void DocumentSourceMatch::joinMatchWith(intrusive_ptr<DocumentSourceMatch> other) {
_predicate = BSON("$and" << BSON_ARRAY(_predicate << other->getQuery()));
- StatusWithMatchExpression status = uassertStatusOK(
- MatchExpressionParser::parse(_predicate, ExtensionsCallbackNoop(), pExpCtx->getCollator()));
+ StatusWithMatchExpression status = uassertStatusOK(MatchExpressionParser::parse(
+ _predicate, ExtensionsCallbackNoop(), pExpCtx->getCollator(), pExpCtx));
_expression = std::move(status.getValue());
_dependencies = DepsTracker(_dependencies.getMetadataAvailable());
getDependencies(&_dependencies);
@@ -506,8 +506,8 @@ void DocumentSourceMatch::addDependencies(DepsTracker* deps) const {
DocumentSourceMatch::DocumentSourceMatch(const BSONObj& query,
const intrusive_ptr<ExpressionContext>& pExpCtx)
: DocumentSource(pExpCtx), _predicate(query.getOwned()), _isTextQuery(isTextQuery(query)) {
- StatusWithMatchExpression status = uassertStatusOK(
- MatchExpressionParser::parse(_predicate, ExtensionsCallbackNoop(), pExpCtx->getCollator()));
+ StatusWithMatchExpression status = uassertStatusOK(MatchExpressionParser::parse(
+ _predicate, ExtensionsCallbackNoop(), pExpCtx->getCollator(), pExpCtx));
_expression = std::move(status.getValue());
getDependencies(&_dependencies);
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 6e5ab270f46..d1bdaf6c983 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -1832,6 +1832,14 @@ intrusive_ptr<Expression> ExpressionFieldPath::optimize() {
return ExpressionConstant::create(getExpressionContext(), Value());
}
+ if (Variables::isUserDefinedVariable(_variable) &&
+ getExpressionContext()->variables.hasUserDefinedValue(_variable)) {
+ const auto val = getExpressionContext()->variables.getUserDefinedValue(_variable);
+ if (!val.missing()) {
+ return ExpressionConstant::create(getExpressionContext(), val);
+ }
+ }
+
return intrusive_ptr<Expression>(this);
}
diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp
index 22180869ccb..b05a1bc1515 100644
--- a/src/mongo/db/pipeline/expression_test.cpp
+++ b/src/mongo/db/pipeline/expression_test.cpp
@@ -2190,17 +2190,48 @@ public:
}
};
-/** No optimization is performed. */
-class Optimize {
-public:
- void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a");
- // An attempt to optimize returns the Expression itself.
- ASSERT_EQUALS(expression, expression->optimize());
- }
+TEST(FieldPath, NoOptimizationOnNormalPath) {
+ intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a");
+ // An attempt to optimize returns the Expression itself.
+ ASSERT_EQUALS(expression, expression->optimize());
};
+TEST(FieldPath, OptimizeOnVariableWithConstantValue) {
+ intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value(123));
+
+ auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar", expCtx->variablesParseState);
+ ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
+
+ auto optimizedExpr = expr->optimize();
+ ASSERT_TRUE(dynamic_cast<ExpressionConstant*>(optimizedExpr.get()));
+}
+
+TEST(FieldPath, NoOptimizationOnVariableWithNoValue) {
+ intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ expCtx->variablesParseState.defineVariable("userVar");
+
+ auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar", expCtx->variablesParseState);
+ ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
+
+ auto optimizedExpr = expr->optimize();
+ ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(optimizedExpr.get()));
+}
+
+TEST(FieldPath, NoOptimizationOnVariableWithMissingValue) {
+ intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto varId = expCtx->variablesParseState.defineVariable("userVar");
+ expCtx->variables.setValue(varId, Value());
+
+ auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar", expCtx->variablesParseState);
+ ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
+
+ auto optimizedExpr = expr->optimize();
+ ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(optimizedExpr.get()));
+}
+
/** The field path itself is a dependency. */
class Dependencies {
public:
@@ -5254,7 +5285,6 @@ public:
add<Constant::AddToBsonArray>();
add<FieldPath::Invalid>();
- add<FieldPath::Optimize>();
add<FieldPath::Dependencies>();
add<FieldPath::Missing>();
add<FieldPath::Present>();
diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp
index f1222797f11..36aad7baf0d 100644
--- a/src/mongo/db/pipeline/pipeline_d.cpp
+++ b/src/mongo/db/pipeline/pipeline_d.cpp
@@ -420,7 +420,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> attemptToGetExe
const ExtensionsCallbackReal extensionsCallback(pExpCtx->opCtx, &nss);
- auto cq = CanonicalQuery::canonicalize(opCtx, std::move(qr), extensionsCallback);
+ auto cq = CanonicalQuery::canonicalize(opCtx, std::move(qr), extensionsCallback, pExpCtx);
if (!cq.isOK()) {
// Return an error instead of uasserting, since there are cases where the combination of
diff --git a/src/mongo/db/pipeline/pipeline_test.cpp b/src/mongo/db/pipeline/pipeline_test.cpp
index 0401460e60a..fb98ea45eeb 100644
--- a/src/mongo/db/pipeline/pipeline_test.cpp
+++ b/src/mongo/db/pipeline/pipeline_test.cpp
@@ -566,7 +566,8 @@ TEST(PipelineOptimizationTest, LookupDoesNotAbsorbUnwindOnSubfieldOfAsButStillMo
TEST(PipelineOptimizationTest, MatchShouldDuplicateItselfBeforeRedact) {
string inputPipe = "[{$redact: '$$PRUNE'}, {$match: {a: 1, b:12}}]";
- string outputPipe = "[{$match: {a: 1, b:12}}, {$redact: '$$PRUNE'}, {$match: {a: 1, b:12}}]";
+ string outputPipe =
+ "[{$match: {a: 1, b:12}}, {$redact: {$const: 'prune'}}, {$match: {a: 1, b:12}}]";
assertPipelineOptimizesTo(inputPipe, outputPipe);
}
diff --git a/src/mongo/db/pipeline/variables.cpp b/src/mongo/db/pipeline/variables.cpp
index 39b9130ed6e..ac713a37f5a 100644
--- a/src/mongo/db/pipeline/variables.cpp
+++ b/src/mongo/db/pipeline/variables.cpp
@@ -109,6 +109,15 @@ void Variables::setValue(Id id, const Value& value) {
_valueList[id] = value;
}
+Value Variables::getUserDefinedValue(Variables::Id id) const {
+ invariant(isUserDefinedVariable(id));
+
+ uassert(40434,
+ str::stream() << "Requesting Variables::getValue with an out of range id: " << id,
+ static_cast<size_t>(id) < _valueList.size());
+ return _valueList[id];
+}
+
Value Variables::getValue(Id id, const Document& root) const {
if (id < 0) {
// This is a reserved id for a builtin variable.
@@ -122,10 +131,7 @@ Value Variables::getValue(Id id, const Document& root) const {
}
}
- uassert(40434,
- str::stream() << "Requesting Variables::getValue with an out of range id: " << id,
- static_cast<size_t>(id) < _valueList.size());
- return _valueList[id];
+ return getUserDefinedValue(id);
}
Document Variables::getDocument(Id id, const Document& root) const {
diff --git a/src/mongo/db/pipeline/variables.h b/src/mongo/db/pipeline/variables.h
index efbf115269f..4e487e811f4 100644
--- a/src/mongo/db/pipeline/variables.h
+++ b/src/mongo/db/pipeline/variables.h
@@ -64,6 +64,10 @@ public:
static void uassertValidNameForUserWrite(StringData varName);
static void uassertValidNameForUserRead(StringData varName);
+ static bool isUserDefinedVariable(Variables::Id id) {
+ return id >= 0;
+ }
+
// Ids for builtin variables.
static constexpr Variables::Id kRootId = Id(-1);
static constexpr Variables::Id kRemoveId = Id(-2);
@@ -84,6 +88,20 @@ public:
Value getValue(Variables::Id id, const Document& root) const;
/**
+ * Gets the value of a user-defined variable. Should only be called when we know 'id' represents
+ * a user-defined variable.
+ */
+ Value getUserDefinedValue(Variables::Id id) const;
+
+ /**
+ * Returns whether a value for 'id' has been stored in this Variables instance.
+ */
+ bool hasUserDefinedValue(Variables::Id id) const {
+ invariant(isUserDefinedVariable(id));
+ return _valueList.size() > static_cast<size_t>(id);
+ }
+
+ /**
* Returns Document() for non-document values, but otherwise identical to getValue(). If the
* 'id' provided represents the special ROOT variable, then we return 'root'.
*/
diff --git a/src/mongo/db/query/canonical_query.cpp b/src/mongo/db/query/canonical_query.cpp
index ace19183ff5..a8e512c22d9 100644
--- a/src/mongo/db/query/canonical_query.cpp
+++ b/src/mongo/db/query/canonical_query.cpp
@@ -102,21 +102,26 @@ bool matchExpressionLessThan(const MatchExpression* lhs, const MatchExpression*
// static
StatusWith<std::unique_ptr<CanonicalQuery>> CanonicalQuery::canonicalize(
- OperationContext* opCtx, const QueryMessage& qm, const ExtensionsCallback& extensionsCallback) {
+ OperationContext* opCtx,
+ const QueryMessage& qm,
+ const ExtensionsCallback& extensionsCallback,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx) {
// Make QueryRequest.
auto qrStatus = QueryRequest::fromLegacyQueryMessage(qm);
if (!qrStatus.isOK()) {
return qrStatus.getStatus();
}
- return CanonicalQuery::canonicalize(opCtx, std::move(qrStatus.getValue()), extensionsCallback);
+ return CanonicalQuery::canonicalize(
+ opCtx, std::move(qrStatus.getValue()), extensionsCallback, expCtx);
}
// static
StatusWith<std::unique_ptr<CanonicalQuery>> CanonicalQuery::canonicalize(
OperationContext* opCtx,
std::unique_ptr<QueryRequest> qr,
- const ExtensionsCallback& extensionsCallback) {
+ const ExtensionsCallback& extensionsCallback,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx) {
auto qrStatus = qr->validate();
if (!qrStatus.isOK()) {
return qrStatus;
@@ -134,7 +139,7 @@ StatusWith<std::unique_ptr<CanonicalQuery>> CanonicalQuery::canonicalize(
// Make MatchExpression.
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(qr->getFilter(), extensionsCallback, collator.get());
+ MatchExpressionParser::parse(qr->getFilter(), extensionsCallback, collator.get(), expCtx);
if (!statusWithMatcher.isOK()) {
return statusWithMatcher.getStatus();
}
diff --git a/src/mongo/db/query/canonical_query.h b/src/mongo/db/query/canonical_query.h
index dfcbaf070f0..f2466fe0c66 100644
--- a/src/mongo/db/query/canonical_query.h
+++ b/src/mongo/db/query/canonical_query.h
@@ -48,26 +48,28 @@ public:
* query (which will never be NULL). If parsing fails, returns an error Status.
*
* 'opCtx' must point to a valid OperationContext, but 'opCtx' does not need to outlive the
- * returned
- * CanonicalQuery.
+ * returned CanonicalQuery.
*
* Used for legacy find through the OP_QUERY message.
*/
static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize(
OperationContext* opCtx,
const QueryMessage& qm,
- const ExtensionsCallback& extensionsCallback);
+ const ExtensionsCallback& extensionsCallback,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx = nullptr);
/**
* If parsing succeeds, returns a std::unique_ptr<CanonicalQuery> representing the parsed
* query (which will never be NULL). If parsing fails, returns an error Status.
*
* 'opCtx' must point to a valid OperationContext, but 'opCtx' does not need to outlive the
- * returned
- * CanonicalQuery.
+ * returned CanonicalQuery.
*/
static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize(
- OperationContext* opCtx, std::unique_ptr<QueryRequest> qr, const ExtensionsCallback&);
+ OperationContext* opCtx,
+ std::unique_ptr<QueryRequest> qr,
+ const ExtensionsCallback&,
+ const boost::intrusive_ptr<ExpressionContext>& expCtx = nullptr);
/**
* For testing or for internal clients to use.
diff --git a/src/mongo/db/update/addtoset_node_test.cpp b/src/mongo/db/update/addtoset_node_test.cpp
index 816cccf4899..c8440764c38 100644
--- a/src/mongo/db/update/addtoset_node_test.cpp
+++ b/src/mongo/db/update/addtoset_node_test.cpp
@@ -42,7 +42,6 @@ namespace mongo {
namespace {
using AddToSetNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -109,7 +108,7 @@ TEST_F(AddToSetNodeTest, ApplyFailsOnNonArray) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: 2}"));
+ mutablebson::Document doc(fromjson("{a: 2}"));
setPathTaken("a");
ASSERT_THROWS_CODE_AND_WHAT(
node.apply(getApplyParams(doc.root()["a"])),
@@ -124,7 +123,7 @@ TEST_F(AddToSetNodeTest, ApplyNonEach) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -141,7 +140,7 @@ TEST_F(AddToSetNodeTest, ApplyNonEachArray) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -158,7 +157,7 @@ TEST_F(AddToSetNodeTest, ApplyEach) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -175,7 +174,7 @@ TEST_F(AddToSetNodeTest, ApplyToEmptyArray) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -192,7 +191,7 @@ TEST_F(AddToSetNodeTest, ApplyDeduplicateElementsToAdd) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -209,7 +208,7 @@ TEST_F(AddToSetNodeTest, ApplyDoNotAddExistingElements) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -226,7 +225,7 @@ TEST_F(AddToSetNodeTest, ApplyDoNotDeduplicateExistingElements) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0, 0]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -243,7 +242,7 @@ TEST_F(AddToSetNodeTest, ApplyNoElementsToAdd) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -260,7 +259,7 @@ TEST_F(AddToSetNodeTest, ApplyNoNonDuplicateElementsToAdd) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -277,7 +276,7 @@ TEST_F(AddToSetNodeTest, ApplyCreateArray) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -294,7 +293,7 @@ TEST_F(AddToSetNodeTest, ApplyCreateEmptyArrayIsNotNoop) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -311,7 +310,7 @@ TEST_F(AddToSetNodeTest, ApplyDeduplicationOfElementsToAddRespectsCollation) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], &collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -328,7 +327,7 @@ TEST_F(AddToSetNodeTest, ApplyComparisonToExistingElementsRespectsCollation) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], &collator));
- Document doc(fromjson("{a: ['ABC']}"));
+ mutablebson::Document doc(fromjson("{a: ['ABC']}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -349,7 +348,7 @@ TEST_F(AddToSetNodeTest, ApplyRespectsCollationFromSetCollator) {
CollatorInterfaceMock::MockType::kToLowerString);
node.setCollator(&caseInsensitiveCollator);
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -387,7 +386,7 @@ TEST_F(AddToSetNodeTest, ApplyNestedArray) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a.1"], collator));
- Document doc(fromjson("{ _id : 1, a : [ 1, [ ] ] }"));
+ mutablebson::Document doc(fromjson("{ _id : 1, a : [ 1, [ ] ] }"));
setPathTaken("a.1");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["1"]));
@@ -404,7 +403,7 @@ TEST_F(AddToSetNodeTest, ApplyIndexesNotAffected) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("b");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -420,7 +419,7 @@ TEST_F(AddToSetNodeTest, ApplyNoIndexDataOrLogBuilder) {
AddToSetNode node;
ASSERT_OK(node.init(update["$addToSet"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
diff --git a/src/mongo/db/update/arithmetic_node_test.cpp b/src/mongo/db/update/arithmetic_node_test.cpp
index 76855f66640..3a4d74121ea 100644
--- a/src/mongo/db/update/arithmetic_node_test.cpp
+++ b/src/mongo/db/update/arithmetic_node_test.cpp
@@ -41,7 +41,6 @@ namespace mongo {
namespace {
using ArithmeticNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -116,7 +115,7 @@ TEST_F(ArithmeticNodeTest, ApplyIncNoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -133,7 +132,7 @@ TEST_F(ArithmeticNodeTest, ApplyMulNoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kMultiply);
ASSERT_OK(node.init(update["$mul"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -150,7 +149,7 @@ TEST_F(ArithmeticNodeTest, ApplyRoundingNoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: 6.022e23}"));
+ mutablebson::Document doc(fromjson("{a: 6.022e23}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -167,7 +166,7 @@ TEST_F(ArithmeticNodeTest, ApplyEmptyPathToCreate) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -184,7 +183,7 @@ TEST_F(ArithmeticNodeTest, ApplyCreatePath) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b.c"], collator));
- Document doc(fromjson("{a: {d: 5}}"));
+ mutablebson::Document doc(fromjson("{a: {d: 5}}"));
setPathToCreate("b.c");
setPathTaken("a");
addIndexedPath("a");
@@ -202,7 +201,7 @@ TEST_F(ArithmeticNodeTest, ApplyExtendPath) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{a: {c: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {c: 1}}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a.b");
@@ -219,7 +218,7 @@ TEST_F(ArithmeticNodeTest, ApplyCreatePathFromRoot) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{c: 5}"));
+ mutablebson::Document doc(fromjson("{c: 5}"));
setPathToCreate("a.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -236,7 +235,7 @@ TEST_F(ArithmeticNodeTest, ApplyPositional) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.$"], collator));
- Document doc(fromjson("{a: [0, 1, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2]}"));
setPathTaken("a.1");
setMatchedField("1");
addIndexedPath("a");
@@ -254,7 +253,7 @@ TEST_F(ArithmeticNodeTest, ApplyNonViablePathToInc) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a");
@@ -270,7 +269,7 @@ TEST_F(ArithmeticNodeTest, ApplyNonViablePathToCreateFromReplicationIsNoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a");
@@ -289,7 +288,7 @@ TEST_F(ArithmeticNodeTest, ApplyNoIndexDataNoLogBuilder) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -305,7 +304,7 @@ TEST_F(ArithmeticNodeTest, ApplyDoesNotAffectIndexes) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("b");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -321,7 +320,7 @@ TEST_F(ArithmeticNodeTest, IncTypePromotionIsNotANoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: NumberInt(2)}"));
+ mutablebson::Document doc(fromjson("{a: NumberInt(2)}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -337,7 +336,7 @@ TEST_F(ArithmeticNodeTest, MulTypePromotionIsNotANoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kMultiply);
ASSERT_OK(node.init(update["$mul"]["a"], collator));
- Document doc(fromjson("{a: NumberInt(2)}"));
+ mutablebson::Document doc(fromjson("{a: NumberInt(2)}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -353,7 +352,7 @@ TEST_F(ArithmeticNodeTest, TypePromotionFromIntToDecimalIsNotANoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: NumberInt(5)}"));
+ mutablebson::Document doc(fromjson("{a: NumberInt(5)}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -370,7 +369,7 @@ TEST_F(ArithmeticNodeTest, TypePromotionFromLongToDecimalIsNotANoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: NumberLong(5)}"));
+ mutablebson::Document doc(fromjson("{a: NumberLong(5)}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -387,7 +386,7 @@ TEST_F(ArithmeticNodeTest, TypePromotionFromDoubleToDecimalIsNotANoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: 5.25}"));
+ mutablebson::Document doc(fromjson("{a: 5.25}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -404,7 +403,7 @@ TEST_F(ArithmeticNodeTest, ApplyPromoteToFloatingPoint) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: NumberLong(1)}"));
+ mutablebson::Document doc(fromjson("{a: NumberLong(1)}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -420,7 +419,7 @@ TEST_F(ArithmeticNodeTest, IncrementedDecimalStaysDecimal) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: NumberDecimal(\"6.25\")}"));
+ mutablebson::Document doc(fromjson("{a: NumberDecimal(\"6.25\")}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -438,7 +437,7 @@ TEST_F(ArithmeticNodeTest, OverflowIntToLong) {
ASSERT_OK(node.init(update["$inc"]["a"], collator));
const int initialValue = std::numeric_limits<int>::max();
- Document doc(BSON("a" << initialValue));
+ mutablebson::Document doc(BSON("a" << initialValue));
ASSERT_EQUALS(mongo::NumberInt, doc.root()["a"].getType());
setPathTaken("a");
addIndexedPath("a");
@@ -457,7 +456,7 @@ TEST_F(ArithmeticNodeTest, UnderflowIntToLong) {
ASSERT_OK(node.init(update["$inc"]["a"], collator));
const int initialValue = std::numeric_limits<int>::min();
- Document doc(BSON("a" << initialValue));
+ mutablebson::Document doc(BSON("a" << initialValue));
ASSERT_EQUALS(mongo::NumberInt, doc.root()["a"].getType());
setPathTaken("a");
addIndexedPath("a");
@@ -475,8 +474,8 @@ TEST_F(ArithmeticNodeTest, IncModeCanBeReused) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc1(fromjson("{a: 1}"));
- Document doc2(fromjson("{a: 2}"));
+ mutablebson::Document doc1(fromjson("{a: 1}"));
+ mutablebson::Document doc2(fromjson("{a: 2}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc1.root()["a"]));
@@ -501,7 +500,7 @@ TEST_F(ArithmeticNodeTest, CreatedNumberHasSameTypeAsInc) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{b: 6}"));
+ mutablebson::Document doc(fromjson("{b: 6}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -517,7 +516,7 @@ TEST_F(ArithmeticNodeTest, CreatedNumberHasSameTypeAsMul) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kMultiply);
ASSERT_OK(node.init(update["$mul"]["a"], collator));
- Document doc(fromjson("{b: 6}"));
+ mutablebson::Document doc(fromjson("{b: 6}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -533,7 +532,7 @@ TEST_F(ArithmeticNodeTest, ApplyEmptyDocument) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -549,7 +548,7 @@ TEST_F(ArithmeticNodeTest, ApplyIncToObjectFails) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{_id: 'test_object', a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{_id: 'test_object', a: {b: 1}}"));
setPathTaken("a");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -565,7 +564,7 @@ TEST_F(ArithmeticNodeTest, ApplyIncToArrayFails) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{_id: 'test_object', a: []}"));
+ mutablebson::Document doc(fromjson("{_id: 'test_object', a: []}"));
setPathTaken("a");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -581,7 +580,7 @@ TEST_F(ArithmeticNodeTest, ApplyIncToStringFails) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{_id: 'test_object', a: \"foo\"}"));
+ mutablebson::Document doc(fromjson("{_id: 'test_object', a: \"foo\"}"));
setPathTaken("a");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -597,7 +596,7 @@ TEST_F(ArithmeticNodeTest, ApplyNewPath) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{b: 1}"));
+ mutablebson::Document doc(fromjson("{b: 1}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -613,7 +612,7 @@ TEST_F(ArithmeticNodeTest, ApplyEmptyIndexData) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
node.apply(getApplyParams(doc.root()["a"]));
ASSERT_EQUALS(fromjson("{a: 3}"), doc);
@@ -628,7 +627,7 @@ TEST_F(ArithmeticNodeTest, ApplyNoOpDottedPath) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -644,7 +643,7 @@ TEST_F(ArithmeticNodeTest, TypePromotionOnDottedPathIsNotANoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{a: {b: NumberInt(2)}}"));
+ mutablebson::Document doc(fromjson("{a: {b: NumberInt(2)}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -660,7 +659,7 @@ TEST_F(ArithmeticNodeTest, ApplyPathNotViableArray) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{a:[{b:1}]}"));
+ mutablebson::Document doc(fromjson("{a:[{b:1}]}"));
setPathToCreate("b");
setPathTaken("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -675,7 +674,7 @@ TEST_F(ArithmeticNodeTest, ApplyInPlaceDottedPath) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 1}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -691,7 +690,7 @@ TEST_F(ArithmeticNodeTest, ApplyPromotionDottedPath) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{a: {b: NumberInt(3)}}"));
+ mutablebson::Document doc(fromjson("{a: {b: NumberInt(3)}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -707,7 +706,7 @@ TEST_F(ArithmeticNodeTest, ApplyDottedPathEmptyDoc) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()));
@@ -723,7 +722,7 @@ TEST_F(ArithmeticNodeTest, ApplyFieldWithDot) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.b"], collator));
- Document doc(fromjson("{'a.b':4}"));
+ mutablebson::Document doc(fromjson("{'a.b':4}"));
setPathToCreate("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()));
@@ -739,7 +738,7 @@ TEST_F(ArithmeticNodeTest, ApplyNoOpArrayIndex) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 2}]}"));
setPathTaken("a.2.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["2"]["b"]));
@@ -755,7 +754,8 @@ TEST_F(ArithmeticNodeTest, TypePromotionInArrayIsNotANoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: NumberInt(0)},{b: NumberInt(1)},{b: NumberInt(2)}]}"));
+ mutablebson::Document doc(
+ fromjson("{a: [{b: NumberInt(0)},{b: NumberInt(1)},{b: NumberInt(2)}]}"));
setPathTaken("a.2.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["2"]["b"]));
@@ -771,7 +771,7 @@ TEST_F(ArithmeticNodeTest, ApplyNonViablePathThroughArray) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathToCreate("2.b");
setPathTaken("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -786,7 +786,7 @@ TEST_F(ArithmeticNodeTest, ApplyInPlaceArrayIndex) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 1}]}"));
setPathTaken("a.2.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["2"]["b"]));
@@ -802,7 +802,7 @@ TEST_F(ArithmeticNodeTest, ApplyAppendArray) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0},{b: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0},{b: 1}]}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a");
@@ -819,7 +819,7 @@ TEST_F(ArithmeticNodeTest, ApplyPaddingArray) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0}]}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a");
@@ -836,7 +836,7 @@ TEST_F(ArithmeticNodeTest, ApplyNumericObject) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: {b: 0}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 0}}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a");
@@ -853,7 +853,7 @@ TEST_F(ArithmeticNodeTest, ApplyNumericField) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: {'2': {b: 1}}}"));
+ mutablebson::Document doc(fromjson("{a: {'2': {b: 1}}}"));
setPathTaken("a.2.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["2"]["b"]));
@@ -869,7 +869,7 @@ TEST_F(ArithmeticNodeTest, ApplyExtendNumericField) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: {'2': {c: 1}}}"));
+ mutablebson::Document doc(fromjson("{a: {'2': {c: 1}}}"));
setPathToCreate("b");
setPathTaken("a.2");
addIndexedPath("a");
@@ -886,7 +886,7 @@ TEST_F(ArithmeticNodeTest, ApplyNumericFieldToEmptyObject) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: {}}"));
+ mutablebson::Document doc(fromjson("{a: {}}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a");
@@ -903,7 +903,7 @@ TEST_F(ArithmeticNodeTest, ApplyEmptyArray) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a");
@@ -920,7 +920,7 @@ TEST_F(ArithmeticNodeTest, ApplyLogDottedPath) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b:0}, {b:1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b:0}, {b:1}]}"));
setPathToCreate("2.b");
setPathTaken("a");
node.apply(getApplyParams(doc.root()["a"]));
@@ -936,7 +936,7 @@ TEST_F(ArithmeticNodeTest, LogEmptyArray) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathToCreate("2.b");
setPathTaken("a");
node.apply(getApplyParams(doc.root()["a"]));
@@ -952,7 +952,7 @@ TEST_F(ArithmeticNodeTest, LogEmptyObject) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kAdd);
ASSERT_OK(node.init(update["$inc"]["a.2.b"], collator));
- Document doc(fromjson("{a: {}}"));
+ mutablebson::Document doc(fromjson("{a: {}}"));
setPathToCreate("2.b");
setPathTaken("a");
node.apply(getApplyParams(doc.root()["a"]));
@@ -968,7 +968,7 @@ TEST_F(ArithmeticNodeTest, ApplyDeserializedDocNotNoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kMultiply);
ASSERT_OK(node.init(update["$mul"]["b"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
// De-serialize the int.
doc.root()["a"].setValueInt(1).transitional_ignore();
@@ -987,7 +987,7 @@ TEST_F(ArithmeticNodeTest, ApplyToDeserializedDocNoOp) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kMultiply);
ASSERT_OK(node.init(update["$mul"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
// De-serialize the int.
doc.root()["a"].setValueInt(2).transitional_ignore();
@@ -1006,7 +1006,7 @@ TEST_F(ArithmeticNodeTest, ApplyToDeserializedDocNestedNoop) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kMultiply);
ASSERT_OK(node.init(update["$mul"]["a.b"], collator));
- Document doc{BSONObj()};
+ mutablebson::Document doc{BSONObj()};
// De-serialize the int.
doc.root().appendObject("a", BSON("b" << static_cast<int>(1))).transitional_ignore();
@@ -1025,7 +1025,7 @@ TEST_F(ArithmeticNodeTest, ApplyToDeserializedDocNestedNotNoop) {
ArithmeticNode node(ArithmeticNode::ArithmeticOp::kMultiply);
ASSERT_OK(node.init(update["$mul"]["a.b"], collator));
- Document doc{BSONObj()};
+ mutablebson::Document doc{BSONObj()};
// De-serialize the int.
doc.root().appendObject("a", BSON("b" << static_cast<int>(1))).transitional_ignore();
diff --git a/src/mongo/db/update/bit_node_test.cpp b/src/mongo/db/update/bit_node_test.cpp
index 54db7ccdafb..868d064f66b 100644
--- a/src/mongo/db/update/bit_node_test.cpp
+++ b/src/mongo/db/update/bit_node_test.cpp
@@ -41,7 +41,6 @@ namespace mongo {
namespace {
using BitNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -156,7 +155,7 @@ TEST_F(BitNodeTest, ApplyAndLogEmptyDocumentAnd) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
@@ -171,7 +170,7 @@ TEST_F(BitNodeTest, ApplyAndLogEmptyDocumentOr) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
@@ -186,7 +185,7 @@ TEST_F(BitNodeTest, ApplyAndLogEmptyDocumentXor) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
@@ -201,7 +200,7 @@ TEST_F(BitNodeTest, ApplyAndLogSimpleDocumentAnd) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(BSON("a" << 0b0101));
+ mutablebson::Document doc(BSON("a" << 0b0101));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_FALSE(result.noop);
@@ -216,7 +215,7 @@ TEST_F(BitNodeTest, ApplyAndLogSimpleDocumentOr) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(BSON("a" << 0b0101));
+ mutablebson::Document doc(BSON("a" << 0b0101));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_FALSE(result.noop);
@@ -231,7 +230,7 @@ TEST_F(BitNodeTest, ApplyAndLogSimpleDocumentXor) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(BSON("a" << 0b0101));
+ mutablebson::Document doc(BSON("a" << 0b0101));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_FALSE(result.noop);
@@ -246,7 +245,7 @@ TEST_F(BitNodeTest, ApplyShouldReportNoOp) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(BSON("a" << 1));
+ mutablebson::Document doc(BSON("a" << 1));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_TRUE(result.noop);
@@ -266,7 +265,7 @@ TEST_F(BitNodeTest, ApplyMultipleBitOps) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(BSON("a" << 0b1111111100000000));
+ mutablebson::Document doc(BSON("a" << 0b1111111100000000));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_FALSE(result.noop);
@@ -281,7 +280,7 @@ TEST_F(BitNodeTest, ApplyRepeatedBitOps) {
BitNode node;
ASSERT_OK(node.init(update["$bit"]["a"], collator));
- Document doc(BSON("a" << 0b11110000));
+ mutablebson::Document doc(BSON("a" << 0b11110000));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_FALSE(result.noop);
diff --git a/src/mongo/db/update/compare_node_test.cpp b/src/mongo/db/update/compare_node_test.cpp
index d69ac1c5d8b..37949aef2dc 100644
--- a/src/mongo/db/update/compare_node_test.cpp
+++ b/src/mongo/db/update/compare_node_test.cpp
@@ -42,7 +42,6 @@ namespace mongo {
namespace {
using CompareNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -59,7 +58,7 @@ TEST_F(CompareNodeTest, ApplyMaxSameNumber) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -76,7 +75,7 @@ TEST_F(CompareNodeTest, ApplyMinSameNumber) {
CompareNode node(CompareNode::CompareMode::kMin);
ASSERT_OK(node.init(update["$min"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -93,7 +92,7 @@ TEST_F(CompareNodeTest, ApplyMaxNumberIsLess) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -110,7 +109,7 @@ TEST_F(CompareNodeTest, ApplyMinNumberIsMore) {
CompareNode node(CompareNode::CompareMode::kMin);
ASSERT_OK(node.init(update["$min"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -127,7 +126,7 @@ TEST_F(CompareNodeTest, ApplyMaxSameValInt) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: 1.0}"));
+ mutablebson::Document doc(fromjson("{a: 1.0}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -144,7 +143,7 @@ TEST_F(CompareNodeTest, ApplyMaxSameValIntZero) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: 0.0}"));
+ mutablebson::Document doc(fromjson("{a: 0.0}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -161,7 +160,7 @@ TEST_F(CompareNodeTest, ApplyMinSameValIntZero) {
CompareNode node(CompareNode::CompareMode::kMin);
ASSERT_OK(node.init(update["$min"]["a"], collator));
- Document doc(fromjson("{a: 0.0}"));
+ mutablebson::Document doc(fromjson("{a: 0.0}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -178,7 +177,7 @@ TEST_F(CompareNodeTest, ApplyMissingFieldMinNumber) {
CompareNode node(CompareNode::CompareMode::kMin);
ASSERT_OK(node.init(update["$min"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -195,7 +194,7 @@ TEST_F(CompareNodeTest, ApplyExistingNumberMinNumber) {
CompareNode node(CompareNode::CompareMode::kMin);
ASSERT_OK(node.init(update["$min"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -212,7 +211,7 @@ TEST_F(CompareNodeTest, ApplyMissingFieldMaxNumber) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -229,7 +228,7 @@ TEST_F(CompareNodeTest, ApplyExistingNumberMaxNumber) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -246,7 +245,7 @@ TEST_F(CompareNodeTest, ApplyExistingDateMaxDate) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: {$date: 0}}"));
+ mutablebson::Document doc(fromjson("{a: {$date: 0}}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -263,7 +262,7 @@ TEST_F(CompareNodeTest, ApplyExistingEmbeddedDocMaxDoc) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -280,7 +279,7 @@ TEST_F(CompareNodeTest, ApplyExistingEmbeddedDocMaxNumber) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -297,7 +296,7 @@ TEST_F(CompareNodeTest, ApplyMinRespectsCollation) {
CompareNode node(CompareNode::CompareMode::kMin);
ASSERT_OK(node.init(update["$min"]["a"], &collator));
- Document doc(fromjson("{a: 'cbc'}"));
+ mutablebson::Document doc(fromjson("{a: 'cbc'}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -318,7 +317,7 @@ TEST_F(CompareNodeTest, ApplyMinRespectsCollationFromSetCollator) {
CollatorInterfaceMock::MockType::kReverseString);
node.setCollator(&reverseStringCollator);
- Document doc(fromjson("{a: 'cbc'}"));
+ mutablebson::Document doc(fromjson("{a: 'cbc'}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -339,7 +338,7 @@ TEST_F(CompareNodeTest, ApplyMaxRespectsCollationFromSetCollator) {
CollatorInterfaceMock::MockType::kReverseString);
node.setCollator(&reverseStringCollator);
- Document doc(fromjson("{a: 'cbc'}"));
+ mutablebson::Document doc(fromjson("{a: 'cbc'}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -377,7 +376,7 @@ TEST_F(CompareNodeTest, ApplyIndexesNotAffected) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathTaken("a");
addIndexedPath("b");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -394,7 +393,7 @@ TEST_F(CompareNodeTest, ApplyNoIndexDataOrLogBuilder) {
CompareNode node(CompareNode::CompareMode::kMax);
ASSERT_OK(node.init(update["$max"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
diff --git a/src/mongo/db/update/current_date_node_test.cpp b/src/mongo/db/update/current_date_node_test.cpp
index 7a5005b83d8..689ada219f6 100644
--- a/src/mongo/db/update/current_date_node_test.cpp
+++ b/src/mongo/db/update/current_date_node_test.cpp
@@ -41,7 +41,6 @@ namespace mongo {
namespace {
using CurrentDateNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -128,7 +127,7 @@ TEST_F(CurrentDateNodeTest, ApplyTrue) {
CurrentDateNode node;
ASSERT_OK(node.init(update["$currentDate"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -152,7 +151,7 @@ TEST_F(CurrentDateNodeTest, ApplyFalse) {
CurrentDateNode node;
ASSERT_OK(node.init(update["$currentDate"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -176,7 +175,7 @@ TEST_F(CurrentDateNodeTest, ApplyDate) {
CurrentDateNode node;
ASSERT_OK(node.init(update["$currentDate"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -200,7 +199,7 @@ TEST_F(CurrentDateNodeTest, ApplyTimestamp) {
CurrentDateNode node;
ASSERT_OK(node.init(update["$currentDate"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -224,7 +223,7 @@ TEST_F(CurrentDateNodeTest, ApplyFieldDoesNotExist) {
CurrentDateNode node;
ASSERT_OK(node.init(update["$currentDate"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -248,7 +247,7 @@ TEST_F(CurrentDateNodeTest, ApplyIndexesNotAffected) {
CurrentDateNode node;
ASSERT_OK(node.init(update["$currentDate"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathTaken("a");
addIndexedPath("b");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -272,7 +271,7 @@ TEST_F(CurrentDateNodeTest, ApplyNoIndexDataOrLogBuilder) {
CurrentDateNode node;
ASSERT_OK(node.init(update["$currentDate"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
diff --git a/src/mongo/db/update/log_builder.cpp b/src/mongo/db/update/log_builder.cpp
index deddbab3840..173c8afb3f9 100644
--- a/src/mongo/db/update/log_builder.cpp
+++ b/src/mongo/db/update/log_builder.cpp
@@ -31,7 +31,6 @@
namespace mongo {
-using mutablebson::Document;
using mutablebson::Element;
namespace str = mongoutils::str;
@@ -49,7 +48,7 @@ inline Status LogBuilder::addToSection(Element newElt, Element* section, const c
"LogBuilder: Invalid attempt to add a $set/$unset entry"
"to a log with an existing object replacement");
- Document& doc = _logRoot.getDocument();
+ mutablebson::Document& doc = _logRoot.getDocument();
// We should not already have an element with the section name under the root.
dassert(_logRoot[sectionName] == doc.end());
diff --git a/src/mongo/db/update/object_replace_node_test.cpp b/src/mongo/db/update/object_replace_node_test.cpp
index 69c3bbf6070..645a3e69ff3 100644
--- a/src/mongo/db/update/object_replace_node_test.cpp
+++ b/src/mongo/db/update/object_replace_node_test.cpp
@@ -42,7 +42,6 @@ namespace mongo {
namespace {
using ObjectReplaceNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -50,7 +49,7 @@ TEST_F(ObjectReplaceNodeTest, Noop) {
auto obj = fromjson("{a: 1, b: 2}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{a: 1, b: 2}"));
+ mutablebson::Document doc(fromjson("{a: 1, b: 2}"));
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.noop);
ASSERT_FALSE(result.indexesAffected);
@@ -63,7 +62,7 @@ TEST_F(ObjectReplaceNodeTest, ShouldNotCreateIdIfNoIdExistsAndNoneIsSpecified) {
auto obj = fromjson("{a: 1, b: 2}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{c: 1, d: 2}"));
+ mutablebson::Document doc(fromjson("{c: 1, d: 2}"));
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
ASSERT_TRUE(result.indexesAffected);
@@ -76,7 +75,7 @@ TEST_F(ObjectReplaceNodeTest, ShouldPreserveIdOfExistingDocumentIfIdNotSpecified
auto obj = fromjson("{a: 1, b: 2}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{_id: 0, c: 1, d: 2}"));
+ mutablebson::Document doc(fromjson("{_id: 0, c: 1, d: 2}"));
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
ASSERT_TRUE(result.indexesAffected);
@@ -89,7 +88,7 @@ TEST_F(ObjectReplaceNodeTest, ShouldSucceedWhenImmutableIdIsNotModified) {
auto obj = fromjson("{_id: 0, a: 1, b: 2}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{_id: 0, c: 1, d: 2}"));
+ mutablebson::Document doc(fromjson("{_id: 0, c: 1, d: 2}"));
addImmutablePath("_id");
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
@@ -103,7 +102,7 @@ TEST_F(ObjectReplaceNodeTest, IdTimestampNotModified) {
auto obj = fromjson("{_id: Timestamp(0,0)}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
ASSERT_TRUE(result.indexesAffected);
@@ -116,7 +115,7 @@ TEST_F(ObjectReplaceNodeTest, NonIdTimestampsModified) {
auto obj = fromjson("{a: Timestamp(0,0), b: Timestamp(0,0)}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
ASSERT_TRUE(result.indexesAffected);
@@ -143,7 +142,7 @@ TEST_F(ObjectReplaceNodeTest, ComplexDoc) {
auto obj = fromjson("{a: 1, b: [0, 1, 2], c: {d: 1}}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{a: 1, b: [0, 2, 2], e: []}"));
+ mutablebson::Document doc(fromjson("{a: 1, b: [0, 2, 2], e: []}"));
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
ASSERT_TRUE(result.indexesAffected);
@@ -156,7 +155,7 @@ TEST_F(ObjectReplaceNodeTest, CannotRemoveImmutablePath) {
auto obj = fromjson("{_id: 0, c: 1}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{_id: 0, a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{_id: 0, a: {b: 1}}"));
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root())),
UserException,
@@ -169,7 +168,7 @@ TEST_F(ObjectReplaceNodeTest, IdFieldIsNotRemoved) {
auto obj = fromjson("{a: 1}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{_id: 0, b: 1}"));
+ mutablebson::Document doc(fromjson("{_id: 0, b: 1}"));
addImmutablePath("_id");
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
@@ -183,7 +182,7 @@ TEST_F(ObjectReplaceNodeTest, CannotReplaceImmutablePathWithArrayField) {
auto obj = fromjson("{_id: 0, a: [{b: 1}]}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{_id: 0, a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{_id: 0, a: {b: 1}}"));
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root())),
UserException,
@@ -196,7 +195,7 @@ TEST_F(ObjectReplaceNodeTest, CannotMakeImmutablePathArrayDescendant) {
auto obj = fromjson("{_id: 0, a: [1]}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{_id: 0, a: {'0': 1}}"));
+ mutablebson::Document doc(fromjson("{_id: 0, a: {'0': 1}}"));
addImmutablePath("a.0");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root())),
UserException,
@@ -209,7 +208,7 @@ TEST_F(ObjectReplaceNodeTest, CannotModifyImmutablePath) {
auto obj = fromjson("{_id: 0, a: {b: 2}}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{_id: 0, a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{_id: 0, a: {b: 1}}"));
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root())),
UserException,
@@ -222,7 +221,7 @@ TEST_F(ObjectReplaceNodeTest, CannotModifyImmutableId) {
auto obj = fromjson("{_id: 1}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{_id: 0}"));
+ mutablebson::Document doc(fromjson("{_id: 0}"));
addImmutablePath("_id");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root())),
UserException,
@@ -235,7 +234,7 @@ TEST_F(ObjectReplaceNodeTest, CanAddImmutableField) {
auto obj = fromjson("{a: {b: 1}}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{c: 1}"));
+ mutablebson::Document doc(fromjson("{c: 1}"));
addImmutablePath("a.b");
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
@@ -249,7 +248,7 @@ TEST_F(ObjectReplaceNodeTest, CanAddImmutableId) {
auto obj = fromjson("{_id: 0}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{c: 1}"));
+ mutablebson::Document doc(fromjson("{c: 1}"));
addImmutablePath("_id");
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
@@ -263,7 +262,7 @@ TEST_F(ObjectReplaceNodeTest, CannotCreateDollarPrefixedNameWhenValidateForStora
auto obj = fromjson("{a: {b: 1, $bad: 1}}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
ASSERT_THROWS_CODE_AND_WHAT(
node.apply(getApplyParams(doc.root())),
UserException,
@@ -275,7 +274,7 @@ TEST_F(ObjectReplaceNodeTest, CanCreateDollarPrefixedNameWhenValidateForStorageI
auto obj = fromjson("{a: {b: 1, $bad: 1}}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setValidateForStorage(false);
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
@@ -289,7 +288,7 @@ TEST_F(ObjectReplaceNodeTest, NoLogBuilder) {
auto obj = fromjson("{a: 1}");
ObjectReplaceNode node(obj);
- Document doc(fromjson("{b: 1}"));
+ mutablebson::Document doc(fromjson("{b: 1}"));
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.noop);
diff --git a/src/mongo/db/update/path_support_test.cpp b/src/mongo/db/update/path_support_test.cpp
index 4a915bdf7d5..339781699e1 100644
--- a/src/mongo/db/update/path_support_test.cpp
+++ b/src/mongo/db/update/path_support_test.cpp
@@ -56,9 +56,9 @@
namespace {
using namespace mongo;
-using namespace mutablebson;
using namespace pathsupport;
using mongoutils::str::stream;
+using mutablebson::Element;
using std::unique_ptr;
using std::string;
@@ -66,7 +66,7 @@ class EmptyDoc : public mongo::unittest::Test {
public:
EmptyDoc() : _doc() {}
- Document& doc() {
+ mutablebson::Document& doc() {
return _doc;
}
@@ -83,7 +83,7 @@ public:
}
private:
- Document _doc;
+ mutablebson::Document _doc;
FieldRef _field;
};
@@ -137,7 +137,7 @@ public:
ASSERT_OK(root().appendInt("a", 1));
}
- Document& doc() {
+ mutablebson::Document& doc() {
return _doc;
}
@@ -153,7 +153,7 @@ public:
}
private:
- Document _doc;
+ mutablebson::Document _doc;
FieldRef _field;
};
@@ -248,7 +248,7 @@ public:
ASSERT_OK(root().pushBack(elemA));
}
- Document& doc() {
+ mutablebson::Document& doc() {
return _doc;
}
@@ -264,7 +264,7 @@ public:
}
private:
- Document _doc;
+ mutablebson::Document _doc;
FieldRef _field;
};
@@ -363,7 +363,7 @@ public:
ASSERT_OK(root().pushBack(elemB));
}
- Document& doc() {
+ mutablebson::Document& doc() {
return _doc;
}
@@ -380,7 +380,7 @@ public:
}
private:
- Document _doc;
+ mutablebson::Document _doc;
FieldRef _field;
};
diff --git a/src/mongo/db/update/pull_node_test.cpp b/src/mongo/db/update/pull_node_test.cpp
index f158b1c0678..9d3c101fba9 100644
--- a/src/mongo/db/update/pull_node_test.cpp
+++ b/src/mongo/db/update/pull_node_test.cpp
@@ -42,7 +42,6 @@ namespace mongo {
namespace {
using PullNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -70,7 +69,7 @@ TEST_F(PullNodeTest, TargetNotFound) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -87,7 +86,7 @@ TEST_F(PullNodeTest, ApplyToStringFails) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: 'foo'}"));
+ mutablebson::Document doc(fromjson("{a: 'foo'}"));
setPathTaken("a");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -102,7 +101,7 @@ TEST_F(PullNodeTest, ApplyToObjectFails) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: {foo: 'bar'}}"));
+ mutablebson::Document doc(fromjson("{a: {foo: 'bar'}}"));
setPathTaken("a");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -117,7 +116,7 @@ TEST_F(PullNodeTest, ApplyToNonViablePathFails) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a.b"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a");
@@ -134,7 +133,7 @@ TEST_F(PullNodeTest, ApplyToMissingElement) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a.b.c.d"], collator));
- Document doc(fromjson("{a: {b: {c: {}}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: {}}}}"));
setPathToCreate("d");
setPathTaken("a.b.c");
addIndexedPath("a");
@@ -152,7 +151,7 @@ TEST_F(PullNodeTest, ApplyToEmptyArray) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -169,7 +168,7 @@ TEST_F(PullNodeTest, ApplyToArrayMatchingNone) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: [2, 3, 4, 5]}"));
+ mutablebson::Document doc(fromjson("{a: [2, 3, 4, 5]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -186,7 +185,7 @@ TEST_F(PullNodeTest, ApplyToArrayMatchingOne) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: [0, 1, 2, 3]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2, 3]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -203,7 +202,7 @@ TEST_F(PullNodeTest, ApplyToArrayMatchingSeveral) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: [0, 1, 0, 2, 0, 3, 0, 4, 0, 5]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 0, 2, 0, 3, 0, 4, 0, 5]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -220,7 +219,7 @@ TEST_F(PullNodeTest, ApplyToArrayMatchingAll) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: [0, -1, -2, -3, -4, -5]}"));
+ mutablebson::Document doc(fromjson("{a: [0, -1, -2, -3, -4, -5]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -237,7 +236,7 @@ TEST_F(PullNodeTest, ApplyNoIndexDataNoLogBuilder) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: [0, 1, 2, 3]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2, 3]}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -255,7 +254,7 @@ TEST_F(PullNodeTest, ApplyWithCollation) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], &collator));
- Document doc(fromjson("{a: ['zaa', 'zcc', 'zbb', 'zee']}"));
+ mutablebson::Document doc(fromjson("{a: ['zaa', 'zcc', 'zbb', 'zee']}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -272,7 +271,7 @@ TEST_F(PullNodeTest, ApplyWithCollationDoesNotAffectNonStringMatches) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], &collator));
- Document doc(fromjson("{a: [2, 1, 0, -1, -2, -3]}"));
+ mutablebson::Document doc(fromjson("{a: [2, 1, 0, -1, -2, -3]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -289,7 +288,7 @@ TEST_F(PullNodeTest, ApplyWithCollationDoesNotAffectRegexMatches) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], &collator));
- Document doc(fromjson("{a: ['b', 'a', 'aab', 'cb', 'bba']}"));
+ mutablebson::Document doc(fromjson("{a: ['b', 'a', 'aab', 'cb', 'bba']}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -306,7 +305,7 @@ TEST_F(PullNodeTest, ApplyStringLiteralMatchWithCollation) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], &collator));
- Document doc(fromjson("{a: ['b', 'a', 'aab', 'cb', 'bba']}"));
+ mutablebson::Document doc(fromjson("{a: ['b', 'a', 'aab', 'cb', 'bba']}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -323,7 +322,7 @@ TEST_F(PullNodeTest, ApplyCollationDoesNotAffectNumberLiteralMatches) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], &collator));
- Document doc(fromjson("{a: ['a', 99, 'b', 2, 'c', 99, 'd']}"));
+ mutablebson::Document doc(fromjson("{a: ['a', 99, 'b', 2, 'c', 99, 'd']}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -341,7 +340,7 @@ TEST_F(PullNodeTest, ApplyStringMatchAfterSetCollator) {
ASSERT_OK(node.init(update["$pull"]["a"], collator));
// First without a collator.
- Document doc(fromjson("{ a : ['a', 'b', 'c', 'd'] }"));
+ mutablebson::Document doc(fromjson("{ a : ['a', 'b', 'c', 'd'] }"));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_FALSE(result.noop);
@@ -352,7 +351,7 @@ TEST_F(PullNodeTest, ApplyStringMatchAfterSetCollator) {
// Now with a collator.
CollatorInterfaceMock mockCollator(CollatorInterfaceMock::MockType::kAlwaysEqual);
node.setCollator(&mockCollator);
- Document doc2(fromjson("{ a : ['a', 'b', 'c', 'd'] }"));
+ mutablebson::Document doc2(fromjson("{ a : ['a', 'b', 'c', 'd'] }"));
resetApplyParams();
setPathTaken("a");
result = node.apply(getApplyParams(doc2.root()["a"]));
@@ -374,7 +373,7 @@ TEST_F(PullNodeTest, SetCollatorDoesNotAffectClone) {
node.setCollator(&mockCollator);
// The original node should now have collation.
- Document doc(fromjson("{ a : ['a', 'b', 'c', 'd'] }"));
+ mutablebson::Document doc(fromjson("{ a : ['a', 'b', 'c', 'd'] }"));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_FALSE(result.noop);
@@ -383,7 +382,7 @@ TEST_F(PullNodeTest, SetCollatorDoesNotAffectClone) {
ASSERT_FALSE(doc.isInPlaceModeEnabled());
// The clone should have exact string matches (no collation).
- Document doc2(fromjson("{ a : ['a', 'b', 'c', 'd'] }"));
+ mutablebson::Document doc2(fromjson("{ a : ['a', 'b', 'c', 'd'] }"));
resetApplyParams();
setPathTaken("a");
result = cloneNode->apply(getApplyParams(doc2.root()["a"]));
@@ -403,7 +402,7 @@ TEST_F(PullNodeTest, ApplyComplexDocAndMatching1) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a.b"], collator));
- Document doc(fromjson("{a: {b: [{x: 1}, {y: 'y'}, {x: 2}, {z: 'z'}]}}"));
+ mutablebson::Document doc(fromjson("{a: {b: [{x: 1}, {y: 'y'}, {x: 2}, {z: 'z'}]}}"));
setPathTaken("a.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -420,7 +419,7 @@ TEST_F(PullNodeTest, ApplyComplexDocAndMatching2) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a.b"], collator));
- Document doc(fromjson("{a: {b: [{x: 1}, {y: 'y'}, {x: 2}, {z: 'z'}]}}"));
+ mutablebson::Document doc(fromjson("{a: {b: [{x: 1}, {y: 'y'}, {x: 2}, {z: 'z'}]}}"));
setPathTaken("a.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -437,7 +436,7 @@ TEST_F(PullNodeTest, ApplyComplexDocAndMatching3) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a.b"], collator));
- Document doc(fromjson("{a: {b: [{x: 1}, {y: 'y'}, {x: 2}, {z: 'z'}]}}"));
+ mutablebson::Document doc(fromjson("{a: {b: [{x: 1}, {y: 'y'}, {x: 2}, {z: 'z'}]}}"));
setPathTaken("a.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -454,7 +453,8 @@ TEST_F(PullNodeTest, ApplyFullPredicateWithCollation) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a.b"], &collator));
- Document doc(fromjson("{a: {b: [{x: 'foo', y: 1}, {x: 'bar', y: 2}, {x: 'baz', y: 3}]}}"));
+ mutablebson::Document doc(
+ fromjson("{a: {b: [{x: 'foo', y: 1}, {x: 'bar', y: 2}, {x: 'baz', y: 3}]}}"));
setPathTaken("a.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -471,7 +471,7 @@ TEST_F(PullNodeTest, ApplyScalarValueMod) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: [1, 2, 1, 2, 1, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 2, 1, 2, 1, 2]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -488,7 +488,7 @@ TEST_F(PullNodeTest, ApplyObjectValueMod) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: [{x: 1}, {y: 2}, {x: 1}, {y: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [{x: 1}, {y: 2}, {x: 1}, {y: 2}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -505,7 +505,8 @@ TEST_F(PullNodeTest, DocumentationExample1) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["flags"], collator));
- Document doc(fromjson("{flags: ['vme', 'de', 'pse', 'tsc', 'msr', 'pae', 'mce']}"));
+ mutablebson::Document doc(
+ fromjson("{flags: ['vme', 'de', 'pse', 'tsc', 'msr', 'pae', 'mce']}"));
setPathTaken("flags");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["flags"]));
@@ -523,7 +524,7 @@ TEST_F(PullNodeTest, DocumentationExample2a) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["votes"], collator));
- Document doc(fromjson("{votes: [3, 5, 6, 7, 7, 8]}"));
+ mutablebson::Document doc(fromjson("{votes: [3, 5, 6, 7, 7, 8]}"));
setPathTaken("votes");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["votes"]));
@@ -540,7 +541,7 @@ TEST_F(PullNodeTest, DocumentationExample2b) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["votes"], collator));
- Document doc(fromjson("{votes: [3, 5, 6, 7, 7, 8]}"));
+ mutablebson::Document doc(fromjson("{votes: [3, 5, 6, 7, 7, 8]}"));
setPathTaken("votes");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["votes"]));
@@ -557,7 +558,7 @@ TEST_F(PullNodeTest, ApplyPullWithObjectValueToArrayWithNonObjectValue) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["a"], collator));
- Document doc(fromjson("{a: [{x: 1}, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [{x: 1}, 2]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -574,7 +575,7 @@ TEST_F(PullNodeTest, CannotModifyImmutableField) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["_id.a"], collator));
- Document doc(fromjson("{_id: {a: [0, 1, 2]}}"));
+ mutablebson::Document doc(fromjson("{_id: {a: [0, 1, 2]}}"));
setPathTaken("_id.a");
addImmutablePath("_id");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -590,7 +591,7 @@ TEST_F(PullNodeTest, SERVER_3988) {
PullNode node;
ASSERT_OK(node.init(update["$pull"]["y"], collator));
- Document doc(fromjson("{x: 1, y: [2, 3, 4, 'abc', 'xyz']}"));
+ mutablebson::Document doc(fromjson("{x: 1, y: [2, 3, 4, 'abc', 'xyz']}"));
setPathTaken("y");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["y"]));
diff --git a/src/mongo/db/update/pullall_node_test.cpp b/src/mongo/db/update/pullall_node_test.cpp
index 1928b5f6223..4af970eb306 100644
--- a/src/mongo/db/update/pullall_node_test.cpp
+++ b/src/mongo/db/update/pullall_node_test.cpp
@@ -42,7 +42,6 @@ namespace mongo {
namespace {
using PullAllNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -88,7 +87,7 @@ TEST_F(PullAllNodeTest, TargetNotFound) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["b"], collator));
- Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
setPathToCreate("b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -105,7 +104,7 @@ TEST_F(PullAllNodeTest, TargetArrayElementNotFound) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a.2"], collator));
- Document doc(fromjson("{a: [1, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 2]}"));
setPathToCreate("2");
setPathTaken("a");
addIndexedPath("a");
@@ -123,7 +122,7 @@ TEST_F(PullAllNodeTest, ApplyToNonArrayFails) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a.0"], collator));
- Document doc(fromjson("{a: [1, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 2]}"));
setPathTaken("a.0");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"][0])),
@@ -138,7 +137,7 @@ TEST_F(PullAllNodeTest, ApplyWithSingleNumber) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a"], collator));
- Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -155,7 +154,7 @@ TEST_F(PullAllNodeTest, ApplyNoIndexDataNoLogBuilder) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a"], collator));
- Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -171,7 +170,7 @@ TEST_F(PullAllNodeTest, ApplyWithElementNotPresentInArray) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a"], collator));
- Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -188,7 +187,7 @@ TEST_F(PullAllNodeTest, ApplyWithWithTwoElements) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a"], collator));
- Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -205,7 +204,7 @@ TEST_F(PullAllNodeTest, ApplyWithAllArrayElements) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a"], collator));
- Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -222,7 +221,7 @@ TEST_F(PullAllNodeTest, ApplyWithAllArrayElementsButOutOfOrder) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a"], collator));
- Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -239,7 +238,7 @@ TEST_F(PullAllNodeTest, ApplyWithAllArrayElementsAndThenSome) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a"], collator));
- Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 'a', {r: 1, b: 2}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -256,7 +255,7 @@ TEST_F(PullAllNodeTest, ApplyWithCollator) {
PullAllNode node;
ASSERT_OK(node.init(update["$pullAll"]["a"], &collator));
- Document doc(fromjson("{a: ['foo', 'bar', 'baz']}"));
+ mutablebson::Document doc(fromjson("{a: ['foo', 'bar', 'baz']}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -274,7 +273,7 @@ TEST_F(PullAllNodeTest, ApplyAfterSetCollator) {
ASSERT_OK(node.init(update["$pullAll"]["a"], collator));
// First without a collator.
- Document doc(fromjson("{a: ['foo', 'bar', 'baz']}"));
+ mutablebson::Document doc(fromjson("{a: ['foo', 'bar', 'baz']}"));
setPathTaken("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
ASSERT_TRUE(result.noop);
@@ -284,7 +283,7 @@ TEST_F(PullAllNodeTest, ApplyAfterSetCollator) {
// Now with a collator.
CollatorInterfaceMock mockCollator(CollatorInterfaceMock::MockType::kToLowerString);
node.setCollator(&mockCollator);
- Document doc2(fromjson("{a: ['foo', 'bar', 'baz']}"));
+ mutablebson::Document doc2(fromjson("{a: ['foo', 'bar', 'baz']}"));
resetApplyParams();
setPathTaken("a");
result = node.apply(getApplyParams(doc2.root()["a"]));
diff --git a/src/mongo/db/update/push_node_test.cpp b/src/mongo/db/update/push_node_test.cpp
index a06b26484bd..ba9e988fb64 100644
--- a/src/mongo/db/update/push_node_test.cpp
+++ b/src/mongo/db/update/push_node_test.cpp
@@ -42,7 +42,6 @@ namespace mongo {
namespace {
using PushNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -262,7 +261,7 @@ TEST_F(PushNodeTest, ApplyToNonArrayFails) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{_id: 'test_object', a: 1}"));
+ mutablebson::Document doc(fromjson("{_id: 'test_object', a: 1}"));
setPathTaken("a");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -278,7 +277,7 @@ TEST_F(PushNodeTest, ApplyToEmptyArray) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -295,7 +294,7 @@ TEST_F(PushNodeTest, ApplyToEmptyDocument) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -312,7 +311,7 @@ TEST_F(PushNodeTest, ApplyToArrayWithOneElement) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -329,7 +328,7 @@ TEST_F(PushNodeTest, ApplyToDottedPathElement) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["choices.first.votes"], collator));
- Document doc(
+ mutablebson::Document doc(
fromjson("{_id : 1 , "
" question : 'a', "
" choices: {first: { choice: 'b'}, "
@@ -357,7 +356,7 @@ TEST_F(PushNodeTest, ApplySimpleEachToEmptyArray) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -374,7 +373,7 @@ TEST_F(PushNodeTest, ApplySimpleEachToEmptyDocument) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -391,7 +390,7 @@ TEST_F(PushNodeTest, ApplyMultipleEachToEmptyDocument) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -408,7 +407,7 @@ TEST_F(PushNodeTest, ApplySimpleEachToArrayWithOneElement) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -425,7 +424,7 @@ TEST_F(PushNodeTest, ApplyMultipleEachToArrayWithOneElement) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -442,7 +441,7 @@ TEST_F(PushNodeTest, ApplyEmptyEachToEmptyArray) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -459,7 +458,7 @@ TEST_F(PushNodeTest, ApplyEmptyEachToEmptyDocument) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -476,7 +475,7 @@ TEST_F(PushNodeTest, ApplyEmptyEachToArrayWithOneElement) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -493,7 +492,7 @@ TEST_F(PushNodeTest, ApplyToArrayWithSlice) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [3]}"));
+ mutablebson::Document doc(fromjson("{a: [3]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -510,7 +509,7 @@ TEST_F(PushNodeTest, ApplyWithNumericSort) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [3]}"));
+ mutablebson::Document doc(fromjson("{a: [3]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -527,7 +526,7 @@ TEST_F(PushNodeTest, ApplyWithReverseNumericSort) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [3]}"));
+ mutablebson::Document doc(fromjson("{a: [3]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -544,7 +543,7 @@ TEST_F(PushNodeTest, ApplyWithMixedSort) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [3, 't', {b: 1}, {a: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [3, 't', {b: 1}, {a: 1}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -561,7 +560,7 @@ TEST_F(PushNodeTest, ApplyWithReverseMixedSort) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [3, 't', {b: 1}, {a: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [3, 't', {b: 1}, {a: 1}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -578,7 +577,7 @@ TEST_F(PushNodeTest, ApplyWithEmbeddedFieldSort) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [3, 't', {b: 1}, {a: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [3, 't', {b: 1}, {a: 1}]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -595,7 +594,7 @@ TEST_F(PushNodeTest, ApplySortWithCollator) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], &collator));
- Document doc(fromjson("{a: ['dd', 'fc', 'gb']}"));
+ mutablebson::Document doc(fromjson("{a: ['dd', 'fc', 'gb']}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -612,7 +611,7 @@ TEST_F(PushNodeTest, ApplySortAfterSetCollator) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: ['dd', 'fc', 'gb']}"));
+ mutablebson::Document doc(fromjson("{a: ['dd', 'fc', 'gb']}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -623,7 +622,7 @@ TEST_F(PushNodeTest, ApplySortAfterSetCollator) {
// Now with a collator.
CollatorInterfaceMock mockCollator(CollatorInterfaceMock::MockType::kReverseString);
node.setCollator(&mockCollator);
- Document doc2(fromjson("{a: ['dd', 'fc', 'gb']}"));
+ mutablebson::Document doc2(fromjson("{a: ['dd', 'fc', 'gb']}"));
result = node.apply(getApplyParams(doc2.root()["a"]));
ASSERT_FALSE(result.noop);
ASSERT_EQUALS(fromjson("{a: ['ha', 'gb', 'fc', 'dd']}"), doc2);
@@ -634,7 +633,7 @@ TEST_F(PushNodeTest, ApplySortAfterSetCollator) {
// prints out the modifier when it observes a failure, which will help with diagnosis.
void checkDocumentAndResult(BSONObj updateModifier,
BSONObj expectedDocument,
- const Document& actualDocument,
+ const mutablebson::Document& actualDocument,
UpdateNode::ApplyResult applyResult) {
if (expectedDocument == actualDocument && !applyResult.noop && !applyResult.indexesAffected) {
// Check succeeded.
@@ -671,7 +670,7 @@ TEST_F(PushNodeTest, ApplyToEmptyArrayWithSliceValues) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -703,7 +702,7 @@ TEST_F(PushNodeTest, ApplyToPopulatedArrayWithSliceValues) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [2, 3]}"));
+ mutablebson::Document doc(fromjson("{a: [2, 3]}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -804,7 +803,7 @@ TEST_F(PushNodeTest, ApplyToPopulatedArrayWithSortAndSliceValues) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [{a: 2, b: 3}, {a: 3, b: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{a: 2, b: 3}, {a: 3, b: 1}]}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -818,7 +817,7 @@ TEST_F(PushNodeTest, ApplyToEmptyArrayWithPositionZero) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -835,7 +834,7 @@ TEST_F(PushNodeTest, ApplyToEmptyArrayWithPositionOne) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -852,7 +851,7 @@ TEST_F(PushNodeTest, ApplyToEmptyArrayWithLargePosition) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -869,7 +868,7 @@ TEST_F(PushNodeTest, ApplyToSingletonArrayWithPositionZero) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -886,7 +885,7 @@ TEST_F(PushNodeTest, ApplyToSingletonArrayWithLargePosition) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -903,7 +902,7 @@ TEST_F(PushNodeTest, ApplyToEmptyArrayWithNegativePosition) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -920,7 +919,7 @@ TEST_F(PushNodeTest, ApplyToSingletonArrayWithNegativePosition) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -937,7 +936,7 @@ TEST_F(PushNodeTest, ApplyToPopulatedArrayWithNegativePosition) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0, 1, 2, 3, 4]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2, 3, 4]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -954,7 +953,7 @@ TEST_F(PushNodeTest, ApplyToPopulatedArrayWithOutOfBoundsNegativePosition) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0, 1, 2, 3, 4]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2, 3, 4]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -971,7 +970,7 @@ TEST_F(PushNodeTest, ApplyMultipleElementsPushWithNegativePosition) {
PushNode node;
ASSERT_OK(node.init(update["$push"]["a"], collator));
- Document doc(fromjson("{a: [0, 1, 2, 3, 4]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2, 3, 4]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
diff --git a/src/mongo/db/update/push_sorter_test.cpp b/src/mongo/db/update/push_sorter_test.cpp
index 42cc0f3783d..611f4e80206 100644
--- a/src/mongo/db/update/push_sorter_test.cpp
+++ b/src/mongo/db/update/push_sorter_test.cpp
@@ -40,7 +40,6 @@
namespace mongo {
namespace {
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::sortChildren;
@@ -75,7 +74,7 @@ public:
}
private:
- Document _doc;
+ mutablebson::Document _doc;
BSONObj _objs[3];
size_t _size;
};
diff --git a/src/mongo/db/update/rename_node_test.cpp b/src/mongo/db/update/rename_node_test.cpp
index 84f46f0651f..a72485b7e23 100644
--- a/src/mongo/db/update/rename_node_test.cpp
+++ b/src/mongo/db/update/rename_node_test.cpp
@@ -41,7 +41,6 @@ namespace mongo {
namespace {
using RenameNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -115,7 +114,7 @@ TEST_F(RenameNodeTest, SimpleNumberAtRoot) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 2}"));
+ mutablebson::Document doc(fromjson("{a: 2}"));
setPathToCreate("b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -131,7 +130,7 @@ TEST_F(RenameNodeTest, ToExistsAtSameLevel) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 2, b: 1}"));
+ mutablebson::Document doc(fromjson("{a: 2, b: 1}"));
setPathTaken("b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["b"]));
@@ -147,7 +146,7 @@ TEST_F(RenameNodeTest, ToAndFromHaveSameValue) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 2, b: 2}"));
+ mutablebson::Document doc(fromjson("{a: 2, b: 2}"));
setPathTaken("b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["b"]));
@@ -163,7 +162,7 @@ TEST_F(RenameNodeTest, FromDottedElement) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.c"], collator));
- Document doc(fromjson("{a: {c: {d: 6}}, b: 1}"));
+ mutablebson::Document doc(fromjson("{a: {c: {d: 6}}, b: 1}"));
setPathTaken("b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["b"]));
@@ -179,7 +178,7 @@ TEST_F(RenameNodeTest, RenameToExistingNestedFieldDoesNotReorderFields) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["c.d"], collator));
- Document doc(fromjson("{a: {b: {c: 1, d: 2}}, b: 3, c: {d: 4}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: 1, d: 2}}, b: 3, c: {d: 4}}"));
setPathTaken("a.b.c");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]["c"]));
@@ -195,7 +194,7 @@ TEST_F(RenameNodeTest, MissingCompleteTo) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 2, b: 1, c: {}}"));
+ mutablebson::Document doc(fromjson("{a: 2, b: 1, c: {}}"));
setPathToCreate("r.d");
setPathTaken("c");
addIndexedPath("a");
@@ -212,7 +211,7 @@ TEST_F(RenameNodeTest, ToIsCompletelyMissing) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 2}"));
+ mutablebson::Document doc(fromjson("{a: 2}"));
setPathToCreate("b.c.d");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -228,7 +227,7 @@ TEST_F(RenameNodeTest, ToMissingDottedField) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: [{a:2, b:1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{a:2, b:1}]}"));
setPathToCreate("b.c.d");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -244,7 +243,7 @@ TEST_F(RenameNodeTest, MoveIntoArray) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["b"], collator));
- Document doc(fromjson("{_id: 'test_object', a: [1, 2], b: 2}"));
+ mutablebson::Document doc(fromjson("{_id: 'test_object', a: [1, 2], b: 2}"));
setPathToCreate("2");
setPathTaken("a");
addIndexedPath("a");
@@ -261,7 +260,7 @@ TEST_F(RenameNodeTest, MoveIntoArrayNoId) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["b"], collator));
- Document doc(fromjson("{a: [1, 2], b: 2}"));
+ mutablebson::Document doc(fromjson("{a: [1, 2], b: 2}"));
setPathToCreate("2");
setPathTaken("a");
addIndexedPath("a");
@@ -278,7 +277,7 @@ TEST_F(RenameNodeTest, MoveToArrayElement) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["b"], collator));
- Document doc(fromjson("{_id: 'test_object', a: [1, 2], b: 2}"));
+ mutablebson::Document doc(fromjson("{_id: 'test_object', a: [1, 2], b: 2}"));
setPathTaken("a.1");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"]["1"])),
@@ -294,7 +293,7 @@ TEST_F(RenameNodeTest, MoveOutOfArray) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.0"], collator));
- Document doc(fromjson("{_id: 'test_object', a: [1, 2]}"));
+ mutablebson::Document doc(fromjson("{_id: 'test_object', a: [1, 2]}"));
setPathToCreate("b");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root())),
@@ -310,7 +309,7 @@ TEST_F(RenameNodeTest, MoveNonexistentEmbeddedFieldOut) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.a"], collator));
- Document doc(fromjson("{a: [{a: 1}, {b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [{a: 1}, {b: 2}]}"));
setPathToCreate("b");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -326,7 +325,7 @@ TEST_F(RenameNodeTest, MoveEmbeddedFieldOutWithElementNumber) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.0.a"], collator));
- Document doc(fromjson("{_id: 'test_object', a: [{a: 1}, {b: 2}]}"));
+ mutablebson::Document doc(fromjson("{_id: 'test_object', a: [{a: 1}, {b: 2}]}"));
setPathToCreate("b");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root())),
@@ -342,7 +341,7 @@ TEST_F(RenameNodeTest, ReplaceArrayField) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 2, b: []}"));
+ mutablebson::Document doc(fromjson("{a: 2, b: []}"));
setPathTaken("b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["b"]));
@@ -358,7 +357,7 @@ TEST_F(RenameNodeTest, ReplaceWithArrayField) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: [], b: 2}"));
+ mutablebson::Document doc(fromjson("{a: [], b: 2}"));
setPathTaken("b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["b"]));
@@ -374,7 +373,7 @@ TEST_F(RenameNodeTest, CanRenameFromInvalidFieldName) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["$a"], collator));
- Document doc(fromjson("{$a: 2}"));
+ mutablebson::Document doc(fromjson("{$a: 2}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -390,7 +389,7 @@ TEST_F(RenameNodeTest, RenameWithoutLogBuilderOrIndexData) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 2}"));
+ mutablebson::Document doc(fromjson("{a: 2}"));
setPathToCreate("b");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()));
@@ -404,7 +403,7 @@ TEST_F(RenameNodeTest, RenameFromNonExistentPathIsNoOp) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{b: 2}"));
+ mutablebson::Document doc(fromjson("{b: 2}"));
setPathTaken("b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["b"]));
@@ -420,7 +419,7 @@ TEST_F(RenameNodeTest, ApplyCannotRemoveRequiredPartOfDBRef) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.$id"], collator));
- Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
+ mutablebson::Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
setPathToCreate("b");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root())),
UserException,
@@ -434,7 +433,7 @@ TEST_F(RenameNodeTest, ApplyCanRemoveRequiredPartOfDBRefIfValidateForStorageIsFa
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.$id"], collator));
- Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
+ mutablebson::Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
setPathToCreate("b");
addIndexedPath("a");
setValidateForStorage(false);
@@ -456,7 +455,7 @@ TEST_F(RenameNodeTest, ApplyCannotRemoveImmutablePath) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 1}}"));
setPathToCreate("c");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -472,7 +471,7 @@ TEST_F(RenameNodeTest, ApplyCannotRemovePrefixOfImmutablePath) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 1}}"));
setPathToCreate("c");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -488,7 +487,7 @@ TEST_F(RenameNodeTest, ApplyCannotRemoveSuffixOfImmutablePath) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: {c: 1}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: 1}}}"));
setPathToCreate("d");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -504,7 +503,7 @@ TEST_F(RenameNodeTest, ApplyCanRemoveImmutablePathIfNoop) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: {}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {}}}"));
setPathToCreate("d");
addImmutablePath("a.b");
addIndexedPath("a");
@@ -522,7 +521,7 @@ TEST_F(RenameNodeTest, ApplyCannotCreateDollarPrefixedField) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathToCreate("$bad");
ASSERT_THROWS_CODE_AND_WHAT(
node.apply(getApplyParams(doc.root())),
@@ -537,7 +536,7 @@ TEST_F(RenameNodeTest, ApplyCannotOverwriteImmutablePath) {
RenameNode node;
ASSERT_OK(node.init(update["$rename"]["a"], collator));
- Document doc(fromjson("{a: 0, b: 1}"));
+ mutablebson::Document doc(fromjson("{a: 0, b: 1}"));
setPathTaken("b");
addImmutablePath("b");
ASSERT_THROWS_CODE_AND_WHAT(
diff --git a/src/mongo/db/update/set_node_test.cpp b/src/mongo/db/update/set_node_test.cpp
index 3d90d27b6c5..a7a6f793a10 100644
--- a/src/mongo/db/update/set_node_test.cpp
+++ b/src/mongo/db/update/set_node_test.cpp
@@ -41,7 +41,6 @@ namespace mongo {
namespace {
using SetNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -65,7 +64,7 @@ TEST_F(SetNodeTest, ApplyNoOp) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -82,7 +81,7 @@ TEST_F(SetNodeTest, ApplyEmptyPathToCreate) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -99,7 +98,7 @@ TEST_F(SetNodeTest, ApplyCreatePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b.c"], collator));
- Document doc(fromjson("{a: {d: 5}}"));
+ mutablebson::Document doc(fromjson("{a: {d: 5}}"));
setPathToCreate("b.c");
setPathTaken("a");
addIndexedPath("a");
@@ -117,7 +116,7 @@ TEST_F(SetNodeTest, ApplyCreatePathFromRoot) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{c: 5}"));
+ mutablebson::Document doc(fromjson("{c: 5}"));
setPathToCreate("a.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -134,7 +133,7 @@ TEST_F(SetNodeTest, ApplyPositional) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.$"], collator));
- Document doc(fromjson("{a: [0, 1, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2]}"));
setPathTaken("a.1");
setMatchedField("1");
addIndexedPath("a");
@@ -152,7 +151,7 @@ TEST_F(SetNodeTest, ApplyNonViablePathToCreate) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a");
@@ -168,7 +167,7 @@ TEST_F(SetNodeTest, ApplyNonViablePathToCreateFromReplicationIsNoOp) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a");
@@ -187,7 +186,7 @@ TEST_F(SetNodeTest, ApplyNoIndexDataNoLogBuilder) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -203,7 +202,7 @@ TEST_F(SetNodeTest, ApplyDoesNotAffectIndexes) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("b");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -219,7 +218,7 @@ TEST_F(SetNodeTest, TypeChangeIsNotANoop) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: NumberInt(2)}"));
+ mutablebson::Document doc(fromjson("{a: NumberInt(2)}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -236,7 +235,7 @@ TEST_F(SetNodeTest, IdentityOpOnDeserializedIsNotANoOp) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: { b: NumberInt(0)}}"));
+ mutablebson::Document doc(fromjson("{a: { b: NumberInt(0)}}"));
// Apply a mutation to the document that will make it non-serialized.
doc.root()["a"]["b"].setValueInt(2).transitional_ignore();
@@ -255,7 +254,7 @@ TEST_F(SetNodeTest, ApplyEmptyDocument) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -271,7 +270,7 @@ TEST_F(SetNodeTest, ApplyInPlace) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -287,7 +286,7 @@ TEST_F(SetNodeTest, ApplyOverridePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 1}}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -303,7 +302,7 @@ TEST_F(SetNodeTest, ApplyChangeType) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 'str'}"));
+ mutablebson::Document doc(fromjson("{a: 'str'}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -319,7 +318,7 @@ TEST_F(SetNodeTest, ApplyNewPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{b: 1}"));
+ mutablebson::Document doc(fromjson("{b: 1}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -335,7 +334,7 @@ TEST_F(SetNodeTest, ApplyLog) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
node.apply(getApplyParams(doc.root()["a"]));
ASSERT_EQUALS(fromjson("{a: 2}"), doc);
@@ -350,7 +349,7 @@ TEST_F(SetNodeTest, ApplyNoOpDottedPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -366,7 +365,7 @@ TEST_F(SetNodeTest, TypeChangeOnDottedPathIsNotANoOp) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {b: NumberLong(2)}}"));
+ mutablebson::Document doc(fromjson("{a: {b: NumberLong(2)}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -382,7 +381,7 @@ TEST_F(SetNodeTest, ApplyPathNotViable) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a:1}"));
+ mutablebson::Document doc(fromjson("{a:1}"));
setPathToCreate("b");
setPathTaken("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -397,7 +396,7 @@ TEST_F(SetNodeTest, ApplyPathNotViableArrray) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a:[{b:1}]}"));
+ mutablebson::Document doc(fromjson("{a:[{b:1}]}"));
setPathToCreate("b");
setPathTaken("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -412,7 +411,7 @@ TEST_F(SetNodeTest, ApplyInPlaceDottedPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 1}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -428,7 +427,7 @@ TEST_F(SetNodeTest, ApplyChangeTypeDottedPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 'str'}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 'str'}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -444,7 +443,7 @@ TEST_F(SetNodeTest, ApplyChangePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {b: {c: 1}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: 1}}}"));
setPathTaken("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -460,7 +459,7 @@ TEST_F(SetNodeTest, ApplyExtendPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {c: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {c: 1}}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a.b");
@@ -477,7 +476,7 @@ TEST_F(SetNodeTest, ApplyNewDottedPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{c: 1}"));
+ mutablebson::Document doc(fromjson("{c: 1}"));
setPathToCreate("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()));
@@ -493,7 +492,7 @@ TEST_F(SetNodeTest, ApplyEmptyDoc) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()));
@@ -509,7 +508,7 @@ TEST_F(SetNodeTest, ApplyFieldWithDot) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{'a.b':4}"));
+ mutablebson::Document doc(fromjson("{'a.b':4}"));
setPathToCreate("a.b");
addIndexedPath("a.b");
auto result = node.apply(getApplyParams(doc.root()));
@@ -525,7 +524,7 @@ TEST_F(SetNodeTest, ApplyNoOpArrayIndex) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 2}]}"));
setPathTaken("a.2.b");
addIndexedPath("a.2.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["2"]["b"]));
@@ -541,7 +540,7 @@ TEST_F(SetNodeTest, TypeChangeInArrayIsNotANoOp) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 2.0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 2.0}]}"));
setPathTaken("a.2.b");
addIndexedPath("a.2.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["2"]["b"]));
@@ -557,7 +556,7 @@ TEST_F(SetNodeTest, ApplyNonViablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
setPathToCreate("2.b");
setPathTaken("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -572,7 +571,7 @@ TEST_F(SetNodeTest, ApplyInPlaceArrayIndex) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0},{b: 1},{b: 1}]}"));
setPathTaken("a.2.b");
addIndexedPath("a.2.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["2"]["b"]));
@@ -588,7 +587,7 @@ TEST_F(SetNodeTest, ApplyNormalArray) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0},{b: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0},{b: 1}]}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a.2.b");
@@ -605,7 +604,7 @@ TEST_F(SetNodeTest, ApplyPaddingArray) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0}]}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a.2.b");
@@ -622,7 +621,7 @@ TEST_F(SetNodeTest, ApplyNumericObject) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: {b: 0}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 0}}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a.2.b");
@@ -639,7 +638,7 @@ TEST_F(SetNodeTest, ApplyNumericField) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: {'2': {b: 1}}}"));
+ mutablebson::Document doc(fromjson("{a: {'2': {b: 1}}}"));
setPathTaken("a.2.b");
addIndexedPath("a.2.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["2"]["b"]));
@@ -655,7 +654,7 @@ TEST_F(SetNodeTest, ApplyExtendNumericField) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: {'2': {c: 1}}}"));
+ mutablebson::Document doc(fromjson("{a: {'2': {c: 1}}}"));
setPathToCreate("b");
setPathTaken("a.2");
addIndexedPath("a.2.b");
@@ -672,7 +671,7 @@ TEST_F(SetNodeTest, ApplyEmptyObject) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: {}}"));
+ mutablebson::Document doc(fromjson("{a: {}}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a.2.b");
@@ -689,7 +688,7 @@ TEST_F(SetNodeTest, ApplyEmptyArray) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathToCreate("2.b");
setPathTaken("a");
addIndexedPath("a.2.b");
@@ -706,7 +705,7 @@ TEST_F(SetNodeTest, ApplyLogDottedPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: [{b:0}, {b:1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b:0}, {b:1}]}"));
setPathToCreate("2.b");
setPathTaken("a");
node.apply(getApplyParams(doc.root()["a"]));
@@ -722,7 +721,7 @@ TEST_F(SetNodeTest, LogEmptyArray) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
setPathToCreate("2.b");
setPathTaken("a");
node.apply(getApplyParams(doc.root()["a"]));
@@ -738,7 +737,7 @@ TEST_F(SetNodeTest, LogEmptyObject) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.2.b"], collator));
- Document doc(fromjson("{a: {}}"));
+ mutablebson::Document doc(fromjson("{a: {}}"));
setPathToCreate("2.b");
setPathTaken("a");
node.apply(getApplyParams(doc.root()["a"]));
@@ -754,7 +753,7 @@ TEST_F(SetNodeTest, ApplyNoOpComplex) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.1.b"], collator));
- Document doc(fromjson("{a: [{b: {c: 0, d: 0}}, {b: {c: 1, d: 1}}]}}"));
+ mutablebson::Document doc(fromjson("{a: [{b: {c: 0, d: 0}}, {b: {c: 1, d: 1}}]}}"));
setPathTaken("a.1.b");
addIndexedPath("a.1.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["1"]["b"]));
@@ -770,7 +769,7 @@ TEST_F(SetNodeTest, ApplySameStructure) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.1.b"], collator));
- Document doc(fromjson("{a: [{b: {c: 0, d: 0}}, {b: {c: 1, xxx: 1}}]}}"));
+ mutablebson::Document doc(fromjson("{a: [{b: {c: 0, d: 0}}, {b: {c: 1, xxx: 1}}]}}"));
setPathTaken("a.1.b");
addIndexedPath("a.1.b");
auto result = node.apply(getApplyParams(doc.root()["a"]["1"]["b"]));
@@ -786,7 +785,7 @@ TEST_F(SetNodeTest, NonViablePathWithoutRepl) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.1.b"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathToCreate("1.b");
setPathTaken("a");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -801,7 +800,7 @@ TEST_F(SetNodeTest, SingleFieldFromReplication) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.1.b"], collator));
- Document doc(fromjson("{_id:1, a: 1}"));
+ mutablebson::Document doc(fromjson("{_id:1, a: 1}"));
setPathToCreate("1.b");
setPathTaken("a");
addIndexedPath("a.1.b");
@@ -819,7 +818,7 @@ TEST_F(SetNodeTest, SingleFieldNoIdFromReplication) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.1.b"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathToCreate("1.b");
setPathTaken("a");
addIndexedPath("a.1.b");
@@ -837,7 +836,7 @@ TEST_F(SetNodeTest, NestedFieldFromReplication) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.a.1.b"], collator));
- Document doc(fromjson("{_id:1, a: {a: 1}}"));
+ mutablebson::Document doc(fromjson("{_id:1, a: {a: 1}}"));
setPathToCreate("1.b");
setPathTaken("a.a");
addIndexedPath("a.a.1.b");
@@ -855,7 +854,7 @@ TEST_F(SetNodeTest, DoubleNestedFieldFromReplication) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b.c.d"], collator));
- Document doc(fromjson("{_id:1, a: {b: {c: 1}}}"));
+ mutablebson::Document doc(fromjson("{_id:1, a: {b: {c: 1}}}"));
setPathToCreate("d");
setPathTaken("a.b.c");
addIndexedPath("a.b.c.d");
@@ -873,7 +872,7 @@ TEST_F(SetNodeTest, NestedFieldNoIdFromReplication) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.a.1.b"], collator));
- Document doc(fromjson("{a: {a: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {a: 1}}"));
setPathToCreate("1.b");
setPathTaken("a.a");
addIndexedPath("a.a.1.b");
@@ -891,7 +890,7 @@ TEST_F(SetNodeTest, ReplayArrayFieldNotAppendedIntermediateFromReplication) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.0.b"], collator));
- Document doc(fromjson("{_id: 0, a: [1, {b: [1]}]}"));
+ mutablebson::Document doc(fromjson("{_id: 0, a: [1, {b: [1]}]}"));
setPathToCreate("b");
setPathTaken("a.0");
addIndexedPath("a.1.b");
@@ -909,7 +908,7 @@ TEST_F(SetNodeTest, Set6) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["r.a"], collator));
- Document doc(fromjson("{_id: 1, r: {a:1, b:2}}"));
+ mutablebson::Document doc(fromjson("{_id: 1, r: {a:1, b:2}}"));
setPathTaken("r.a");
addIndexedPath("r.a");
auto result = node.apply(getApplyParams(doc.root()["r"]["a"]));
@@ -927,7 +926,7 @@ TEST_F(SetNodeTest, Set6FromRepl) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["r.a"], collator));
- Document doc(fromjson("{_id: 1, r: {a:1, b:2}}"));
+ mutablebson::Document doc(fromjson("{_id: 1, r: {a:1, b:2}}"));
setPathTaken("r.a");
addIndexedPath("r.a");
setFromReplication(true);
@@ -949,7 +948,7 @@ TEST_F(SetNodeTest, ApplySetModToEphemeralDocument) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["x"], collator));
- Document doc;
+ mutablebson::Document doc;
Element x = doc.makeElementObject("x");
doc.root().pushBack(x).transitional_ignore();
Element a = doc.makeElementInt("a", 100);
@@ -970,7 +969,7 @@ TEST_F(SetNodeTest, ApplyCannotCreateDollarPrefixedFieldInsideSetElement) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
ASSERT_THROWS_CODE_AND_WHAT(
node.apply(getApplyParams(doc.root()["a"])),
@@ -985,7 +984,7 @@ TEST_F(SetNodeTest, ApplyCannotCreateDollarPrefixedFieldAtStartOfPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["$bad.a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("$bad.a");
ASSERT_THROWS_CODE_AND_WHAT(
node.apply(getApplyParams(doc.root())),
@@ -1000,7 +999,7 @@ TEST_F(SetNodeTest, ApplyCannotCreateDollarPrefixedFieldInMiddleOfPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.$bad.b"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a.$bad.b");
ASSERT_THROWS_CODE_AND_WHAT(
node.apply(getApplyParams(doc.root())),
@@ -1015,7 +1014,7 @@ TEST_F(SetNodeTest, ApplyCannotCreateDollarPrefixedFieldAtEndOfPath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.$bad"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a.$bad");
ASSERT_THROWS_CODE_AND_WHAT(
node.apply(getApplyParams(doc.root())),
@@ -1030,7 +1029,7 @@ TEST_F(SetNodeTest, ApplyCanCreateDollarPrefixedFieldNameWhenValidateForStorageI
SetNode node;
ASSERT_OK(node.init(update["$set"]["$bad"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("$bad");
addIndexedPath("$bad");
setValidateForStorage(false);
@@ -1049,7 +1048,7 @@ TEST_F(SetNodeTest, ApplyCannotOverwriteImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a.b");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -1065,7 +1064,7 @@ TEST_F(SetNodeTest, ApplyCanPerformNoopOnImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a.b");
addImmutablePath("a.b");
addIndexedPath("a");
@@ -1084,7 +1083,7 @@ TEST_F(SetNodeTest, ApplyCannotOverwritePrefixToRemoveImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -1100,7 +1099,7 @@ TEST_F(SetNodeTest, ApplyCannotOverwritePrefixToModifyImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -1116,7 +1115,7 @@ TEST_F(SetNodeTest, ApplyCanPerformNoopOnPrefixOfImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a");
addImmutablePath("a.b");
addIndexedPath("a");
@@ -1135,7 +1134,7 @@ TEST_F(SetNodeTest, ApplyCanOverwritePrefixToCreateImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
addImmutablePath("a.b");
addIndexedPath("a");
@@ -1154,7 +1153,7 @@ TEST_F(SetNodeTest, ApplyCanOverwritePrefixOfImmutablePathIfNoopOnImmutablePath)
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 2}}"));
setPathTaken("a");
addImmutablePath("a.b");
addIndexedPath("a");
@@ -1173,7 +1172,7 @@ TEST_F(SetNodeTest, ApplyCannotOverwriteSuffixOfImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: {c: 2}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: 2}}}"));
setPathTaken("a.b.c");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -1189,7 +1188,7 @@ TEST_F(SetNodeTest, ApplyCanPerformNoopOnSuffixOfImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: {c: 2}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: 2}}}"));
setPathTaken("a.b.c");
addImmutablePath("a.b");
addIndexedPath("a");
@@ -1208,7 +1207,7 @@ TEST_F(SetNodeTest, ApplyCannotCreateFieldAtEndOfImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: {}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {}}}"));
setPathToCreate("c");
setPathTaken("a.b");
addImmutablePath("a.b");
@@ -1225,7 +1224,7 @@ TEST_F(SetNodeTest, ApplyCannotCreateFieldBeyondEndOfImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: {}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {}}}"));
setPathToCreate("c");
setPathTaken("a.b");
addImmutablePath("a");
@@ -1242,7 +1241,7 @@ TEST_F(SetNodeTest, ApplyCanCreateImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a.b"], collator));
- Document doc(fromjson("{a: {}}"));
+ mutablebson::Document doc(fromjson("{a: {}}"));
setPathToCreate("b");
setPathTaken("a");
addImmutablePath("a.b");
@@ -1262,7 +1261,7 @@ TEST_F(SetNodeTest, ApplyCanCreatePrefixOfImmutablePath) {
SetNode node;
ASSERT_OK(node.init(update["$set"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addImmutablePath("a.b");
addIndexedPath("a");
@@ -1281,7 +1280,7 @@ TEST_F(SetNodeTest, ApplySetOnInsertIsNoopWhenInsertIsFalse) {
SetNode node(UpdateNode::Context::kInsertOnly);
ASSERT_OK(node.init(update["$setOnInsert"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -1298,7 +1297,7 @@ TEST_F(SetNodeTest, ApplySetOnInsertIsAppliedWhenInsertIsTrue) {
SetNode node(UpdateNode::Context::kInsertOnly);
ASSERT_OK(node.init(update["$setOnInsert"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
setInsert(true);
addIndexedPath("a");
@@ -1316,7 +1315,7 @@ TEST_F(SetNodeTest, ApplySetOnInsertExistingPath) {
SetNode node(UpdateNode::Context::kInsertOnly);
ASSERT_OK(node.init(update["$setOnInsert"]["a"], collator));
- Document doc(fromjson("{a: 1}"));
+ mutablebson::Document doc(fromjson("{a: 1}"));
setPathTaken("a");
setInsert(true);
addIndexedPath("a");
diff --git a/src/mongo/db/update/unset_node_test.cpp b/src/mongo/db/update/unset_node_test.cpp
index ad8f373e943..94be0fadb2d 100644
--- a/src/mongo/db/update/unset_node_test.cpp
+++ b/src/mongo/db/update/unset_node_test.cpp
@@ -41,7 +41,6 @@ namespace mongo {
namespace {
using UnsetNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
using mongo::mutablebson::countChildren;
@@ -58,7 +57,7 @@ DEATH_TEST_F(UnsetNodeTest, ApplyToRootFails, "Invariant failure parent.ok()") {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
node.apply(getApplyParams(doc.root()));
}
@@ -76,7 +75,7 @@ TEST_F(UnsetNodeTest, UnsetNoOp) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a"], collator));
- Document doc(fromjson("{b: 5}"));
+ mutablebson::Document doc(fromjson("{b: 5}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -93,7 +92,7 @@ TEST_F(UnsetNodeTest, UnsetNoOpDottedPath) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.b"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a");
@@ -111,7 +110,7 @@ TEST_F(UnsetNodeTest, UnsetNoOpThroughArray) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.b"], collator));
- Document doc(fromjson("{a:[{b:1}]}"));
+ mutablebson::Document doc(fromjson("{a:[{b:1}]}"));
setPathToCreate("b");
setPathTaken("a");
addIndexedPath("a");
@@ -129,7 +128,7 @@ TEST_F(UnsetNodeTest, UnsetNoOpEmptyDoc) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a"], collator));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setPathToCreate("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()));
@@ -146,7 +145,7 @@ TEST_F(UnsetNodeTest, UnsetTopLevelPath) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -163,7 +162,7 @@ TEST_F(UnsetNodeTest, UnsetNestedPath) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: {c: 6}}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: 6}}}}"));
setPathTaken("a.b.c");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]["c"]));
@@ -180,7 +179,7 @@ TEST_F(UnsetNodeTest, UnsetObject) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.b"], collator));
- Document doc(fromjson("{a: {b: {c: 6}}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: 6}}}}"));
setPathTaken("a.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -197,7 +196,7 @@ TEST_F(UnsetNodeTest, UnsetArrayElement) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.0"], collator));
- Document doc(fromjson("{a:[1], b:1}"));
+ mutablebson::Document doc(fromjson("{a:[1], b:1}"));
setPathTaken("a.0");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["0"]));
@@ -214,7 +213,7 @@ TEST_F(UnsetNodeTest, UnsetPositional) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.$"], collator));
- Document doc(fromjson("{a: [0, 1, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2]}"));
setPathTaken("a.1");
setMatchedField("1");
addIndexedPath("a");
@@ -232,7 +231,7 @@ TEST_F(UnsetNodeTest, UnsetEntireArray) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a"], collator));
- Document doc(fromjson("{a: [0, 1, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2]}"));
setPathTaken("a");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -249,7 +248,7 @@ TEST_F(UnsetNodeTest, UnsetFromObjectInArray) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.0.b"], collator));
- Document doc(fromjson("{a: [{b: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 1}]}"));
setPathTaken("a.0.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["0"]["b"]));
@@ -266,7 +265,7 @@ TEST_F(UnsetNodeTest, CanUnsetInvalidField) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.$.$b"], collator));
- Document doc(fromjson("{b: 1, a: [{$b: 1}]}"));
+ mutablebson::Document doc(fromjson("{b: 1, a: [{$b: 1}]}"));
setPathTaken("a.0.$b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["0"]["$b"]));
@@ -283,7 +282,7 @@ TEST_F(UnsetNodeTest, ApplyNoIndexDataNoLogBuilder) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
setLogBuilderToNull();
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -299,7 +298,7 @@ TEST_F(UnsetNodeTest, ApplyDoesNotAffectIndexes) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a"], collator));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
setPathTaken("a");
addIndexedPath("b");
auto result = node.apply(getApplyParams(doc.root()["a"]));
@@ -316,7 +315,7 @@ TEST_F(UnsetNodeTest, ApplyFieldWithDot) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.b"], collator));
- Document doc(fromjson("{'a.b':4, a: {b: 2}}"));
+ mutablebson::Document doc(fromjson("{'a.b':4, a: {b: 2}}"));
setPathTaken("a.b");
addIndexedPath("a");
auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
@@ -333,7 +332,7 @@ TEST_F(UnsetNodeTest, ApplyCannotRemoveRequiredPartOfDBRef) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.$id"], collator));
- Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
+ mutablebson::Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
setPathTaken("a.$id");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"]["$id"])),
UserException,
@@ -347,7 +346,7 @@ TEST_F(UnsetNodeTest, ApplyCanRemoveRequiredPartOfDBRefIfValidateForStorageIsFal
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.$id"], collator));
- Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
+ mutablebson::Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
setPathTaken("a.$id");
addIndexedPath("a");
setValidateForStorage(false);
@@ -367,7 +366,7 @@ TEST_F(UnsetNodeTest, ApplyCannotRemoveImmutablePath) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.b"], collator));
- Document doc(fromjson("{a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 1}}"));
setPathTaken("a.b");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"]["b"])),
@@ -382,7 +381,7 @@ TEST_F(UnsetNodeTest, ApplyCannotRemovePrefixOfImmutablePath) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a"], collator));
- Document doc(fromjson("{a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 1}}"));
setPathTaken("a");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(node.apply(getApplyParams(doc.root()["a"])),
@@ -397,7 +396,7 @@ TEST_F(UnsetNodeTest, ApplyCannotRemoveSuffixOfImmutablePath) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: {c: 1}}}"));
+ mutablebson::Document doc(fromjson("{a: {b: {c: 1}}}"));
setPathTaken("a.b.c");
addImmutablePath("a.b");
ASSERT_THROWS_CODE_AND_WHAT(
@@ -413,7 +412,7 @@ TEST_F(UnsetNodeTest, ApplyCanRemoveImmutablePathIfNoop) {
UnsetNode node;
ASSERT_OK(node.init(update["$unset"]["a.b.c"], collator));
- Document doc(fromjson("{a: {b: 1}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 1}}"));
setPathToCreate("c");
setPathTaken("a.b");
addImmutablePath("a.b");
diff --git a/src/mongo/db/update/update_array_node_test.cpp b/src/mongo/db/update/update_array_node_test.cpp
index 60c5bfb4448..42087846813 100644
--- a/src/mongo/db/update/update_array_node_test.cpp
+++ b/src/mongo/db/update/update_array_node_test.cpp
@@ -42,7 +42,6 @@ namespace mongo {
namespace {
using UpdateArrayNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
TEST_F(UpdateArrayNodeTest, ApplyCreatePathFails) {
@@ -60,7 +59,7 @@ TEST_F(UpdateArrayNodeTest, ApplyCreatePathFails) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: {}}"));
+ mutablebson::Document doc(fromjson("{a: {}}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(
root.apply(getApplyParams(doc.root())),
@@ -84,7 +83,7 @@ TEST_F(UpdateArrayNodeTest, ApplyToNonArrayFails) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: {}}"));
+ mutablebson::Document doc(fromjson("{a: {}}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(root.apply(getApplyParams(doc.root())),
UserException,
@@ -107,7 +106,7 @@ TEST_F(UpdateArrayNodeTest, UpdateIsAppliedToAllMatchingElements) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [0, 1, 0]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 1, 0]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -134,7 +133,7 @@ DEATH_TEST_F(UpdateArrayNodeTest,
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{c: 0}, {c: 0}, {c: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{c: 0}, {c: 0}, {c: 1}]}"));
doc.root()["a"]["1"]["c"].setValueInt(1).transitional_ignore();
doc.root()["a"]["2"]["c"].setValueInt(0).transitional_ignore();
addIndexedPath("a");
@@ -154,7 +153,7 @@ TEST_F(UpdateArrayNodeTest, UpdateForEmptyIdentifierIsAppliedToAllArrayElements)
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [0, 0, 0]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 0, 0]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -195,7 +194,7 @@ TEST_F(UpdateArrayNodeTest, ApplyMultipleUpdatesToArrayElement) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: 0, c: 0, d: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0, c: 0, d: 0}]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -228,7 +227,7 @@ TEST_F(UpdateArrayNodeTest, ApplyMultipleUpdatesToArrayElementsUsingMergedChildr
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: 0, c: 0}, {b: 0, c: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0, c: 0}, {b: 0, c: 0}]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -269,7 +268,7 @@ TEST_F(UpdateArrayNodeTest, ApplyMultipleUpdatesToArrayElementsWithoutMergedChil
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: 0, c: 0, d: 1}, {b: 1, c: 0, d: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0, c: 0, d: 1}, {b: 1, c: 0, d: 0}]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -298,7 +297,7 @@ TEST_F(UpdateArrayNodeTest, ApplyMultipleUpdatesToArrayElementWithEmptyIdentifie
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: 0, c: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0, c: 0}]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -335,7 +334,7 @@ TEST_F(UpdateArrayNodeTest, ApplyNestedArrayUpdates) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{x: 0, b: [{c: 0, d: 0}]}]}"));
+ mutablebson::Document doc(fromjson("{a: [{x: 0, b: [{c: 0, d: 0}]}]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -368,7 +367,7 @@ TEST_F(UpdateArrayNodeTest, ApplyUpdatesWithMergeConflictToArrayElementFails) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(root.apply(getApplyParams(doc.root())),
UserException,
@@ -399,7 +398,7 @@ TEST_F(UpdateArrayNodeTest, ApplyUpdatesWithEmptyIdentifiersWithMergeConflictToA
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: [0]}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: [0]}]}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(root.apply(getApplyParams(doc.root())),
UserException,
@@ -434,7 +433,7 @@ TEST_F(UpdateArrayNodeTest, ApplyNestedArrayUpdatesWithMergeConflictFails) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: [0], c: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: [0], c: 0}]}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(root.apply(getApplyParams(doc.root())),
UserException,
@@ -457,7 +456,7 @@ TEST_F(UpdateArrayNodeTest, NoArrayElementsMatch) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [2, 2, 2]}"));
+ mutablebson::Document doc(fromjson("{a: [2, 2, 2]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.indexesAffected);
@@ -482,7 +481,7 @@ TEST_F(UpdateArrayNodeTest, UpdatesToAllArrayElementsAreNoops) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [1, 1, 1]}"));
+ mutablebson::Document doc(fromjson("{a: [1, 1, 1]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.indexesAffected);
@@ -507,7 +506,7 @@ TEST_F(UpdateArrayNodeTest, NoArrayElementAffectsIndexes) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{c: 0}, {c: 0}, {c: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{c: 0}, {c: 0}, {c: 0}]}"));
addIndexedPath("a.c");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.indexesAffected);
@@ -532,7 +531,7 @@ TEST_F(UpdateArrayNodeTest, WhenOneElementIsMatchedLogElementUpdateDirectly) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{c: 1}, {c: 0}, {c: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{c: 1}, {c: 0}, {c: 1}]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -557,7 +556,7 @@ TEST_F(UpdateArrayNodeTest, WhenOneElementIsModifiedLogElement) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{c: 0, b: 0}, {c: 0}, {c: 1}]}"));
+ mutablebson::Document doc(fromjson("{a: [{c: 0, b: 0}, {c: 0}, {c: 1}]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -580,7 +579,7 @@ TEST_F(UpdateArrayNodeTest, ArrayUpdateOnEmptyArrayIsANoop) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.indexesAffected);
@@ -605,7 +604,7 @@ TEST_F(UpdateArrayNodeTest, ApplyPositionalInsideArrayUpdate) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: [0, 0], c: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: [0, 0], c: 0}]}"));
addIndexedPath("a");
setMatchedField("1");
auto result = root.apply(getApplyParams(doc.root()));
@@ -631,7 +630,7 @@ TEST_F(UpdateArrayNodeTest, ApplyArrayUpdateFromReplication) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
addIndexedPath("a");
setFromReplication(true);
auto result = root.apply(getApplyParams(doc.root()));
@@ -657,7 +656,7 @@ TEST_F(UpdateArrayNodeTest, ApplyArrayUpdateNotFromReplication) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(root.apply(getApplyParams(doc.root())),
UserException,
@@ -680,7 +679,7 @@ TEST_F(UpdateArrayNodeTest, ApplyArrayUpdateWithoutLogBuilderOrIndexData) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [0]}"));
+ mutablebson::Document doc(fromjson("{a: [0]}"));
setLogBuilderToNull();
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.indexesAffected);
diff --git a/src/mongo/db/update/update_driver_test.cpp b/src/mongo/db/update/update_driver_test.cpp
index f37074ce24b..02b6ae0e442 100644
--- a/src/mongo/db/update/update_driver_test.cpp
+++ b/src/mongo/db/update/update_driver_test.cpp
@@ -47,7 +47,6 @@
namespace mongo {
namespace {
-using mongo::mutablebson::Document;
using mongoutils::str::stream;
TEST(Parse, Normal) {
@@ -163,7 +162,7 @@ TEST(Collator, SetCollationUpdatesModifierInterfaces) {
const bool validateForStorage = true;
const FieldRefSet emptyImmutablePaths;
bool modified = false;
- Document doc(fromjson("{a: 'cba'}"));
+ mutablebson::Document doc(fromjson("{a: 'cba'}"));
driver.setCollator(&collator);
driver
.update(StringData(),
@@ -195,7 +194,7 @@ public:
_opCtx = _serviceContext.makeOperationContext();
}
- Document& doc() {
+ mutablebson::Document& doc() {
return _doc;
}
@@ -217,7 +216,7 @@ private:
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> _arrayFilters;
std::unique_ptr<UpdateDriver> _driverOps;
std::unique_ptr<UpdateDriver> _driverRepl;
- Document _doc;
+ mutablebson::Document _doc;
};
// Make name nicer to report
diff --git a/src/mongo/db/update/update_object_node_test.cpp b/src/mongo/db/update/update_object_node_test.cpp
index 018719b827a..6bb3d2c51c8 100644
--- a/src/mongo/db/update/update_object_node_test.cpp
+++ b/src/mongo/db/update/update_object_node_test.cpp
@@ -45,7 +45,6 @@ namespace mongo {
namespace {
using UpdateObjectNodeTest = UpdateNodeTest;
-using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
TEST(UpdateObjectNodeTest, InvalidPathFailsToParse) {
@@ -1729,7 +1728,7 @@ TEST_F(UpdateObjectNodeTest, ApplyCreateField) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
addIndexedPath("b");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -1752,7 +1751,7 @@ TEST_F(UpdateObjectNodeTest, ApplyExistingField) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: 5}"));
+ mutablebson::Document doc(fromjson("{a: 5}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -1793,7 +1792,7 @@ TEST_F(UpdateObjectNodeTest, ApplyExistingAndNonexistingFields) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: 0, c: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0, c: 0}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -1834,7 +1833,7 @@ TEST_F(UpdateObjectNodeTest, ApplyExistingNestedPaths) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: {b: 5, c: 5}, b: {d: 5, e: 5}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 5, c: 5}, b: {d: 5, e: 5}}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -1876,7 +1875,7 @@ TEST_F(UpdateObjectNodeTest, ApplyCreateNestedPaths) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{z: 0}"));
+ mutablebson::Document doc(fromjson("{z: 0}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -1912,7 +1911,7 @@ TEST_F(UpdateObjectNodeTest, ApplyCreateDeeplyNestedPaths) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{z: 0}"));
+ mutablebson::Document doc(fromjson("{z: 0}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -1960,7 +1959,7 @@ TEST_F(UpdateObjectNodeTest, ChildrenShouldBeAppliedInAlphabeticalOrder) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{z: 0, a: 0}"));
+ mutablebson::Document doc(fromjson("{z: 0, a: 0}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -1989,7 +1988,7 @@ TEST_F(UpdateObjectNodeTest, CollatorShouldNotAffectUpdateOrder) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
addIndexedPath("abc");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -2024,7 +2023,7 @@ TEST_F(UpdateObjectNodeTest, ApplyNoop) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: 5, b: 6, c: 7}"));
+ mutablebson::Document doc(fromjson("{a: 5, b: 6, c: 7}"));
addIndexedPath("a");
addIndexedPath("b");
addIndexedPath("c");
@@ -2061,7 +2060,7 @@ TEST_F(UpdateObjectNodeTest, ApplySomeChildrenNoops) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: 5, b: 0, c: 7}"));
+ mutablebson::Document doc(fromjson("{a: 5, b: 0, c: 7}"));
addIndexedPath("a");
addIndexedPath("b");
addIndexedPath("c");
@@ -2086,7 +2085,7 @@ TEST_F(UpdateObjectNodeTest, ApplyBlockingElement) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(root.apply(getApplyParams(doc.root())),
UserException,
@@ -2113,7 +2112,7 @@ TEST_F(UpdateObjectNodeTest, ApplyBlockingElementFromReplication) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: 0}"));
+ mutablebson::Document doc(fromjson("{a: 0}"));
addIndexedPath("a");
setFromReplication(true);
auto result = root.apply(getApplyParams(doc.root()));
@@ -2137,7 +2136,7 @@ TEST_F(UpdateObjectNodeTest, ApplyPositionalMissingMatchedField) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(
root.apply(getApplyParams(doc.root())),
@@ -2165,7 +2164,7 @@ TEST_F(UpdateObjectNodeTest, ApplyMergePositionalChild) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: 0, c: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0, c: 0}]}"));
setMatchedField("0");
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
@@ -2207,7 +2206,7 @@ TEST_F(UpdateObjectNodeTest, ApplyOrderMergedPositionalChild) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setMatchedField("1");
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
@@ -2238,7 +2237,7 @@ TEST_F(UpdateObjectNodeTest, ApplyMergeConflictWithPositionalChild) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setMatchedField("0");
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(root.apply(getApplyParams(doc.root())),
@@ -2272,7 +2271,7 @@ TEST_F(UpdateObjectNodeTest, ApplyDoNotMergePositionalChild) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setMatchedField("1");
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
@@ -2308,7 +2307,7 @@ TEST_F(UpdateObjectNodeTest, ApplyPositionalChildLast) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{}"));
+ mutablebson::Document doc(fromjson("{}"));
setMatchedField("2");
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
@@ -2338,7 +2337,7 @@ TEST_F(UpdateObjectNodeTest, ApplyUseStoredMergedPositional) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: 0, c: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0, c: 0}]}"));
setMatchedField("0");
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
@@ -2348,7 +2347,7 @@ TEST_F(UpdateObjectNodeTest, ApplyUseStoredMergedPositional) {
ASSERT_TRUE(doc.isInPlaceModeEnabled());
ASSERT_BSONOBJ_EQ(fromjson("{$set: {'a.0.b': 5, 'a.0.c': 6}}"), getLogDoc().getObject());
- Document doc2(fromjson("{a: [{b: 0, c: 0}]}"));
+ mutablebson::Document doc2(fromjson("{a: [{b: 0, c: 0}]}"));
resetApplyParams();
setMatchedField("0");
addIndexedPath("a");
@@ -2385,7 +2384,7 @@ TEST_F(UpdateObjectNodeTest, ApplyDoNotUseStoredMergedPositional) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: 0, c: 0}, {c: 0, d: 0}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 0, c: 0}, {c: 0, d: 0}]}"));
setMatchedField("0");
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
@@ -2396,7 +2395,7 @@ TEST_F(UpdateObjectNodeTest, ApplyDoNotUseStoredMergedPositional) {
ASSERT_BSONOBJ_EQ(fromjson("{$set: {'a.0.b': 5, 'a.0.c': 6, 'a.1.d': 7}}"),
getLogDoc().getObject());
- Document doc2(fromjson("{a: [{b: 0, c: 0}, {c: 0, d: 0}]}"));
+ mutablebson::Document doc2(fromjson("{a: [{b: 0, c: 0}, {c: 0, d: 0}]}"));
resetApplyParams();
setMatchedField("1");
addIndexedPath("a");
@@ -2427,7 +2426,7 @@ TEST_F(UpdateObjectNodeTest, ApplyToArrayByIndexWithLeadingZero) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [0, 0, 0, 0, 0]}"));
+ mutablebson::Document doc(fromjson("{a: [0, 0, 0, 0, 0]}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -2462,7 +2461,7 @@ TEST_F(UpdateObjectNodeTest, ApplyMultipleArrayUpdates) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: []}"));
+ mutablebson::Document doc(fromjson("{a: []}"));
addIndexedPath("a");
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_TRUE(result.indexesAffected);
@@ -2487,7 +2486,7 @@ TEST_F(UpdateObjectNodeTest, ApplyUpdateToNonViablePathInArray) {
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: [{b: 1}, {b: 2}]}"));
+ mutablebson::Document doc(fromjson("{a: [{b: 1}, {b: 2}]}"));
addIndexedPath("a");
ASSERT_THROWS_CODE_AND_WHAT(root.apply(getApplyParams(doc.root())),
UserException,
@@ -2514,7 +2513,7 @@ TEST_F(UpdateObjectNodeTest, SetAndPopModifiersWithCommonPrefixApplySuccessfully
arrayFilters,
foundIdentifiers));
- Document doc(fromjson("{a: {b: 3, c: [1, 2, 3, 4]}}"));
+ mutablebson::Document doc(fromjson("{a: {b: 3, c: [1, 2, 3, 4]}}"));
auto result = root.apply(getApplyParams(doc.root()));
ASSERT_FALSE(result.indexesAffected);
ASSERT_FALSE(result.noop);
diff --git a/src/mongo/dbtests/extensions_callback_real_test.cpp b/src/mongo/dbtests/extensions_callback_real_test.cpp
index 7ea4e6a4af0..9c0105299d9 100644
--- a/src/mongo/dbtests/extensions_callback_real_test.cpp
+++ b/src/mongo/dbtests/extensions_callback_real_test.cpp
@@ -86,6 +86,15 @@ TEST_F(ExtensionsCallbackRealTest, TextNoIndex) {
ASSERT_EQ(ErrorCodes::IndexNotFound, result.getStatus());
}
+TEST_F(ExtensionsCallbackRealTest, TextRejectsExpr) {
+ BSONObj query = fromjson("{$text: {$expr: '$$userVar'}}");
+ StatusWithMatchExpression result =
+ ExtensionsCallbackReal(&_opCtx, &_nss).parseText(query.firstElement());
+
+ ASSERT_NOT_OK(result.getStatus());
+ ASSERT_EQ(ErrorCodes::NoSuchKey, result.getStatus());
+}
+
TEST_F(ExtensionsCallbackRealTest, TextBasic) {
ASSERT_OK(dbtests::createIndex(&_opCtx,
_nss.ns(),