summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/exec/collection_scan.cpp5
-rw-r--r--src/mongo/db/exec/geo_near.cpp4
-rw-r--r--src/mongo/db/exec/oplogstart.cpp5
-rw-r--r--src/mongo/db/matcher/expression_algo.cpp5
-rw-r--r--src/mongo/db/matcher/expression_algo_test.cpp4
-rw-r--r--src/mongo/db/matcher/expression_arity.h17
-rw-r--r--src/mongo/db/matcher/expression_array.cpp32
-rw-r--r--src/mongo/db/matcher/expression_array.h30
-rw-r--r--src/mongo/db/matcher/expression_array_test.cpp160
-rw-r--r--src/mongo/db/matcher/expression_geo.cpp48
-rw-r--r--src/mongo/db/matcher/expression_geo.h18
-rw-r--r--src/mongo/db/matcher/expression_geo_test.cpp14
-rw-r--r--src/mongo/db/matcher/expression_leaf.cpp165
-rw-r--r--src/mongo/db/matcher/expression_leaf.h176
-rw-r--r--src/mongo/db/matcher/expression_leaf_test.cpp831
-rw-r--r--src/mongo/db/matcher/expression_optimize_test.cpp2
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp411
-rw-r--r--src/mongo/db/matcher/expression_parser_tree.cpp19
-rw-r--r--src/mongo/db/matcher/expression_path.h19
-rw-r--r--src/mongo/db/matcher/expression_test.cpp38
-rw-r--r--src/mongo/db/matcher/expression_text.cpp62
-rw-r--r--src/mongo/db/matcher/expression_text.h3
-rw-r--r--src/mongo/db/matcher/expression_text_base.cpp3
-rw-r--r--src/mongo/db/matcher/expression_text_base.h2
-rw-r--r--src/mongo/db/matcher/expression_text_noop.cpp7
-rw-r--r--src/mongo/db/matcher/expression_text_noop.h2
-rw-r--r--src/mongo/db/matcher/expression_tree.cpp3
-rw-r--r--src/mongo/db/matcher/expression_tree.h16
-rw-r--r--src/mongo/db/matcher/expression_tree_test.cpp320
-rw-r--r--src/mongo/db/matcher/expression_type.h20
-rw-r--r--src/mongo/db/matcher/expression_type_test.cpp61
-rw-r--r--src/mongo/db/matcher/expression_where.cpp37
-rw-r--r--src/mongo/db/matcher/expression_where.h4
-rw-r--r--src/mongo/db/matcher/expression_where_base.h2
-rw-r--r--src/mongo/db/matcher/expression_where_noop.h2
-rw-r--r--src/mongo/db/matcher/extensions_callback_noop.cpp6
-rw-r--r--src/mongo/db/matcher/extensions_callback_real.cpp15
-rw-r--r--src/mongo/db/matcher/path.cpp17
-rw-r--r--src/mongo/db/matcher/path.h2
-rw-r--r--src/mongo/db/matcher/path_test.cpp32
-rw-r--r--src/mongo/db/matcher/rewrite_expr.cpp29
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.cpp12
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.h13
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.cpp32
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.h12
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_cond.h5
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_cond_test.cpp16
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_eq.cpp11
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_eq.h4
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_eq_test.cpp36
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_fmod.cpp24
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_fmod.h7
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_fmod_test.cpp39
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.cpp23
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.h8
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_max_items.h9
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_max_items_test.cpp21
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_max_length.h10
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_max_length_test.cpp51
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_max_properties.h7
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_max_properties_test.cpp30
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_min_items.h9
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_min_items_test.cpp21
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_min_length.h10
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_min_length_test.cpp45
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_min_properties.h7
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_min_properties_test.cpp24
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.cpp4
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.h11
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_num_properties.h11
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_object_match.cpp10
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_object_match.h7
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp15
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.cpp3
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.h11
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq_test.cpp32
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_str_length.cpp6
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_str_length.h11
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_unique_items.cpp3
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_unique_items.h8
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_unique_items_test.cpp27
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_xor_test.cpp6
-rw-r--r--src/mongo/db/matcher/schema/json_schema_parser.cpp191
-rw-r--r--src/mongo/db/pipeline/document_source_match.cpp4
-rw-r--r--src/mongo/db/query/planner_analysis_test.cpp4
-rw-r--r--src/mongo/dbtests/extensions_callback_real_test.cpp17
-rw-r--r--src/mongo/s/shard_key_pattern.cpp2
87 files changed, 1234 insertions, 2283 deletions
diff --git a/src/mongo/db/exec/collection_scan.cpp b/src/mongo/db/exec/collection_scan.cpp
index 168428779f7..a0cff1a7e81 100644
--- a/src/mongo/db/exec/collection_scan.cpp
+++ b/src/mongo/db/exec/collection_scan.cpp
@@ -72,9 +72,8 @@ CollectionScan::CollectionScan(OperationContext* opCtx,
if (params.maxTs) {
_endConditionBSON = BSON("$gte" << *(params.maxTs));
- _endCondition = stdx::make_unique<GTEMatchExpression>();
- invariantOK(_endCondition->init(repl::OpTime::kTimestampFieldName,
- _endConditionBSON.firstElement()));
+ _endCondition = stdx::make_unique<GTEMatchExpression>(repl::OpTime::kTimestampFieldName,
+ _endConditionBSON.firstElement());
}
}
diff --git a/src/mongo/db/exec/geo_near.cpp b/src/mongo/db/exec/geo_near.cpp
index 9da6af59370..d906efebc76 100644
--- a/src/mongo/db/exec/geo_near.cpp
+++ b/src/mongo/db/exec/geo_near.cpp
@@ -505,9 +505,7 @@ namespace {
class TwoDPtInAnnulusExpression : public LeafMatchExpression {
public:
TwoDPtInAnnulusExpression(const R2Annulus& annulus, StringData twoDPath)
- : LeafMatchExpression(INTERNAL_2D_POINT_IN_ANNULUS), _annulus(annulus) {
- setPath(twoDPath).transitional_ignore();
- }
+ : LeafMatchExpression(INTERNAL_2D_POINT_IN_ANNULUS, twoDPath), _annulus(annulus) {}
void serialize(BSONObjBuilder* out) const final {
out->append("TwoDPtInAnnulusExpression", true);
diff --git a/src/mongo/db/exec/oplogstart.cpp b/src/mongo/db/exec/oplogstart.cpp
index 9b7659b3a13..4cb85047051 100644
--- a/src/mongo/db/exec/oplogstart.cpp
+++ b/src/mongo/db/exec/oplogstart.cpp
@@ -55,9 +55,8 @@ OplogStart::OplogStart(OperationContext* opCtx,
_done(false),
_collection(collection),
_workingSet(ws),
- _filterBSON(BSON("$lte" << timestamp)) {
- invariantOK(_filter.init(repl::OpTime::kTimestampFieldName, _filterBSON.firstElement()));
-}
+ _filterBSON(BSON("$lte" << timestamp)),
+ _filter(repl::OpTime::kTimestampFieldName, _filterBSON.firstElement()) {}
PlanStage::StageState OplogStart::doWork(WorkingSetID* out) {
// We do our (heavy) init in a work(), where work is expected.
diff --git a/src/mongo/db/matcher/expression_algo.cpp b/src/mongo/db/matcher/expression_algo.cpp
index 44791145805..e0575431de8 100644
--- a/src/mongo/db/matcher/expression_algo.cpp
+++ b/src/mongo/db/matcher/expression_algo.cpp
@@ -153,8 +153,7 @@ bool _isSubsetOf(const MatchExpression* lhs, const ComparisonMatchExpression* rh
}
for (BSONElement elem : ime->getEqualities()) {
// Each element in the $in-array represents an equality predicate.
- EqualityMatchExpression equality;
- equality.init(lhs->path(), elem).transitional_ignore();
+ EqualityMatchExpression equality(lhs->path(), elem);
equality.setCollator(ime->getCollator());
if (!_isSubsetOf(&equality, rhs)) {
return false;
@@ -179,7 +178,7 @@ bool _isSubsetOf(const MatchExpression* lhs, const ExistsMatchExpression* rhs) {
if (ComparisonMatchExpression::isComparisonMatchExpression(lhs)) {
const ComparisonMatchExpression* cme = static_cast<const ComparisonMatchExpression*>(lhs);
- // CompareMatchExpression::init() prohibits creating a match expression with EOO or
+ // The CompareMatchExpression constructor prohibits creating a match expression with EOO or
// Undefined types, so only need to ensure that the value is not of type jstNULL.
return cme->getData().type() != jstNULL;
}
diff --git a/src/mongo/db/matcher/expression_algo_test.cpp b/src/mongo/db/matcher/expression_algo_test.cpp
index d1ec11137dd..49198f799dc 100644
--- a/src/mongo/db/matcher/expression_algo_test.cpp
+++ b/src/mongo/db/matcher/expression_algo_test.cpp
@@ -70,8 +70,8 @@ private:
};
TEST(ExpressionAlgoIsSubsetOf, NullAndOmittedField) {
- // Verify that ComparisonMatchExpression::init() prohibits creating a match expression with
- // an Undefined type.
+ // Verify that the ComparisonMatchExpression constructor prohibits creating a match expression
+ // with an Undefined type.
BSONObj undefined = fromjson("{a: undefined}");
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
ASSERT_EQUALS(ErrorCodes::BadValue,
diff --git a/src/mongo/db/matcher/expression_arity.h b/src/mongo/db/matcher/expression_arity.h
index e6f71395941..a2b5734c1e1 100644
--- a/src/mongo/db/matcher/expression_arity.h
+++ b/src/mongo/db/matcher/expression_arity.h
@@ -93,13 +93,6 @@ public:
}
/**
- * Takes ownership of the MatchExpressions in 'expressions'.
- */
- void init(std::array<std::unique_ptr<MatchExpression>, nargs> expressions) {
- _expressions = std::move(expressions);
- }
-
- /**
* The name of this MatchExpression.
*/
virtual StringData name() const = 0;
@@ -121,7 +114,6 @@ public:
* Clones this MatchExpression by recursively cloning each sub-expression.
*/
std::unique_ptr<MatchExpression> shallowClone() const final {
- std::unique_ptr<T> clone = stdx::make_unique<T>();
std::array<std::unique_ptr<MatchExpression>, nargs> clonedExpressions;
std::transform(_expressions.begin(),
_expressions.end(),
@@ -130,7 +122,7 @@ public:
return orig ? orig->shallowClone()
: std::unique_ptr<MatchExpression>(nullptr);
});
- clone->_expressions = std::move(clonedExpressions);
+ std::unique_ptr<T> clone = stdx::make_unique<T>(std::move(clonedExpressions));
if (getTag()) {
clone->setTag(getTag()->clone());
@@ -140,7 +132,12 @@ public:
}
protected:
- explicit FixedArityMatchExpression(MatchType type) : MatchExpression(type) {}
+ /**
+ * Takes ownership of the MatchExpressions in 'expressions'.
+ */
+ explicit FixedArityMatchExpression(
+ MatchType type, std::array<std::unique_ptr<MatchExpression>, nargs> expressions)
+ : MatchExpression(type), _expressions(std::move(expressions)) {}
const auto& expressions() const {
return _expressions;
diff --git a/src/mongo/db/matcher/expression_array.cpp b/src/mongo/db/matcher/expression_array.cpp
index 84c544df2bf..e4c9af9a024 100644
--- a/src/mongo/db/matcher/expression_array.cpp
+++ b/src/mongo/db/matcher/expression_array.cpp
@@ -67,10 +67,9 @@ bool ArrayMatchingMatchExpression::equivalent(const MatchExpression* other) cons
// -------
-Status ElemMatchObjectMatchExpression::init(StringData path, MatchExpression* sub) {
- _sub.reset(sub);
- return setPath(path);
-}
+ElemMatchObjectMatchExpression::ElemMatchObjectMatchExpression(StringData path,
+ MatchExpression* sub)
+ : ArrayMatchingMatchExpression(ELEM_MATCH_OBJECT, path), _sub(sub) {}
bool ElemMatchObjectMatchExpression::matchesArray(const BSONObj& anArray,
MatchDetails* details) const {
@@ -119,23 +118,20 @@ MatchExpression::ExpressionOptimizerFunc ElemMatchObjectMatchExpression::getOpti
// -------
+ElemMatchValueMatchExpression::ElemMatchValueMatchExpression(StringData path, MatchExpression* sub)
+ : ArrayMatchingMatchExpression(ELEM_MATCH_VALUE, path) {
+ add(sub);
+}
+
+ElemMatchValueMatchExpression::ElemMatchValueMatchExpression(StringData path)
+ : ArrayMatchingMatchExpression(ELEM_MATCH_VALUE, path) {}
+
ElemMatchValueMatchExpression::~ElemMatchValueMatchExpression() {
for (unsigned i = 0; i < _subs.size(); i++)
delete _subs[i];
_subs.clear();
}
-Status ElemMatchValueMatchExpression::init(StringData path, MatchExpression* sub) {
- init(path).transitional_ignore();
- add(sub);
- return Status::OK();
-}
-
-Status ElemMatchValueMatchExpression::init(StringData path) {
- return setPath(path);
-}
-
-
void ElemMatchValueMatchExpression::add(MatchExpression* sub) {
verify(sub);
_subs.push_back(sub);
@@ -208,10 +204,8 @@ MatchExpression::ExpressionOptimizerFunc ElemMatchValueMatchExpression::getOptim
// ---------
-Status SizeMatchExpression::init(StringData path, int size) {
- _size = size;
- return setPath(path);
-}
+SizeMatchExpression::SizeMatchExpression(StringData path, int size)
+ : ArrayMatchingMatchExpression(SIZE, path), _size(size) {}
bool SizeMatchExpression::matchesArray(const BSONObj& anArray, MatchDetails* details) const {
if (_size < 0)
diff --git a/src/mongo/db/matcher/expression_array.h b/src/mongo/db/matcher/expression_array.h
index f4090c0a8b0..4cf54f43677 100644
--- a/src/mongo/db/matcher/expression_array.h
+++ b/src/mongo/db/matcher/expression_array.h
@@ -45,7 +45,10 @@ namespace mongo {
*/
class ArrayMatchingMatchExpression : public PathMatchExpression {
public:
- ArrayMatchingMatchExpression(MatchType matchType) : PathMatchExpression(matchType) {}
+ ArrayMatchingMatchExpression(MatchType matchType, StringData path)
+ : PathMatchExpression(matchType, path) {
+ setTraverseLeafArray();
+ }
virtual ~ArrayMatchingMatchExpression() {}
@@ -71,15 +74,14 @@ public:
class ElemMatchObjectMatchExpression : public ArrayMatchingMatchExpression {
public:
- ElemMatchObjectMatchExpression() : ArrayMatchingMatchExpression(ELEM_MATCH_OBJECT) {}
- Status init(StringData path, MatchExpression* sub);
+ ElemMatchObjectMatchExpression(StringData path, MatchExpression* sub);
bool matchesArray(const BSONObj& anArray, MatchDetails* details) const;
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ElemMatchObjectMatchExpression> e =
- stdx::make_unique<ElemMatchObjectMatchExpression>();
- e->init(path(), _sub->shallowClone().release()).transitional_ignore();
+ stdx::make_unique<ElemMatchObjectMatchExpression>(path(),
+ _sub->shallowClone().release());
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -118,19 +120,20 @@ private:
class ElemMatchValueMatchExpression : public ArrayMatchingMatchExpression {
public:
- ElemMatchValueMatchExpression() : ArrayMatchingMatchExpression(ELEM_MATCH_VALUE) {}
+ /**
+ * This constructor takes ownership of 'sub.'
+ */
+ ElemMatchValueMatchExpression(StringData path, MatchExpression* sub);
+ explicit ElemMatchValueMatchExpression(StringData path);
virtual ~ElemMatchValueMatchExpression();
- Status init(StringData path);
- Status init(StringData path, MatchExpression* sub);
void add(MatchExpression* sub);
bool matchesArray(const BSONObj& anArray, MatchDetails* details) const;
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ElemMatchValueMatchExpression> e =
- stdx::make_unique<ElemMatchValueMatchExpression>();
- e->init(path()).transitional_ignore();
+ stdx::make_unique<ElemMatchValueMatchExpression>(path());
for (size_t i = 0; i < _subs.size(); ++i) {
e->add(_subs[i]->shallowClone().release());
}
@@ -166,12 +169,11 @@ private:
class SizeMatchExpression : public ArrayMatchingMatchExpression {
public:
- SizeMatchExpression() : ArrayMatchingMatchExpression(SIZE) {}
- Status init(StringData path, int size);
+ SizeMatchExpression(StringData path, int size);
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<SizeMatchExpression> e = stdx::make_unique<SizeMatchExpression>();
- e->init(path(), _size).transitional_ignore();
+ std::unique_ptr<SizeMatchExpression> e =
+ stdx::make_unique<SizeMatchExpression>(path(), _size);
if (getTag()) {
e->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/expression_array_test.cpp b/src/mongo/db/matcher/expression_array_test.cpp
index 6b7d0c9a851..4d014818c2d 100644
--- a/src/mongo/db/matcher/expression_array_test.cpp
+++ b/src/mongo/db/matcher/expression_array_test.cpp
@@ -45,10 +45,8 @@ TEST(ElemMatchObjectMatchExpression, MatchesElementSingle) {
BSONObj baseOperand = BSON("b" << 5);
BSONObj match = BSON("a" << BSON_ARRAY(BSON("b" << 5.0)));
BSONObj notMatch = BSON("a" << BSON_ARRAY(BSON("b" << 6)));
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("b", baseOperand["b"]).isOK());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a", eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("b", baseOperand["b"]));
+ ElemMatchObjectMatchExpression op("a", eq.release());
ASSERT(op.matchesSingleElement(match["a"]));
ASSERT(!op.matchesSingleElement(notMatch["a"]));
}
@@ -57,10 +55,8 @@ TEST(ElemMatchObjectMatchExpression, MatchesElementArray) {
BSONObj baseOperand = BSON("1" << 5);
BSONObj match = BSON("a" << BSON_ARRAY(BSON_ARRAY('s' << 5.0)));
BSONObj notMatch = BSON("a" << BSON_ARRAY(BSON_ARRAY(5 << 6)));
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("1", baseOperand["1"]).isOK());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a", eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("1", baseOperand["1"]));
+ ElemMatchObjectMatchExpression op("a", eq.release());
ASSERT(op.matchesSingleElement(match["a"]));
ASSERT(!op.matchesSingleElement(notMatch["a"]));
}
@@ -73,20 +69,16 @@ TEST(ElemMatchObjectMatchExpression, MatchesElementMultiple) {
BSONObj notMatch2 = BSON("a" << BSON_ARRAY(BSON("b" << 6 << "c" << 7)));
BSONObj notMatch3 = BSON("a" << BSON_ARRAY(BSON("b" << BSON_ARRAY(5 << 6))));
BSONObj match = BSON("a" << BSON_ARRAY(BSON("b" << BSON_ARRAY(5 << 6) << "c" << 7)));
- unique_ptr<ComparisonMatchExpression> eq1(new EqualityMatchExpression());
- ASSERT(eq1->init("b", baseOperand1["b"]).isOK());
- unique_ptr<ComparisonMatchExpression> eq2(new EqualityMatchExpression());
- ASSERT(eq2->init("b", baseOperand2["b"]).isOK());
- unique_ptr<ComparisonMatchExpression> eq3(new EqualityMatchExpression());
- ASSERT(eq3->init("c", baseOperand3["c"]).isOK());
+ unique_ptr<ComparisonMatchExpression> eq1(new EqualityMatchExpression("b", baseOperand1["b"]));
+ unique_ptr<ComparisonMatchExpression> eq2(new EqualityMatchExpression("b", baseOperand2["b"]));
+ unique_ptr<ComparisonMatchExpression> eq3(new EqualityMatchExpression("c", baseOperand3["c"]));
unique_ptr<AndMatchExpression> andOp(new AndMatchExpression());
andOp->add(eq1.release());
andOp->add(eq2.release());
andOp->add(eq3.release());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a", andOp.release()).isOK());
+ ElemMatchObjectMatchExpression op("a", andOp.release());
ASSERT(!op.matchesSingleElement(notMatch1["a"]));
ASSERT(!op.matchesSingleElement(notMatch2["a"]));
ASSERT(!op.matchesSingleElement(notMatch3["a"]));
@@ -95,10 +87,8 @@ TEST(ElemMatchObjectMatchExpression, MatchesElementMultiple) {
TEST(ElemMatchObjectMatchExpression, MatchesNonArray) {
BSONObj baseOperand = BSON("b" << 5);
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("b", baseOperand["b"]).isOK());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a", eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("b", baseOperand["b"]));
+ ElemMatchObjectMatchExpression op("a", eq.release());
// Directly nested objects are not matched with $elemMatch. An intervening array is
// required.
ASSERT(!op.matchesBSON(BSON("a" << BSON("b" << 5)), NULL));
@@ -108,10 +98,8 @@ TEST(ElemMatchObjectMatchExpression, MatchesNonArray) {
TEST(ElemMatchObjectMatchExpression, MatchesArrayObject) {
BSONObj baseOperand = BSON("b" << 5);
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("b", baseOperand["b"]).isOK());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a", eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("b", baseOperand["b"]));
+ ElemMatchObjectMatchExpression op("a", eq.release());
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(BSON("b" << 5))), NULL));
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(4 << BSON("b" << 5))), NULL));
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(BSONObj() << BSON("b" << 5))), NULL));
@@ -120,10 +108,8 @@ TEST(ElemMatchObjectMatchExpression, MatchesArrayObject) {
TEST(ElemMatchObjectMatchExpression, MatchesMultipleNamedValues) {
BSONObj baseOperand = BSON("c" << 5);
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("c", baseOperand["c"]).isOK());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a.b", eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("c", baseOperand["c"]));
+ ElemMatchObjectMatchExpression op("a.b", eq.release());
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(BSON("b" << BSON_ARRAY(BSON("c" << 5))))), NULL));
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(BSON("b" << BSON_ARRAY(BSON("c" << 1)))
<< BSON("b" << BSON_ARRAY(BSON("c" << 5))))),
@@ -132,10 +118,8 @@ TEST(ElemMatchObjectMatchExpression, MatchesMultipleNamedValues) {
TEST(ElemMatchObjectMatchExpression, ElemMatchKey) {
BSONObj baseOperand = BSON("c" << 6);
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("c", baseOperand["c"]).isOK());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a.b", eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("c", baseOperand["c"]));
+ ElemMatchObjectMatchExpression op("a.b", eq.release());
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!op.matchesBSON(BSONObj(), &details));
@@ -161,10 +145,8 @@ TEST(ElemMatchObjectMatchExpression, Collation) {
<< "string")));
BSONObj notMatch = BSON("a" << BSON_ARRAY(BSON("b"
<< "string2")));
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("b", baseOperand["b"]).isOK());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a", eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("b", baseOperand["b"]));
+ ElemMatchObjectMatchExpression op("a", eq.release());
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
op.setCollator(&collator);
ASSERT(op.matchesSingleElement(match["a"]));
@@ -189,10 +171,8 @@ TEST(ElemMatchValueMatchExpression, MatchesElementSingle) {
BSONObj baseOperand = BSON("$gt" << 5);
BSONObj match = BSON("a" << BSON_ARRAY(6));
BSONObj notMatch = BSON("a" << BSON_ARRAY(4));
- unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression());
- ASSERT(gt->init("", baseOperand["$gt"]).isOK());
- ElemMatchValueMatchExpression op;
- ASSERT(op.init("a", gt.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression("", baseOperand["$gt"]));
+ ElemMatchValueMatchExpression op("a", gt.release());
ASSERT(op.matchesSingleElement(match["a"]));
ASSERT(!op.matchesSingleElement(notMatch["a"]));
}
@@ -203,13 +183,10 @@ TEST(ElemMatchValueMatchExpression, MatchesElementMultiple) {
BSONObj notMatch1 = BSON("a" << BSON_ARRAY(0 << 1));
BSONObj notMatch2 = BSON("a" << BSON_ARRAY(10 << 11));
BSONObj match = BSON("a" << BSON_ARRAY(0 << 5 << 11));
- unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression());
- ASSERT(gt->init("", baseOperand1["$gt"]).isOK());
- unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression());
- ASSERT(lt->init("", baseOperand2["$lt"]).isOK());
+ unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression("", baseOperand1["$gt"]));
+ unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression("", baseOperand2["$lt"]));
- ElemMatchValueMatchExpression op;
- ASSERT(op.init("a").isOK());
+ ElemMatchValueMatchExpression op("a");
op.add(gt.release());
op.add(lt.release());
@@ -220,10 +197,8 @@ TEST(ElemMatchValueMatchExpression, MatchesElementMultiple) {
TEST(ElemMatchValueMatchExpression, MatchesNonArray) {
BSONObj baseOperand = BSON("$gt" << 5);
- unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression());
- ASSERT(gt->init("", baseOperand["$gt"]).isOK());
- ElemMatchObjectMatchExpression op;
- ASSERT(op.init("a", gt.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression("", baseOperand["$gt"]));
+ ElemMatchObjectMatchExpression op("a", gt.release());
// Directly nested objects are not matched with $elemMatch. An intervening array is
// required.
ASSERT(!op.matchesBSON(BSON("a" << 6), NULL));
@@ -232,10 +207,8 @@ TEST(ElemMatchValueMatchExpression, MatchesNonArray) {
TEST(ElemMatchValueMatchExpression, MatchesArrayScalar) {
BSONObj baseOperand = BSON("$gt" << 5);
- unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression());
- ASSERT(gt->init("", baseOperand["$gt"]).isOK());
- ElemMatchValueMatchExpression op;
- ASSERT(op.init("a", gt.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression("", baseOperand["$gt"]));
+ ElemMatchValueMatchExpression op("a", gt.release());
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(6)), NULL));
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(4 << 6)), NULL));
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(BSONObj() << 7)), NULL));
@@ -243,10 +216,8 @@ TEST(ElemMatchValueMatchExpression, MatchesArrayScalar) {
TEST(ElemMatchValueMatchExpression, MatchesMultipleNamedValues) {
BSONObj baseOperand = BSON("$gt" << 5);
- unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression());
- ASSERT(gt->init("", baseOperand["$gt"]).isOK());
- ElemMatchValueMatchExpression op;
- ASSERT(op.init("a.b", gt.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression("", baseOperand["$gt"]));
+ ElemMatchValueMatchExpression op("a.b", gt.release());
ASSERT(op.matchesBSON(BSON("a" << BSON_ARRAY(BSON("b" << BSON_ARRAY(6)))), NULL));
ASSERT(op.matchesBSON(
BSON("a" << BSON_ARRAY(BSON("b" << BSON_ARRAY(4)) << BSON("b" << BSON_ARRAY(4 << 6)))),
@@ -255,10 +226,8 @@ TEST(ElemMatchValueMatchExpression, MatchesMultipleNamedValues) {
TEST(ElemMatchValueMatchExpression, ElemMatchKey) {
BSONObj baseOperand = BSON("$gt" << 6);
- unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression());
- ASSERT(gt->init("", baseOperand["$gt"]).isOK());
- ElemMatchValueMatchExpression op;
- ASSERT(op.init("a.b", gt.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> gt(new GTMatchExpression("", baseOperand["$gt"]));
+ ElemMatchValueMatchExpression op("a.b", gt.release());
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!op.matchesBSON(BSONObj(), &details));
@@ -292,37 +261,37 @@ TEST( ElemMatchValueMatchExpression, MatchesIndexKey ) {
TEST(AndOfElemMatch, MatchesElement) {
BSONObj baseOperanda1 = BSON("a" << 1);
- unique_ptr<ComparisonMatchExpression> eqa1(new EqualityMatchExpression());
- ASSERT(eqa1->init("a", baseOperanda1["a"]).isOK());
+ unique_ptr<ComparisonMatchExpression> eqa1(
+ new EqualityMatchExpression("a", baseOperanda1["a"]));
BSONObj baseOperandb1 = BSON("b" << 1);
- unique_ptr<ComparisonMatchExpression> eqb1(new EqualityMatchExpression());
- ASSERT(eqb1->init("b", baseOperandb1["b"]).isOK());
+ unique_ptr<ComparisonMatchExpression> eqb1(
+ new EqualityMatchExpression("b", baseOperandb1["b"]));
unique_ptr<AndMatchExpression> and1(new AndMatchExpression());
and1->add(eqa1.release());
and1->add(eqb1.release());
// and1 = { a : 1, b : 1 }
- unique_ptr<ElemMatchObjectMatchExpression> elemMatch1(new ElemMatchObjectMatchExpression());
- elemMatch1->init("x", and1.release()).transitional_ignore();
+ unique_ptr<ElemMatchObjectMatchExpression> elemMatch1(
+ new ElemMatchObjectMatchExpression("x", and1.release()));
// elemMatch1 = { x : { $elemMatch : { a : 1, b : 1 } } }
BSONObj baseOperanda2 = BSON("a" << 2);
- unique_ptr<ComparisonMatchExpression> eqa2(new EqualityMatchExpression());
- ASSERT(eqa2->init("a", baseOperanda2["a"]).isOK());
+ unique_ptr<ComparisonMatchExpression> eqa2(
+ new EqualityMatchExpression("a", baseOperanda2["a"]));
BSONObj baseOperandb2 = BSON("b" << 2);
- unique_ptr<ComparisonMatchExpression> eqb2(new EqualityMatchExpression());
- ASSERT(eqb2->init("b", baseOperandb2["b"]).isOK());
+ unique_ptr<ComparisonMatchExpression> eqb2(
+ new EqualityMatchExpression("b", baseOperandb2["b"]));
unique_ptr<AndMatchExpression> and2(new AndMatchExpression());
and2->add(eqa2.release());
and2->add(eqb2.release());
// and2 = { a : 2, b : 2 }
- unique_ptr<ElemMatchObjectMatchExpression> elemMatch2(new ElemMatchObjectMatchExpression());
- elemMatch2->init("x", and2.release()).transitional_ignore();
+ unique_ptr<ElemMatchObjectMatchExpression> elemMatch2(
+ new ElemMatchObjectMatchExpression("x", and2.release()));
// elemMatch2 = { x : { $elemMatch : { a : 2, b : 2 } } }
unique_ptr<AndMatchExpression> andOfEM(new AndMatchExpression());
@@ -349,29 +318,23 @@ TEST(AndOfElemMatch, MatchesElement) {
TEST(AndOfElemMatch, Matches) {
BSONObj baseOperandgt1 = BSON("$gt" << 1);
- unique_ptr<ComparisonMatchExpression> gt1(new GTMatchExpression());
- ASSERT(gt1->init("", baseOperandgt1["$gt"]).isOK());
+ unique_ptr<ComparisonMatchExpression> gt1(new GTMatchExpression("", baseOperandgt1["$gt"]));
BSONObj baseOperandlt1 = BSON("$lt" << 10);
- unique_ptr<ComparisonMatchExpression> lt1(new LTMatchExpression());
- ASSERT(lt1->init("", baseOperandlt1["$lt"]).isOK());
+ unique_ptr<ComparisonMatchExpression> lt1(new LTMatchExpression("", baseOperandlt1["$lt"]));
- unique_ptr<ElemMatchValueMatchExpression> elemMatch1(new ElemMatchValueMatchExpression());
- elemMatch1->init("x").transitional_ignore();
+ unique_ptr<ElemMatchValueMatchExpression> elemMatch1(new ElemMatchValueMatchExpression("x"));
elemMatch1->add(gt1.release());
elemMatch1->add(lt1.release());
// elemMatch1 = { x : { $elemMatch : { $gt : 1 , $lt : 10 } } }
BSONObj baseOperandgt2 = BSON("$gt" << 101);
- unique_ptr<ComparisonMatchExpression> gt2(new GTMatchExpression());
- ASSERT(gt2->init("", baseOperandgt2["$gt"]).isOK());
+ unique_ptr<ComparisonMatchExpression> gt2(new GTMatchExpression("", baseOperandgt2["$gt"]));
BSONObj baseOperandlt2 = BSON("$lt" << 110);
- unique_ptr<ComparisonMatchExpression> lt2(new LTMatchExpression());
- ASSERT(lt2->init("", baseOperandlt2["$lt"]).isOK());
+ unique_ptr<ComparisonMatchExpression> lt2(new LTMatchExpression("", baseOperandlt2["$lt"]));
- unique_ptr<ElemMatchValueMatchExpression> elemMatch2(new ElemMatchValueMatchExpression());
- elemMatch2->init("x").transitional_ignore();
+ unique_ptr<ElemMatchValueMatchExpression> elemMatch2(new ElemMatchValueMatchExpression("x"));
elemMatch2->add(gt2.release());
elemMatch2->add(lt2.release());
// elemMatch2 = { x : { $elemMatch : { $gt : 101 , $lt : 110 } } }
@@ -399,8 +362,7 @@ TEST(AndOfElemMatch, Matches) {
TEST(SizeMatchExpression, MatchesElement) {
BSONObj match = BSON("a" << BSON_ARRAY(5 << 6));
BSONObj notMatch = BSON("a" << BSON_ARRAY(5));
- SizeMatchExpression size;
- ASSERT(size.init("", 2).isOK());
+ SizeMatchExpression size("", 2);
ASSERT(size.matchesSingleElement(match.firstElement()));
ASSERT(!size.matchesSingleElement(notMatch.firstElement()));
}
@@ -411,31 +373,27 @@ TEST(SizeMatchExpression, MatchesNonArray) {
<< "z");
BSONObj numberValue = BSON("a" << 0);
BSONObj arrayValue = BSON("a" << BSONArray());
- SizeMatchExpression size;
- ASSERT(size.init("", 0).isOK());
+ SizeMatchExpression size("", 0);
ASSERT(!size.matchesSingleElement(stringValue.firstElement()));
ASSERT(!size.matchesSingleElement(numberValue.firstElement()));
ASSERT(size.matchesSingleElement(arrayValue.firstElement()));
}
TEST(SizeMatchExpression, MatchesArray) {
- SizeMatchExpression size;
- ASSERT(size.init("a", 2).isOK());
+ SizeMatchExpression size("a", 2);
ASSERT(size.matchesBSON(BSON("a" << BSON_ARRAY(4 << 5.5)), NULL));
// Arrays are not unwound to look for matching subarrays.
ASSERT(!size.matchesBSON(BSON("a" << BSON_ARRAY(4 << 5.5 << BSON_ARRAY(1 << 2))), NULL));
}
TEST(SizeMatchExpression, MatchesNestedArray) {
- SizeMatchExpression size;
- ASSERT(size.init("a.2", 2).isOK());
+ SizeMatchExpression size("a.2", 2);
// A numerically referenced nested array is matched.
ASSERT(size.matchesBSON(BSON("a" << BSON_ARRAY(4 << 5.5 << BSON_ARRAY(1 << 2))), NULL));
}
TEST(SizeMatchExpression, ElemMatchKey) {
- SizeMatchExpression size;
- ASSERT(size.init("a.b", 3).isOK());
+ SizeMatchExpression size("a.b", 3);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!size.matchesBSON(BSON("a" << 1), &details));
@@ -449,13 +407,9 @@ TEST(SizeMatchExpression, ElemMatchKey) {
}
TEST(SizeMatchExpression, Equivalent) {
- SizeMatchExpression e1;
- SizeMatchExpression e2;
- SizeMatchExpression e3;
-
- e1.init("a", 5).transitional_ignore();
- e2.init("a", 6).transitional_ignore();
- e3.init("v", 5).transitional_ignore();
+ SizeMatchExpression e1("a", 5);
+ SizeMatchExpression e2("a", 6);
+ SizeMatchExpression e3("v", 5);
ASSERT(e1.equivalent(&e1));
ASSERT(!e1.equivalent(&e2));
diff --git a/src/mongo/db/matcher/expression_geo.cpp b/src/mongo/db/matcher/expression_geo.cpp
index 90ed78ecaa7..5cab016b9b9 100644
--- a/src/mongo/db/matcher/expression_geo.cpp
+++ b/src/mongo/db/matcher/expression_geo.cpp
@@ -329,13 +329,21 @@ Status GeoNearExpression::parseFrom(const BSONObj& obj) {
// Geo queries we don't need an index to answer: geoWithin and geoIntersects
//
-Status GeoMatchExpression::init(StringData path,
- const GeoExpression* query,
- const BSONObj& rawObj) {
- _query.reset(query);
- _rawObj = rawObj;
- return setPath(path);
-}
+/**
+* Takes ownership of the passed-in GeoExpression.
+*/
+GeoMatchExpression::GeoMatchExpression(StringData path,
+ const GeoExpression* query,
+ const BSONObj& rawObj)
+ : LeafMatchExpression(GEO, path), _rawObj(rawObj), _query(query), _canSkipValidation(false) {}
+
+/**
+* Takes shared ownership of the passed-in GeoExpression.
+*/
+GeoMatchExpression::GeoMatchExpression(StringData path,
+ std::shared_ptr<const GeoExpression> query,
+ const BSONObj& rawObj)
+ : LeafMatchExpression(GEO, path), _rawObj(rawObj), _query(query), _canSkipValidation(false) {}
bool GeoMatchExpression::matchesSingleElement(const BSONElement& e, MatchDetails* details) const {
if (!e.isABSONObj())
@@ -398,9 +406,8 @@ bool GeoMatchExpression::equivalent(const MatchExpression* other) const {
}
std::unique_ptr<MatchExpression> GeoMatchExpression::shallowClone() const {
- std::unique_ptr<GeoMatchExpression> next = stdx::make_unique<GeoMatchExpression>();
- next->init(path(), NULL, _rawObj).transitional_ignore();
- next->_query = _query;
+ std::unique_ptr<GeoMatchExpression> next =
+ stdx::make_unique<GeoMatchExpression>(path(), _query, _rawObj);
next->_canSkipValidation = _canSkipValidation;
if (getTag()) {
next->setTag(getTag()->clone());
@@ -412,13 +419,15 @@ std::unique_ptr<MatchExpression> GeoMatchExpression::shallowClone() const {
// Parse-only geo expressions: geoNear (formerly known as near).
//
-Status GeoNearMatchExpression::init(StringData path,
- const GeoNearExpression* query,
- const BSONObj& rawObj) {
- _query.reset(query);
- _rawObj = rawObj;
- return setPath(path);
-}
+GeoNearMatchExpression::GeoNearMatchExpression(StringData path,
+ const GeoNearExpression* query,
+ const BSONObj& rawObj)
+ : LeafMatchExpression(GEO_NEAR, path), _rawObj(rawObj), _query(query) {}
+
+GeoNearMatchExpression::GeoNearMatchExpression(StringData path,
+ std::shared_ptr<const GeoNearExpression> query,
+ const BSONObj& rawObj)
+ : LeafMatchExpression(GEO_NEAR, path), _rawObj(rawObj), _query(query) {}
bool GeoNearMatchExpression::matchesSingleElement(const BSONElement& e,
MatchDetails* details) const {
@@ -455,9 +464,8 @@ bool GeoNearMatchExpression::equivalent(const MatchExpression* other) const {
}
std::unique_ptr<MatchExpression> GeoNearMatchExpression::shallowClone() const {
- std::unique_ptr<GeoNearMatchExpression> next = stdx::make_unique<GeoNearMatchExpression>();
- next->init(path(), NULL, _rawObj).transitional_ignore();
- next->_query = _query;
+ std::unique_ptr<GeoNearMatchExpression> next =
+ stdx::make_unique<GeoNearMatchExpression>(path(), _query, _rawObj);
if (getTag()) {
next->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/expression_geo.h b/src/mongo/db/matcher/expression_geo.h
index 87b9624a5be..34b015484e6 100644
--- a/src/mongo/db/matcher/expression_geo.h
+++ b/src/mongo/db/matcher/expression_geo.h
@@ -78,15 +78,13 @@ private:
class GeoMatchExpression : public LeafMatchExpression {
public:
- GeoMatchExpression() : LeafMatchExpression(GEO), _canSkipValidation(false) {}
+ GeoMatchExpression(StringData path, const GeoExpression* query, const BSONObj& rawObj);
+ GeoMatchExpression(StringData path,
+ std::shared_ptr<const GeoExpression> query,
+ const BSONObj& rawObj);
virtual ~GeoMatchExpression() {}
- /**
- * Takes ownership of the passed-in GeoExpression.
- */
- Status init(StringData path, const GeoExpression* query, const BSONObj& rawObj);
-
bool matchesSingleElement(const BSONElement&, MatchDetails* details = nullptr) const final;
virtual void debugString(StringBuilder& debug, int level = 0) const;
@@ -167,10 +165,12 @@ private:
class GeoNearMatchExpression : public LeafMatchExpression {
public:
- GeoNearMatchExpression() : LeafMatchExpression(GEO_NEAR) {}
- virtual ~GeoNearMatchExpression() {}
+ GeoNearMatchExpression(StringData path, const GeoNearExpression* query, const BSONObj& rawObj);
+ GeoNearMatchExpression(StringData path,
+ std::shared_ptr<const GeoNearExpression> query,
+ const BSONObj& rawObj);
- Status init(StringData path, const GeoNearExpression* query, const BSONObj& rawObj);
+ virtual ~GeoNearMatchExpression() {}
/**
* Stub implementation that should never be called, since geoNear execution requires an
diff --git a/src/mongo/db/matcher/expression_geo_test.cpp b/src/mongo/db/matcher/expression_geo_test.cpp
index de7bd773c8a..082bcef790d 100644
--- a/src/mongo/db/matcher/expression_geo_test.cpp
+++ b/src/mongo/db/matcher/expression_geo_test.cpp
@@ -46,8 +46,7 @@ TEST(ExpressionGeoTest, Geo1) {
std::unique_ptr<GeoExpression> gq(new GeoExpression);
ASSERT_OK(gq->parseFrom(query["loc"].Obj()));
- GeoMatchExpression ge;
- ASSERT(ge.init("a", gq.release(), query).isOK());
+ GeoMatchExpression ge("a", gq.release(), query);
ASSERT(!ge.matchesBSON(fromjson("{a: [3,4]}")));
ASSERT(ge.matchesBSON(fromjson("{a: [4,4]}")));
@@ -63,8 +62,7 @@ TEST(ExpressionGeoTest, GeoNear1) {
std::unique_ptr<GeoNearExpression> nq(new GeoNearExpression);
ASSERT_OK(nq->parseFrom(query["loc"].Obj()));
- GeoNearMatchExpression gne;
- ASSERT(gne.init("a", nq.release(), query).isOK());
+ GeoNearMatchExpression gne("a", nq.release(), query);
// We can't match the data but we can make sure it was parsed OK.
ASSERT_EQUALS(gne.getData().centroid->crs, SPHERE);
@@ -76,8 +74,8 @@ std::unique_ptr<GeoMatchExpression> makeGeoMatchExpression(const BSONObj& locQue
std::unique_ptr<GeoExpression> gq(new GeoExpression);
ASSERT_OK(gq->parseFrom(locQuery));
- std::unique_ptr<GeoMatchExpression> ge = stdx::make_unique<GeoMatchExpression>();
- ASSERT_OK(ge->init("a", gq.release(), locQuery));
+ std::unique_ptr<GeoMatchExpression> ge =
+ stdx::make_unique<GeoMatchExpression>("a", gq.release(), locQuery);
return ge;
}
@@ -86,8 +84,8 @@ std::unique_ptr<GeoNearMatchExpression> makeGeoNearMatchExpression(const BSONObj
std::unique_ptr<GeoNearExpression> nq(new GeoNearExpression);
ASSERT_OK(nq->parseFrom(locQuery));
- std::unique_ptr<GeoNearMatchExpression> gne = stdx::make_unique<GeoNearMatchExpression>();
- ASSERT_OK(gne->init("a", nq.release(), locQuery));
+ std::unique_ptr<GeoNearMatchExpression> gne =
+ stdx::make_unique<GeoNearMatchExpression>("a", nq.release(), locQuery);
return gne;
}
diff --git a/src/mongo/db/matcher/expression_leaf.cpp b/src/mongo/db/matcher/expression_leaf.cpp
index ba0244b98a0..bde6be92d7d 100644
--- a/src/mongo/db/matcher/expression_leaf.cpp
+++ b/src/mongo/db/matcher/expression_leaf.cpp
@@ -47,29 +47,14 @@
namespace mongo {
-bool ComparisonMatchExpression::equivalent(const MatchExpression* other) const {
- if (other->matchType() != matchType())
- return false;
- const ComparisonMatchExpression* realOther =
- static_cast<const ComparisonMatchExpression*>(other);
-
- if (!CollatorInterface::collatorsMatch(_collator, realOther->_collator)) {
- return false;
- }
-
- const StringData::ComparatorInterface* stringComparator = nullptr;
- BSONElementComparator eltCmp(BSONElementComparator::FieldNamesMode::kIgnore, stringComparator);
- return path() == realOther->path() && eltCmp.evaluate(_rhs == realOther->_rhs);
-}
-
-Status ComparisonMatchExpression::init(StringData path, const BSONElement& rhs) {
- _rhs = rhs;
-
+ComparisonMatchExpression::ComparisonMatchExpression(MatchType type,
+ StringData path,
+ const BSONElement& rhs)
+ : LeafMatchExpression(type, path), _rhs(rhs) {
invariant(_rhs);
- if (_rhs.type() == BSONType::Undefined) {
- return Status(ErrorCodes::BadValue, "cannot compare to undefined");
- }
+ uassert(
+ ErrorCodes::BadValue, "cannot compare to undefined", _rhs.type() != BSONType::Undefined);
switch (matchType()) {
case LT:
@@ -79,10 +64,23 @@ Status ComparisonMatchExpression::init(StringData path, const BSONElement& rhs)
case GTE:
break;
default:
- return Status(ErrorCodes::BadValue, "bad match type for ComparisonMatchExpression");
+ uasserted(ErrorCodes::BadValue, "bad match type for ComparisonMatchExpression");
}
+}
- return setPath(path);
+bool ComparisonMatchExpression::equivalent(const MatchExpression* other) const {
+ if (other->matchType() != matchType())
+ return false;
+ const ComparisonMatchExpression* realOther =
+ static_cast<const ComparisonMatchExpression*>(other);
+
+ if (!CollatorInterface::collatorsMatch(_collator, realOther->_collator)) {
+ return false;
+ }
+
+ const StringData::ComparatorInterface* stringComparator = nullptr;
+ BSONElementComparator eltCmp(BSONElementComparator::FieldNamesMode::kIgnore, stringComparator);
+ return path() == realOther->path() && eltCmp.evaluate(_rhs == realOther->_rhs);
}
bool ComparisonMatchExpression::matchesSingleElement(const BSONElement& e,
@@ -221,7 +219,36 @@ inline pcrecpp::RE_Options flags2options(const char* flags) {
return options;
}
-RegexMatchExpression::RegexMatchExpression() : LeafMatchExpression(REGEX) {}
+RegexMatchExpression::RegexMatchExpression(StringData path, const BSONElement& e)
+ : LeafMatchExpression(REGEX, path),
+ _regex(e.regex()),
+ _flags(e.regexFlags()),
+ _re(new pcrecpp::RE(_regex.c_str(), flags2options(_flags.c_str()))) {
+ uassert(ErrorCodes::BadValue, "regex not a regex", e.type() == RegEx);
+ _init();
+}
+
+RegexMatchExpression::RegexMatchExpression(StringData path, StringData regex, StringData options)
+ : LeafMatchExpression(REGEX, path),
+ _regex(regex.toString()),
+ _flags(options.toString()),
+ _re(new pcrecpp::RE(_regex.c_str(), flags2options(_flags.c_str()))) {
+ _init();
+}
+
+void RegexMatchExpression::_init() {
+ uassert(ErrorCodes::BadValue,
+ "Regular expression cannot contain an embedded null byte",
+ _regex.find('\0') == std::string::npos);
+
+ uassert(ErrorCodes::BadValue,
+ "Regular expression options string cannot contain an embedded null byte",
+ _flags.find('\0') == std::string::npos);
+
+ uassert(ErrorCodes::BadValue,
+ str::stream() << "Regular expression is invalid: " << _re->error(),
+ _re->error().empty());
+}
RegexMatchExpression::~RegexMatchExpression() {}
@@ -234,37 +261,6 @@ bool RegexMatchExpression::equivalent(const MatchExpression* other) const {
_flags == realOther->_flags;
}
-
-Status RegexMatchExpression::init(StringData path, const BSONElement& e) {
- if (e.type() != RegEx)
- return Status(ErrorCodes::BadValue, "regex not a regex");
- return init(path, e.regex(), e.regexFlags());
-}
-
-
-Status RegexMatchExpression::init(StringData path, StringData regex, StringData options) {
- if (regex.find('\0') != std::string::npos) {
- return Status(ErrorCodes::BadValue,
- "Regular expression cannot contain an embedded null byte");
- }
-
- if (options.find('\0') != std::string::npos) {
- return Status(ErrorCodes::BadValue,
- "Regular expression options string cannot contain an embedded null byte");
- }
-
- _regex = regex.toString();
- _flags = options.toString();
- _re.reset(new pcrecpp::RE(_regex.c_str(), flags2options(_flags.c_str())));
-
- if (!_re->error().empty()) {
- return Status(ErrorCodes::BadValue,
- str::stream() << "Regular expression is invalid: " << _re->error());
- }
-
- return setPath(path);
-}
-
bool RegexMatchExpression::matchesSingleElement(const BSONElement& e, MatchDetails* details) const {
switch (e.type()) {
case String:
@@ -315,12 +311,9 @@ void RegexMatchExpression::shortDebugString(StringBuilder& debug) const {
// ---------
-Status ModMatchExpression::init(StringData path, int divisor, int remainder) {
- if (divisor == 0)
- return Status(ErrorCodes::BadValue, "divisor cannot be 0");
- _divisor = divisor;
- _remainder = remainder;
- return setPath(path);
+ModMatchExpression::ModMatchExpression(StringData path, int divisor, int remainder)
+ : LeafMatchExpression(MOD, path), _divisor(divisor), _remainder(remainder) {
+ uassert(ErrorCodes::BadValue, "divisor cannot be 0", divisor != 0);
}
bool ModMatchExpression::matchesSingleElement(const BSONElement& e, MatchDetails* details) const {
@@ -356,9 +349,7 @@ bool ModMatchExpression::equivalent(const MatchExpression* other) const {
// ------------------
-Status ExistsMatchExpression::init(StringData path) {
- return setPath(path);
-}
+ExistsMatchExpression::ExistsMatchExpression(StringData path) : LeafMatchExpression(EXISTS, path) {}
bool ExistsMatchExpression::matchesSingleElement(const BSONElement& e,
MatchDetails* details) const {
@@ -391,13 +382,13 @@ bool ExistsMatchExpression::equivalent(const MatchExpression* other) const {
// ----
-Status InMatchExpression::init(StringData path) {
- return setPath(path);
-}
+InMatchExpression::InMatchExpression(StringData path)
+ : LeafMatchExpression(MATCH_IN, path),
+ _eltCmp(BSONElementComparator::FieldNamesMode::kIgnore, _collator),
+ _equalitySet(_eltCmp.makeBSONEltFlatSet(_originalEqualityVector)) {}
std::unique_ptr<MatchExpression> InMatchExpression::shallowClone() const {
- auto next = stdx::make_unique<InMatchExpression>();
- next->init(path()).transitional_ignore();
+ auto next = stdx::make_unique<InMatchExpression>(path());
next->setCollator(_collator);
if (getTag()) {
next->setTag(getTag()->clone());
@@ -552,18 +543,16 @@ MatchExpression::ExpressionOptimizerFunc InMatchExpression::getOptimizer() const
auto& childRe = regexList.front();
invariant(!childRe->getTag());
- auto simplifiedExpression = stdx::make_unique<RegexMatchExpression>();
- invariantOK(simplifiedExpression->init(
- expression->path(), childRe->getString(), childRe->getFlags()));
+ auto simplifiedExpression = stdx::make_unique<RegexMatchExpression>(
+ expression->path(), childRe->getString(), childRe->getFlags());
if (expression->getTag()) {
simplifiedExpression->setTag(expression->getTag()->clone());
}
-
return std::move(simplifiedExpression);
} else if (equalitySet.size() == 1 && regexList.empty()) {
// Simplify IN of exactly one equality to be an EqualityMatchExpression.
- auto simplifiedExpression = stdx::make_unique<EqualityMatchExpression>();
- invariantOK(simplifiedExpression->init(expression->path(), *(equalitySet.begin())));
+ auto simplifiedExpression = stdx::make_unique<EqualityMatchExpression>(
+ expression->path(), *(equalitySet.begin()));
simplifiedExpression->setCollator(collator);
if (expression->getTag()) {
simplifiedExpression->setTag(expression->getTag()->clone());
@@ -578,9 +567,10 @@ MatchExpression::ExpressionOptimizerFunc InMatchExpression::getOptimizer() const
// -----------
-Status BitTestMatchExpression::init(StringData path, std::vector<uint32_t> bitPositions) {
- _bitPositions = std::move(bitPositions);
-
+BitTestMatchExpression::BitTestMatchExpression(MatchType type,
+ StringData path,
+ std::vector<uint32_t> bitPositions)
+ : LeafMatchExpression(type, path), _bitPositions(std::move(bitPositions)) {
// Process bit positions into bitmask.
for (auto bitPosition : _bitPositions) {
// Checking bits > 63 is just checking the sign bit, since we sign-extend numbers. For
@@ -589,26 +579,23 @@ Status BitTestMatchExpression::init(StringData path, std::vector<uint32_t> bitPo
bitPosition = std::min(bitPosition, 63U);
_bitMask |= 1ULL << bitPosition;
}
-
- return setPath(path);
}
-Status BitTestMatchExpression::init(StringData path, uint64_t bitMask) {
- _bitMask = bitMask;
-
+BitTestMatchExpression::BitTestMatchExpression(MatchType type, StringData path, uint64_t bitMask)
+ : LeafMatchExpression(type, path), _bitMask(bitMask) {
// Process bitmask into bit positions.
for (int bit = 0; bit < 64; bit++) {
if (_bitMask & (1ULL << bit)) {
_bitPositions.push_back(bit);
}
}
-
- return setPath(path);
}
-Status BitTestMatchExpression::init(StringData path,
- const char* bitMaskBinary,
- uint32_t bitMaskLen) {
+BitTestMatchExpression::BitTestMatchExpression(MatchType type,
+ StringData path,
+ const char* bitMaskBinary,
+ uint32_t bitMaskLen)
+ : LeafMatchExpression(type, path) {
for (uint32_t byte = 0; byte < bitMaskLen; byte++) {
char byteAt = bitMaskBinary[byte];
if (!byteAt) {
@@ -631,8 +618,6 @@ Status BitTestMatchExpression::init(StringData path,
}
}
}
-
- return setPath(path);
}
bool BitTestMatchExpression::needFurtherBitTests(bool isBitSet) const {
diff --git a/src/mongo/db/matcher/expression_leaf.h b/src/mongo/db/matcher/expression_leaf.h
index dd225c57763..77123742849 100644
--- a/src/mongo/db/matcher/expression_leaf.h
+++ b/src/mongo/db/matcher/expression_leaf.h
@@ -47,7 +47,10 @@ class CollatorInterface;
class LeafMatchExpression : public PathMatchExpression {
public:
- explicit LeafMatchExpression(MatchType matchType) : PathMatchExpression(matchType) {}
+ explicit LeafMatchExpression(MatchType matchType, StringData path)
+ : PathMatchExpression(matchType, path) {
+ setTraverseLeafArray();
+ }
virtual ~LeafMatchExpression() {}
@@ -77,9 +80,7 @@ public:
*/
class ComparisonMatchExpression : public LeafMatchExpression {
public:
- explicit ComparisonMatchExpression(MatchType type) : LeafMatchExpression(type) {}
-
- Status init(StringData path, const BSONElement& rhs);
+ explicit ComparisonMatchExpression(MatchType type, StringData path, const BSONElement& rhs);
virtual ~ComparisonMatchExpression() {}
@@ -136,10 +137,12 @@ private:
class EqualityMatchExpression : public ComparisonMatchExpression {
public:
- EqualityMatchExpression() : ComparisonMatchExpression(EQ) {}
+ EqualityMatchExpression(StringData path, const BSONElement& rhs)
+ : ComparisonMatchExpression(EQ, path, rhs) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<EqualityMatchExpression>();
- invariantOK(e->init(path(), _rhs));
+ std::unique_ptr<ComparisonMatchExpression> e =
+ stdx::make_unique<EqualityMatchExpression>(path(), _rhs);
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -150,10 +153,12 @@ public:
class LTEMatchExpression : public ComparisonMatchExpression {
public:
- LTEMatchExpression() : ComparisonMatchExpression(LTE) {}
+ LTEMatchExpression(StringData path, const BSONElement& rhs)
+ : ComparisonMatchExpression(LTE, path, rhs) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<LTEMatchExpression>();
- invariantOK(e->init(path(), _rhs));
+ std::unique_ptr<ComparisonMatchExpression> e =
+ stdx::make_unique<LTEMatchExpression>(path(), _rhs);
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -164,10 +169,12 @@ public:
class LTMatchExpression : public ComparisonMatchExpression {
public:
- LTMatchExpression() : ComparisonMatchExpression(LT) {}
+ LTMatchExpression(StringData path, const BSONElement& rhs)
+ : ComparisonMatchExpression(LT, path, rhs) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<LTMatchExpression>();
- invariantOK(e->init(path(), _rhs));
+ std::unique_ptr<ComparisonMatchExpression> e =
+ stdx::make_unique<LTMatchExpression>(path(), _rhs);
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -178,10 +185,12 @@ public:
class GTMatchExpression : public ComparisonMatchExpression {
public:
- GTMatchExpression() : ComparisonMatchExpression(GT) {}
+ GTMatchExpression(StringData path, const BSONElement& rhs)
+ : ComparisonMatchExpression(GT, path, rhs) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<GTMatchExpression>();
- invariantOK(e->init(path(), _rhs));
+ std::unique_ptr<ComparisonMatchExpression> e =
+ stdx::make_unique<GTMatchExpression>(path(), _rhs);
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -192,10 +201,12 @@ public:
class GTEMatchExpression : public ComparisonMatchExpression {
public:
- GTEMatchExpression() : ComparisonMatchExpression(GTE) {}
+ GTEMatchExpression(StringData path, const BSONElement& rhs)
+ : ComparisonMatchExpression(GTE, path, rhs) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<GTEMatchExpression>();
- invariantOK(e->init(path(), _rhs));
+ std::unique_ptr<ComparisonMatchExpression> e =
+ stdx::make_unique<GTEMatchExpression>(path(), _rhs);
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -206,15 +217,13 @@ public:
class RegexMatchExpression : public LeafMatchExpression {
public:
- RegexMatchExpression();
+ RegexMatchExpression(StringData path, const BSONElement& e);
+ RegexMatchExpression(StringData path, StringData regex, StringData options);
~RegexMatchExpression();
- Status init(StringData path, StringData regex, StringData options);
- Status init(StringData path, const BSONElement& e);
-
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<RegexMatchExpression> e = stdx::make_unique<RegexMatchExpression>();
- invariantOK(e->init(path(), _regex, _flags));
+ std::unique_ptr<RegexMatchExpression> e =
+ stdx::make_unique<RegexMatchExpression>(path(), _regex, _flags);
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -245,6 +254,8 @@ private:
return [](std::unique_ptr<MatchExpression> expression) { return expression; };
}
+ void _init();
+
std::string _regex;
std::string _flags;
std::unique_ptr<pcrecpp::RE> _re;
@@ -252,13 +263,11 @@ private:
class ModMatchExpression : public LeafMatchExpression {
public:
- ModMatchExpression() : LeafMatchExpression(MOD) {}
-
- Status init(StringData path, int divisor, int remainder);
+ ModMatchExpression(StringData path, int divisor, int remainder);
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<ModMatchExpression> m = stdx::make_unique<ModMatchExpression>();
- invariantOK(m->init(path(), _divisor, _remainder));
+ std::unique_ptr<ModMatchExpression> m =
+ stdx::make_unique<ModMatchExpression>(path(), _divisor, _remainder);
if (getTag()) {
m->setTag(getTag()->clone());
}
@@ -291,13 +300,10 @@ private:
class ExistsMatchExpression : public LeafMatchExpression {
public:
- ExistsMatchExpression() : LeafMatchExpression(EXISTS) {}
-
- Status init(StringData path);
+ explicit ExistsMatchExpression(StringData path);
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<ExistsMatchExpression> e = stdx::make_unique<ExistsMatchExpression>();
- invariantOK(e->init(path()));
+ std::unique_ptr<ExistsMatchExpression> e = stdx::make_unique<ExistsMatchExpression>(path());
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -323,12 +329,7 @@ private:
*/
class InMatchExpression : public LeafMatchExpression {
public:
- InMatchExpression()
- : LeafMatchExpression(MATCH_IN),
- _eltCmp(BSONElementComparator::FieldNamesMode::kIgnore, _collator),
- _equalitySet(_eltCmp.makeBSONEltFlatSet(_originalEqualityVector)) {}
-
- Status init(StringData path);
+ explicit InMatchExpression(StringData path);
virtual std::unique_ptr<MatchExpression> shallowClone() const;
@@ -401,16 +402,19 @@ private:
*/
class BitTestMatchExpression : public LeafMatchExpression {
public:
- explicit BitTestMatchExpression(MatchType type) : LeafMatchExpression(type) {}
- virtual ~BitTestMatchExpression() {}
-
/**
- * Initialize with either bit positions, a 64-bit numeric bitmask, or a char array
+ * Construct with either bit positions, a 64-bit numeric bitmask, or a char array
* bitmask.
*/
- Status init(StringData path, std::vector<uint32_t> bitPositions);
- Status init(StringData path, uint64_t bitMask);
- Status init(StringData path, const char* bitMaskBinary, uint32_t bitMaskLen);
+ explicit BitTestMatchExpression(MatchType type,
+ StringData path,
+ std::vector<uint32_t> bitPositions);
+ explicit BitTestMatchExpression(MatchType type, StringData path, uint64_t bitMask);
+ explicit BitTestMatchExpression(MatchType type,
+ StringData path,
+ const char* bitMaskBinary,
+ uint32_t bitMaskLen);
+ virtual ~BitTestMatchExpression() {}
bool matchesSingleElement(const BSONElement&, MatchDetails* details = nullptr) const final;
@@ -428,18 +432,6 @@ public:
return _bitPositions;
}
-protected:
- /**
- * Used to copy this match expression to another BitTestMatchExpression. Does not take
- * ownership.
- */
- void initClone(BitTestMatchExpression* clone) const {
- invariantOK(clone->init(path(), _bitPositions));
- if (getTag()) {
- clone->setTag(getTag()->clone());
- }
- }
-
private:
ExpressionOptimizerFunc getOptimizer() const final {
return [](std::unique_ptr<MatchExpression> expression) { return expression; };
@@ -475,44 +467,84 @@ private:
class BitsAllSetMatchExpression : public BitTestMatchExpression {
public:
- BitsAllSetMatchExpression() : BitTestMatchExpression(BITS_ALL_SET) {}
+ BitsAllSetMatchExpression(StringData path, std::vector<uint32_t> bitPositions)
+ : BitTestMatchExpression(BITS_ALL_SET, path, bitPositions) {}
+
+ BitsAllSetMatchExpression(StringData path, uint64_t bitMask)
+ : BitTestMatchExpression(BITS_ALL_SET, path, bitMask) {}
+
+ BitsAllSetMatchExpression(StringData path, const char* bitMaskBinary, uint32_t bitMaskLen)
+ : BitTestMatchExpression(BITS_ALL_SET, path, bitMaskBinary, bitMaskLen) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<BitTestMatchExpression> bitTestMatchExpression =
- stdx::make_unique<BitsAllSetMatchExpression>();
- initClone(bitTestMatchExpression.get());
+ stdx::make_unique<BitsAllSetMatchExpression>(path(), getBitPositions());
+ if (getTag()) {
+ bitTestMatchExpression->setTag(getTag()->clone());
+ }
return std::move(bitTestMatchExpression);
}
};
class BitsAllClearMatchExpression : public BitTestMatchExpression {
public:
- BitsAllClearMatchExpression() : BitTestMatchExpression(BITS_ALL_CLEAR) {}
+ BitsAllClearMatchExpression(StringData path, std::vector<uint32_t> bitPositions)
+ : BitTestMatchExpression(BITS_ALL_CLEAR, path, bitPositions) {}
+
+ BitsAllClearMatchExpression(StringData path, uint64_t bitMask)
+ : BitTestMatchExpression(BITS_ALL_CLEAR, path, bitMask) {}
+
+ BitsAllClearMatchExpression(StringData path, const char* bitMaskBinary, uint32_t bitMaskLen)
+ : BitTestMatchExpression(BITS_ALL_CLEAR, path, bitMaskBinary, bitMaskLen) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<BitTestMatchExpression> bitTestMatchExpression =
- stdx::make_unique<BitsAllClearMatchExpression>();
- initClone(bitTestMatchExpression.get());
+ stdx::make_unique<BitsAllClearMatchExpression>(path(), getBitPositions());
+ if (getTag()) {
+ bitTestMatchExpression->setTag(getTag()->clone());
+ }
return std::move(bitTestMatchExpression);
}
};
class BitsAnySetMatchExpression : public BitTestMatchExpression {
public:
- BitsAnySetMatchExpression() : BitTestMatchExpression(BITS_ANY_SET) {}
+ BitsAnySetMatchExpression(StringData path, std::vector<uint32_t> bitPositions)
+ : BitTestMatchExpression(BITS_ANY_SET, path, bitPositions) {}
+
+ BitsAnySetMatchExpression(StringData path, uint64_t bitMask)
+ : BitTestMatchExpression(BITS_ANY_SET, path, bitMask) {}
+
+ BitsAnySetMatchExpression(StringData path, const char* bitMaskBinary, uint32_t bitMaskLen)
+ : BitTestMatchExpression(BITS_ANY_SET, path, bitMaskBinary, bitMaskLen) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<BitTestMatchExpression> bitTestMatchExpression =
- stdx::make_unique<BitsAnySetMatchExpression>();
- initClone(bitTestMatchExpression.get());
+ stdx::make_unique<BitsAnySetMatchExpression>(path(), getBitPositions());
+ if (getTag()) {
+ bitTestMatchExpression->setTag(getTag()->clone());
+ }
return std::move(bitTestMatchExpression);
}
};
class BitsAnyClearMatchExpression : public BitTestMatchExpression {
public:
- BitsAnyClearMatchExpression() : BitTestMatchExpression(BITS_ANY_CLEAR) {}
+ BitsAnyClearMatchExpression(StringData path, std::vector<uint32_t> bitPositions)
+ : BitTestMatchExpression(BITS_ANY_CLEAR, path, bitPositions) {}
+
+ BitsAnyClearMatchExpression(StringData path, uint64_t bitMask)
+ : BitTestMatchExpression(BITS_ANY_CLEAR, path, bitMask) {}
+
+ BitsAnyClearMatchExpression(StringData path, const char* bitMaskBinary, uint32_t bitMaskLen)
+ : BitTestMatchExpression(BITS_ANY_CLEAR, path, bitMaskBinary, bitMaskLen) {}
+
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<BitTestMatchExpression> bitTestMatchExpression =
- stdx::make_unique<BitsAnyClearMatchExpression>();
- initClone(bitTestMatchExpression.get());
+ stdx::make_unique<BitsAnyClearMatchExpression>(path(), getBitPositions());
+ if (getTag()) {
+ bitTestMatchExpression->setTag(getTag()->clone());
+ }
return std::move(bitTestMatchExpression);
}
};
diff --git a/src/mongo/db/matcher/expression_leaf_test.cpp b/src/mongo/db/matcher/expression_leaf_test.cpp
index ca527fd846b..dde4439d517 100644
--- a/src/mongo/db/matcher/expression_leaf_test.cpp
+++ b/src/mongo/db/matcher/expression_leaf_test.cpp
@@ -43,21 +43,23 @@ namespace mongo {
using std::string;
TEST(ComparisonMatchExpression, ComparisonMatchExpressionsWithUnequalCollatorsAreUnequal) {
+ BSONObj operand = BSON("a" << 5);
CollatorInterfaceMock collator1(CollatorInterfaceMock::MockType::kReverseString);
- EqualityMatchExpression eq1;
+ EqualityMatchExpression eq1("a", operand["a"]);
eq1.setCollator(&collator1);
CollatorInterfaceMock collator2(CollatorInterfaceMock::MockType::kAlwaysEqual);
- EqualityMatchExpression eq2;
+ EqualityMatchExpression eq2("a", operand["a"]);
eq2.setCollator(&collator2);
ASSERT(!eq1.equivalent(&eq2));
}
TEST(ComparisonMatchExpression, ComparisonMatchExpressionsWithEqualCollatorsAreEqual) {
+ BSONObj operand = BSON("a" << 5);
CollatorInterfaceMock collator1(CollatorInterfaceMock::MockType::kAlwaysEqual);
- EqualityMatchExpression eq1;
+ EqualityMatchExpression eq1("a", operand["a"]);
eq1.setCollator(&collator1);
CollatorInterfaceMock collator2(CollatorInterfaceMock::MockType::kAlwaysEqual);
- EqualityMatchExpression eq2;
+ EqualityMatchExpression eq2("a", operand["a"]);
eq2.setCollator(&collator2);
ASSERT(eq1.equivalent(&eq2));
}
@@ -65,8 +67,7 @@ TEST(ComparisonMatchExpression, ComparisonMatchExpressionsWithEqualCollatorsAreE
TEST(ComparisonMatchExpression, StringMatchingWithNullCollatorUsesBinaryComparison) {
BSONObj operand = BSON("a"
<< "string");
- EqualityMatchExpression eq;
- ASSERT(eq.init("a", operand["a"]).isOK());
+ EqualityMatchExpression eq("a", operand["a"]);
ASSERT(!eq.matchesBSON(BSON("a"
<< "string2"),
NULL));
@@ -76,9 +77,8 @@ TEST(ComparisonMatchExpression, StringMatchingRespectsCollation) {
BSONObj operand = BSON("a"
<< "string");
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- EqualityMatchExpression eq;
+ EqualityMatchExpression eq("a", operand["a"]);
eq.setCollator(&collator);
- ASSERT(eq.init("a", operand["a"]).isOK());
ASSERT(eq.matchesBSON(BSON("a"
<< "string2"),
NULL));
@@ -89,8 +89,7 @@ TEST(EqOp, MatchesElement) {
BSONObj match = BSON("a" << 5.0);
BSONObj notMatch = BSON("a" << 6);
- EqualityMatchExpression eq;
- eq.init("", operand["a"]).transitional_ignore();
+ EqualityMatchExpression eq("", operand["a"]);
ASSERT(eq.matchesSingleElement(match.firstElement()));
ASSERT(!eq.matchesSingleElement(notMatch.firstElement()));
@@ -99,30 +98,26 @@ TEST(EqOp, MatchesElement) {
DEATH_TEST(EqOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
- EqualityMatchExpression eq;
- eq.init("", operand.firstElement()).ignore();
+ EqualityMatchExpression eq("", operand.firstElement());
}
TEST(EqOp, MatchesScalar) {
BSONObj operand = BSON("a" << 5);
- EqualityMatchExpression eq;
- eq.init("a", operand["a"]).transitional_ignore();
+ EqualityMatchExpression eq("a", operand["a"]);
ASSERT(eq.matchesBSON(BSON("a" << 5.0), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << 4), NULL));
}
TEST(EqOp, MatchesArrayValue) {
BSONObj operand = BSON("a" << 5);
- EqualityMatchExpression eq;
- eq.init("a", operand["a"]).transitional_ignore();
+ EqualityMatchExpression eq("a", operand["a"]);
ASSERT(eq.matchesBSON(BSON("a" << BSON_ARRAY(5.0 << 6)), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << BSON_ARRAY(6 << 7)), NULL));
}
TEST(EqOp, MatchesReferencedObjectValue) {
BSONObj operand = BSON("a.b" << 5);
- EqualityMatchExpression eq;
- eq.init("a.b", operand["a.b"]).transitional_ignore();
+ EqualityMatchExpression eq("a.b", operand["a.b"]);
ASSERT(eq.matchesBSON(BSON("a" << BSON("b" << 5)), NULL));
ASSERT(eq.matchesBSON(BSON("a" << BSON("b" << BSON_ARRAY(5))), NULL));
ASSERT(eq.matchesBSON(BSON("a" << BSON_ARRAY(BSON("b" << 5))), NULL));
@@ -130,16 +125,14 @@ TEST(EqOp, MatchesReferencedObjectValue) {
TEST(EqOp, MatchesReferencedArrayValue) {
BSONObj operand = BSON("a.0" << 5);
- EqualityMatchExpression eq;
- eq.init("a.0", operand["a.0"]).transitional_ignore();
+ EqualityMatchExpression eq("a.0", operand["a.0"]);
ASSERT(eq.matchesBSON(BSON("a" << BSON_ARRAY(5)), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << BSON_ARRAY(BSON_ARRAY(5))), NULL));
}
TEST(EqOp, MatchesNull) {
BSONObj operand = BSON("a" << BSONNULL);
- EqualityMatchExpression eq;
- eq.init("a", operand["a"]).transitional_ignore();
+ EqualityMatchExpression eq("a", operand["a"]);
ASSERT(eq.matchesBSON(BSONObj(), NULL));
ASSERT(eq.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << 4), NULL));
@@ -151,8 +144,7 @@ TEST(EqOp, MatchesNull) {
// not necessarily how it should work ideally.
TEST(EqOp, MatchesNestedNull) {
BSONObj operand = BSON("a.b" << BSONNULL);
- EqualityMatchExpression eq;
- eq.init("a.b", operand["a.b"]).transitional_ignore();
+ EqualityMatchExpression eq("a.b", operand["a.b"]);
// null matches any empty object that is on a subpath of a.b
ASSERT(eq.matchesBSON(BSONObj(), NULL));
ASSERT(eq.matchesBSON(BSON("a" << BSONObj()), NULL));
@@ -171,8 +163,7 @@ TEST(EqOp, MatchesNestedNull) {
TEST(EqOp, MatchesMinKey) {
BSONObj operand = BSON("a" << MinKey);
- EqualityMatchExpression eq;
- eq.init("a", operand["a"]).transitional_ignore();
+ EqualityMatchExpression eq("a", operand["a"]);
ASSERT(eq.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << 4), NULL));
@@ -181,8 +172,7 @@ TEST(EqOp, MatchesMinKey) {
TEST(EqOp, MatchesMaxKey) {
BSONObj operand = BSON("a" << MaxKey);
- EqualityMatchExpression eq;
- ASSERT(eq.init("a", operand["a"]).isOK());
+ EqualityMatchExpression eq("a", operand["a"]);
ASSERT(eq.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << 4), NULL));
@@ -190,8 +180,7 @@ TEST(EqOp, MatchesMaxKey) {
TEST(EqOp, MatchesFullArray) {
BSONObj operand = BSON("a" << BSON_ARRAY(1 << 2));
- EqualityMatchExpression eq;
- ASSERT(eq.init("a", operand["a"]).isOK());
+ EqualityMatchExpression eq("a", operand["a"]);
ASSERT(eq.matchesBSON(BSON("a" << BSON_ARRAY(1 << 2)), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << BSON_ARRAY(1 << 2 << 3)), NULL));
ASSERT(!eq.matchesBSON(BSON("a" << BSON_ARRAY(1)), NULL));
@@ -200,16 +189,14 @@ TEST(EqOp, MatchesFullArray) {
TEST(EqOp, MatchesThroughNestedArray) {
BSONObj operand = BSON("a.b.c.d" << 3);
- EqualityMatchExpression eq;
- eq.init("a.b.c.d", operand["a.b.c.d"]).transitional_ignore();
+ EqualityMatchExpression eq("a.b.c.d", operand["a.b.c.d"]);
BSONObj obj = fromjson("{a:{b:[{c:[{d:1},{d:2}]},{c:[{d:3}]}]}}");
ASSERT(eq.matchesBSON(obj, NULL));
}
TEST(EqOp, ElemMatchKey) {
BSONObj operand = BSON("a" << 5);
- EqualityMatchExpression eq;
- ASSERT(eq.init("a", operand["a"]).isOK());
+ EqualityMatchExpression eq("a", operand["a"]);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!eq.matchesBSON(BSON("a" << 4), &details));
@@ -227,8 +214,7 @@ TEST(EqOp, ElemMatchKey) {
TEST(EqOp, ElemMatchKeyWithImplicitAndExplicitTraversal) {
BSONObj operand = BSON("a.0.b" << 3);
BSONElement operandFirstElt = operand.firstElement();
- EqualityMatchExpression eq;
- ASSERT(eq.init(operandFirstElt.fieldName(), operandFirstElt).isOK());
+ EqualityMatchExpression eq(operandFirstElt.fieldName(), operandFirstElt);
MatchDetails details;
details.requestElemMatchKey();
BSONObj obj = fromjson("{a: [{b: [2, 3]}, {b: [4, 5]}]}");
@@ -238,71 +224,16 @@ TEST(EqOp, ElemMatchKeyWithImplicitAndExplicitTraversal) {
}
TEST(EqOp, Equality1) {
- EqualityMatchExpression eq1;
- EqualityMatchExpression eq2;
- EqualityMatchExpression eq3;
-
BSONObj operand = BSON("a" << 5 << "b" << 5 << "c" << 4);
-
- eq1.init("a", operand["a"]).transitional_ignore();
- eq2.init("a", operand["b"]).transitional_ignore();
- eq3.init("c", operand["c"]).transitional_ignore();
+ EqualityMatchExpression eq1("a", operand["a"]);
+ EqualityMatchExpression eq2("a", operand["b"]);
+ EqualityMatchExpression eq3("c", operand["c"]);
ASSERT(eq1.equivalent(&eq1));
ASSERT(eq1.equivalent(&eq2));
ASSERT(!eq1.equivalent(&eq3));
}
-/**
- TEST( EqOp, MatchesIndexKeyScalar ) {
- BSONObj operand = BSON( "a" << 6 );
- EqualityMatchExpression eq;
- ASSERT( eq.init( "a", operand[ "a" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- eq.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- eq.matchesIndexKey( BSON( "" << 4 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- eq.matchesIndexKey( BSON( "" << BSON_ARRAY( 6 ) ), indexSpec ) );
- }
-
- TEST( EqOp, MatchesIndexKeyMissing ) {
- BSONObj operand = BSON( "a" << 6 );
- EqualityMatchExpression eq;
- ASSERT( eq.init( "a", operand[ "a" ] ).isOK() );
- IndexSpec indexSpec( BSON( "b" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- eq.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- eq.matchesIndexKey( BSON( "" << 4 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- eq.matchesIndexKey( BSON( "" << BSON_ARRAY( 8 << 6 ) ), indexSpec ) );
- }
-
- TEST( EqOp, MatchesIndexKeyArray ) {
- BSONObj operand = BSON( "a" << BSON_ARRAY( 4 << 5 ) );
- ComparisonMatchExpression eq
- ASSERT( eq.init( "a", operand[ "a" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- eq.matchesIndexKey( BSON( "" << 4 ), indexSpec ) );
- }
-
- TEST( EqOp, MatchesIndexKeyArrayValue ) {
- BSONObj operand = BSON( "a" << 6 );
- ComparisonMatchExpression eq
- ASSERT( eq.init( "a", operand[ "a" ] ).isOK() );
- IndexSpec indexSpec( BSON( "loc" << "mockarrayvalue" << "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- eq.matchesIndexKey( BSON( "" << "dummygeohash" << "" << 6 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- eq.matchesIndexKey( BSON( "" << "dummygeohash" << "" << 4 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- eq.matchesIndexKey( BSON( "" << "dummygeohash" <<
- "" << BSON_ARRAY( 8 << 6 ) ), indexSpec ) );
- }
-*/
TEST(LtOp, MatchesElement) {
BSONObj operand = BSON("$lt" << 5);
BSONObj match = BSON("a" << 4.5);
@@ -310,8 +241,7 @@ TEST(LtOp, MatchesElement) {
BSONObj notMatchEqual = BSON("a" << 5);
BSONObj notMatchWrongType = BSON("a"
<< "foo");
- LTMatchExpression lt;
- ASSERT(lt.init("", operand["$lt"]).isOK());
+ LTMatchExpression lt("", operand["$lt"]);
ASSERT(lt.matchesSingleElement(match.firstElement()));
ASSERT(!lt.matchesSingleElement(notMatch.firstElement()));
ASSERT(!lt.matchesSingleElement(notMatchEqual.firstElement()));
@@ -320,38 +250,33 @@ TEST(LtOp, MatchesElement) {
DEATH_TEST(LtOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
- LTMatchExpression lt;
- lt.init("", operand.firstElement()).ignore();
+ LTMatchExpression lt("", operand.firstElement());
}
TEST(LtOp, MatchesScalar) {
BSONObj operand = BSON("$lt" << 5);
- LTMatchExpression lt;
- ASSERT(lt.init("a", operand["$lt"]).isOK());
+ LTMatchExpression lt("a", operand["$lt"]);
ASSERT(lt.matchesBSON(BSON("a" << 4.5), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << 6), NULL));
}
TEST(LtOp, MatchesScalarEmptyKey) {
BSONObj operand = BSON("$lt" << 5);
- LTMatchExpression lt;
- ASSERT(lt.init("", operand["$lt"]).isOK());
+ LTMatchExpression lt("", operand["$lt"]);
ASSERT(lt.matchesBSON(BSON("" << 4.5), NULL));
ASSERT(!lt.matchesBSON(BSON("" << 6), NULL));
}
TEST(LtOp, MatchesArrayValue) {
BSONObj operand = BSON("$lt" << 5);
- LTMatchExpression lt;
- ASSERT(lt.init("a", operand["$lt"]).isOK());
+ LTMatchExpression lt("a", operand["$lt"]);
ASSERT(lt.matchesBSON(BSON("a" << BSON_ARRAY(6 << 4.5)), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << BSON_ARRAY(6 << 7)), NULL));
}
TEST(LtOp, MatchesWholeArray) {
BSONObj operand = BSON("$lt" << BSON_ARRAY(5));
- LTMatchExpression lt;
- ASSERT(lt.init("a", operand["$lt"]).isOK());
+ LTMatchExpression lt("a", operand["$lt"]);
ASSERT(lt.matchesBSON(BSON("a" << BSON_ARRAY(4)), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << BSON_ARRAY(5)), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << BSON_ARRAY(6)), NULL));
@@ -363,8 +288,7 @@ TEST(LtOp, MatchesWholeArray) {
TEST(LtOp, MatchesNull) {
BSONObj operand = BSON("$lt" << BSONNULL);
- LTMatchExpression lt;
- ASSERT(lt.init("a", operand["$lt"]).isOK());
+ LTMatchExpression lt("a", operand["$lt"]);
ASSERT(!lt.matchesBSON(BSONObj(), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << 4), NULL));
@@ -374,8 +298,7 @@ TEST(LtOp, MatchesNull) {
TEST(LtOp, MatchesDotNotationNull) {
BSONObj operand = BSON("$lt" << BSONNULL);
- LTMatchExpression lt;
- ASSERT(lt.init("a.b", operand["$lt"]).isOK());
+ LTMatchExpression lt("a.b", operand["$lt"]);
ASSERT(!lt.matchesBSON(BSONObj(), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << 4), NULL));
@@ -388,8 +311,7 @@ TEST(LtOp, MatchesDotNotationNull) {
TEST(LtOp, MatchesMinKey) {
BSONObj operand = BSON("a" << MinKey);
- LTMatchExpression lt;
- ASSERT(lt.init("a", operand["a"]).isOK());
+ LTMatchExpression lt("a", operand["a"]);
ASSERT(!lt.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(!lt.matchesBSON(BSON("a" << 4), NULL));
@@ -397,8 +319,7 @@ TEST(LtOp, MatchesMinKey) {
TEST(LtOp, MatchesMaxKey) {
BSONObj operand = BSON("a" << MaxKey);
- LTMatchExpression lt;
- ASSERT(lt.init("a", operand["a"]).isOK());
+ LTMatchExpression lt("a", operand["a"]);
ASSERT(!lt.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(lt.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(lt.matchesBSON(BSON("a" << 4), NULL));
@@ -406,8 +327,7 @@ TEST(LtOp, MatchesMaxKey) {
TEST(LtOp, ElemMatchKey) {
BSONObj operand = BSON("$lt" << 5);
- LTMatchExpression lt;
- ASSERT(lt.init("a", operand["$lt"]).isOK());
+ LTMatchExpression lt("a", operand["$lt"]);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!lt.matchesBSON(BSON("a" << 6), &details));
@@ -419,56 +339,6 @@ TEST(LtOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
-/**
- TEST( LtOp, MatchesIndexKeyScalar ) {
- BSONObj operand = BSON( "$lt" << 6 );
- LtOp lt;
- ASSERT( lt.init( "a", operand[ "$lt" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- lt.matchesIndexKey( BSON( "" << 3 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- lt.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- lt.matchesIndexKey( BSON( "" << BSON_ARRAY( 5 ) ), indexSpec ) );
- }
-
- TEST( LtOp, MatchesIndexKeyMissing ) {
- BSONObj operand = BSON( "$lt" << 6 );
- LtOp lt;
- ASSERT( lt.init( "a", operand[ "$lt" ] ).isOK() );
- IndexSpec indexSpec( BSON( "b" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- lt.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- lt.matchesIndexKey( BSON( "" << 4 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- lt.matchesIndexKey( BSON( "" << BSON_ARRAY( 8 << 6 ) ), indexSpec ) );
- }
-
- TEST( LtOp, MatchesIndexKeyArray ) {
- BSONObj operand = BSON( "$lt" << BSON_ARRAY( 4 << 5 ) );
- LtOp lt;
- ASSERT( lt.init( "a", operand[ "$lt" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- lt.matchesIndexKey( BSON( "" << 3 ), indexSpec ) );
- }
-
- TEST( LtOp, MatchesIndexKeyArrayValue ) {
- BSONObj operand = BSON( "$lt" << 6 );
- LtOp lt;
- ASSERT( lt.init( "a", operand[ "$lt" ] ).isOK() );
- IndexSpec indexSpec( BSON( "loc" << "mockarrayvalue" << "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- lt.matchesIndexKey( BSON( "" << "dummygeohash" << "" << 3 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- lt.matchesIndexKey( BSON( "" << "dummygeohash" << "" << 6 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- lt.matchesIndexKey( BSON( "" << "dummygeohash" <<
- "" << BSON_ARRAY( 8 << 6 << 4 ) ), indexSpec ) );
- }
-*/
TEST(LteOp, MatchesElement) {
BSONObj operand = BSON("$lte" << 5);
BSONObj match = BSON("a" << 4.5);
@@ -476,8 +346,7 @@ TEST(LteOp, MatchesElement) {
BSONObj notMatch = BSON("a" << 6);
BSONObj notMatchWrongType = BSON("a"
<< "foo");
- LTEMatchExpression lte;
- ASSERT(lte.init("", operand["$lte"]).isOK());
+ LTEMatchExpression lte("", operand["$lte"]);
ASSERT(lte.matchesSingleElement(match.firstElement()));
ASSERT(lte.matchesSingleElement(equalMatch.firstElement()));
ASSERT(!lte.matchesSingleElement(notMatch.firstElement()));
@@ -486,30 +355,26 @@ TEST(LteOp, MatchesElement) {
DEATH_TEST(LteOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
- LTEMatchExpression lte;
- lte.init("", operand.firstElement()).ignore();
+ LTEMatchExpression lte("", operand.firstElement());
}
TEST(LteOp, MatchesScalar) {
BSONObj operand = BSON("$lte" << 5);
- LTEMatchExpression lte;
- ASSERT(lte.init("a", operand["$lte"]).isOK());
+ LTEMatchExpression lte("a", operand["$lte"]);
ASSERT(lte.matchesBSON(BSON("a" << 4.5), NULL));
ASSERT(!lte.matchesBSON(BSON("a" << 6), NULL));
}
TEST(LteOp, MatchesArrayValue) {
BSONObj operand = BSON("$lte" << 5);
- LTEMatchExpression lte;
- ASSERT(lte.init("a", operand["$lte"]).isOK());
+ LTEMatchExpression lte("a", operand["$lte"]);
ASSERT(lte.matchesBSON(BSON("a" << BSON_ARRAY(6 << 4.5)), NULL));
ASSERT(!lte.matchesBSON(BSON("a" << BSON_ARRAY(6 << 7)), NULL));
}
TEST(LteOp, MatchesWholeArray) {
BSONObj operand = BSON("$lte" << BSON_ARRAY(5));
- LTEMatchExpression lte;
- ASSERT(lte.init("a", operand["$lte"]).isOK());
+ LTEMatchExpression lte("a", operand["$lte"]);
ASSERT(lte.matchesBSON(BSON("a" << BSON_ARRAY(4)), NULL));
ASSERT(lte.matchesBSON(BSON("a" << BSON_ARRAY(5)), NULL));
ASSERT(!lte.matchesBSON(BSON("a" << BSON_ARRAY(6)), NULL));
@@ -521,8 +386,7 @@ TEST(LteOp, MatchesWholeArray) {
TEST(LteOp, MatchesNull) {
BSONObj operand = BSON("$lte" << BSONNULL);
- LTEMatchExpression lte;
- ASSERT(lte.init("a", operand["$lte"]).isOK());
+ LTEMatchExpression lte("a", operand["$lte"]);
ASSERT(lte.matchesBSON(BSONObj(), NULL));
ASSERT(lte.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!lte.matchesBSON(BSON("a" << 4), NULL));
@@ -532,8 +396,7 @@ TEST(LteOp, MatchesNull) {
TEST(LteOp, MatchesDotNotationNull) {
BSONObj operand = BSON("$lte" << BSONNULL);
- LTEMatchExpression lte;
- ASSERT(lte.init("a.b", operand["$lte"]).isOK());
+ LTEMatchExpression lte("a.b", operand["$lte"]);
ASSERT(lte.matchesBSON(BSONObj(), NULL));
ASSERT(lte.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(lte.matchesBSON(BSON("a" << 4), NULL));
@@ -546,8 +409,7 @@ TEST(LteOp, MatchesDotNotationNull) {
TEST(LteOp, MatchesMinKey) {
BSONObj operand = BSON("a" << MinKey);
- LTEMatchExpression lte;
- ASSERT(lte.init("a", operand["a"]).isOK());
+ LTEMatchExpression lte("a", operand["a"]);
ASSERT(lte.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(!lte.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(!lte.matchesBSON(BSON("a" << 4), NULL));
@@ -555,8 +417,7 @@ TEST(LteOp, MatchesMinKey) {
TEST(LteOp, MatchesMaxKey) {
BSONObj operand = BSON("a" << MaxKey);
- LTEMatchExpression lte;
- ASSERT(lte.init("a", operand["a"]).isOK());
+ LTEMatchExpression lte("a", operand["a"]);
ASSERT(lte.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(lte.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(lte.matchesBSON(BSON("a" << 4), NULL));
@@ -565,8 +426,7 @@ TEST(LteOp, MatchesMaxKey) {
TEST(LteOp, ElemMatchKey) {
BSONObj operand = BSON("$lte" << 5);
- LTEMatchExpression lte;
- ASSERT(lte.init("a", operand["$lte"]).isOK());
+ LTEMatchExpression lte("a", operand["$lte"]);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!lte.matchesBSON(BSON("a" << 6), &details));
@@ -578,97 +438,28 @@ TEST(LteOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
-/**
- TEST( LteOp, MatchesIndexKeyScalar ) {
- BSONObj operand = BSON( "$lte" << 6 );
- LteOp lte;
- ASSERT( lte.init( "a", operand[ "$lte" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- lte.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- lte.matchesIndexKey( BSON( "" << 7 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- lte.matchesIndexKey( BSON( "" << BSON_ARRAY( 5 ) ), indexSpec ) );
- }
-
- TEST( LteOp, MatchesIndexKeyMissing ) {
- BSONObj operand = BSON( "$lte" << 6 );
- LteOp lte;
- ASSERT( lte.init( "a", operand[ "$lte" ] ).isOK() );
- IndexSpec indexSpec( BSON( "b" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- lte.matchesIndexKey( BSON( "" << 7 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- lte.matchesIndexKey( BSON( "" << 4 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- lte.matchesIndexKey( BSON( "" << BSON_ARRAY( 8 << 6 ) ), indexSpec ) );
- }
-
- TEST( LteOp, MatchesIndexKeyArray ) {
- BSONObj operand = BSON( "$lte" << BSON_ARRAY( 4 << 5 ) );
- LteOp lte;
- ASSERT( lte.init( "a", operand[ "$lte" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- lte.matchesIndexKey( BSON( "" << 3 ), indexSpec ) );
- }
-
- TEST( LteOp, MatchesIndexKeyArrayValue ) {
- BSONObj operand = BSON( "$lte" << 6 );
- LteOp lte;
- ASSERT( lte.init( "a", operand[ "$lte" ] ).isOK() );
- IndexSpec indexSpec( BSON( "loc" << "mockarrayvalue" << "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- lte.matchesIndexKey( BSON( "" << "dummygeohash" << "" << 3 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- lte.matchesIndexKey( BSON( "" << "dummygeohash" << "" << 7 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- lte.matchesIndexKey( BSON( "" << "dummygeohash" <<
- "" << BSON_ARRAY( 8 << 6 << 4 ) ), indexSpec ) );
- }
-
- TEST( GtOp, MatchesElement ) {
- BSONObj operand = BSON( "$gt" << 5 );
- BSONObj match = BSON( "a" << 5.5 );
- BSONObj notMatch = BSON( "a" << 4 );
- BSONObj notMatchEqual = BSON( "a" << 5 );
- BSONObj notMatchWrongType = BSON( "a" << "foo" );
- GtOp gt;
- ASSERT( gt.init( "", operand[ "$gt" ] ).isOK() );
- ASSERT( gt.matchesSingleElement( match.firstElement() ) );
- ASSERT( !gt.matchesSingleElement( notMatch.firstElement() ) );
- ASSERT( !gt.matchesSingleElement( notMatchEqual.firstElement() ) );
- ASSERT( !gt.matchesSingleElement( notMatchWrongType.firstElement() ) );
- }
-*/
-
DEATH_TEST(GtOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
- GTMatchExpression gt;
- gt.init("", operand.firstElement()).ignore();
+ GTMatchExpression gt("", operand.firstElement());
}
TEST(GtOp, MatchesScalar) {
BSONObj operand = BSON("$gt" << 5);
- GTMatchExpression gt;
- ASSERT(gt.init("a", operand["$gt"]).isOK());
+ GTMatchExpression gt("a", operand["$gt"]);
ASSERT(gt.matchesBSON(BSON("a" << 5.5), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << 4), NULL));
}
TEST(GtOp, MatchesArrayValue) {
BSONObj operand = BSON("$gt" << 5);
- GTMatchExpression gt;
- ASSERT(gt.init("a", operand["$gt"]).isOK());
+ GTMatchExpression gt("a", operand["$gt"]);
ASSERT(gt.matchesBSON(BSON("a" << BSON_ARRAY(3 << 5.5)), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << BSON_ARRAY(2 << 4)), NULL));
}
TEST(GtOp, MatchesWholeArray) {
BSONObj operand = BSON("$gt" << BSON_ARRAY(5));
- GTMatchExpression gt;
- ASSERT(gt.init("a", operand["$gt"]).isOK());
+ GTMatchExpression gt("a", operand["$gt"]);
ASSERT(!gt.matchesBSON(BSON("a" << BSON_ARRAY(4)), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << BSON_ARRAY(5)), NULL));
ASSERT(gt.matchesBSON(BSON("a" << BSON_ARRAY(6)), NULL));
@@ -682,8 +473,7 @@ TEST(GtOp, MatchesWholeArray) {
TEST(GtOp, MatchesNull) {
BSONObj operand = BSON("$gt" << BSONNULL);
- GTMatchExpression gt;
- ASSERT(gt.init("a", operand["$gt"]).isOK());
+ GTMatchExpression gt("a", operand["$gt"]);
ASSERT(!gt.matchesBSON(BSONObj(), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << 4), NULL));
@@ -693,8 +483,7 @@ TEST(GtOp, MatchesNull) {
TEST(GtOp, MatchesDotNotationNull) {
BSONObj operand = BSON("$gt" << BSONNULL);
- GTMatchExpression gt;
- ASSERT(gt.init("a.b", operand["$gt"]).isOK());
+ GTMatchExpression gt("a.b", operand["$gt"]);
ASSERT(!gt.matchesBSON(BSONObj(), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << 4), NULL));
@@ -707,8 +496,7 @@ TEST(GtOp, MatchesDotNotationNull) {
TEST(GtOp, MatchesMinKey) {
BSONObj operand = BSON("a" << MinKey);
- GTMatchExpression gt;
- ASSERT(gt.init("a", operand["a"]).isOK());
+ GTMatchExpression gt("a", operand["a"]);
ASSERT(!gt.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(gt.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(gt.matchesBSON(BSON("a" << 4), NULL));
@@ -716,8 +504,7 @@ TEST(GtOp, MatchesMinKey) {
TEST(GtOp, MatchesMaxKey) {
BSONObj operand = BSON("a" << MaxKey);
- GTMatchExpression gt;
- ASSERT(gt.init("a", operand["a"]).isOK());
+ GTMatchExpression gt("a", operand["a"]);
ASSERT(!gt.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(!gt.matchesBSON(BSON("a" << 4), NULL));
@@ -725,8 +512,7 @@ TEST(GtOp, MatchesMaxKey) {
TEST(GtOp, ElemMatchKey) {
BSONObj operand = BSON("$gt" << 5);
- GTMatchExpression gt;
- ASSERT(gt.init("a", operand["$gt"]).isOK());
+ GTMatchExpression gt("a", operand["$gt"]);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!gt.matchesBSON(BSON("a" << 4), &details));
@@ -738,57 +524,6 @@ TEST(GtOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
-/**
- TEST( GtOp, MatchesIndexKeyScalar ) {
- BSONObj operand = BSON( "$gt" << 6 );
- GtOp gt;
- ASSERT( gt.init( "a", operand[ "$gt" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- gt.matchesIndexKey( BSON( "" << 7 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- gt.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- gt.matchesIndexKey( BSON( "" << BSON_ARRAY( 9 ) ), indexSpec ) );
- }
-
- TEST( GtOp, MatchesIndexKeyMissing ) {
- BSONObj operand = BSON( "$gt" << 6 );
- GtOp gt;
- ASSERT( gt.init( "a", operand[ "$gt" ] ).isOK() );
- IndexSpec indexSpec( BSON( "b" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- gt.matchesIndexKey( BSON( "" << 7 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- gt.matchesIndexKey( BSON( "" << 4 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- gt.matchesIndexKey( BSON( "" << BSON_ARRAY( 8 << 6 ) ), indexSpec ) );
- }
-
- TEST( GtOp, MatchesIndexKeyArray ) {
- BSONObj operand = BSON( "$gt" << BSON_ARRAY( 4 << 5 ) );
- GtOp gt;
- ASSERT( gt.init( "a", operand[ "$gt" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- gt.matchesIndexKey( BSON( "" << 8 ), indexSpec ) );
- }
-
- TEST( GtOp, MatchesIndexKeyArrayValue ) {
- BSONObj operand = BSON( "$gt" << 6 );
- GtOp gt;
- ASSERT( gt.init( "a", operand[ "$gt" ] ).isOK() );
- IndexSpec indexSpec( BSON( "loc" << "mockarrayvalue" << "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- gt.matchesIndexKey( BSON( "" << "dummygeohash" << "" << 7 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- gt.matchesIndexKey( BSON( "" << "dummygeohash" << "" << 3 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- gt.matchesIndexKey( BSON( "" << "dummygeohash" <<
- "" << BSON_ARRAY( 8 << 6 << 4 ) ), indexSpec ) );
- }
-*/
-
TEST(GteOp, MatchesElement) {
BSONObj operand = BSON("$gte" << 5);
BSONObj match = BSON("a" << 5.5);
@@ -796,8 +531,7 @@ TEST(GteOp, MatchesElement) {
BSONObj notMatch = BSON("a" << 4);
BSONObj notMatchWrongType = BSON("a"
<< "foo");
- GTEMatchExpression gte;
- ASSERT(gte.init("", operand["$gte"]).isOK());
+ GTEMatchExpression gte("", operand["$gte"]);
ASSERT(gte.matchesSingleElement(match.firstElement()));
ASSERT(gte.matchesSingleElement(equalMatch.firstElement()));
ASSERT(!gte.matchesSingleElement(notMatch.firstElement()));
@@ -806,30 +540,26 @@ TEST(GteOp, MatchesElement) {
DEATH_TEST(GteOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
- GTEMatchExpression gte;
- gte.init("", operand.firstElement()).ignore();
+ GTEMatchExpression gte("", operand.firstElement());
}
TEST(GteOp, MatchesScalar) {
BSONObj operand = BSON("$gte" << 5);
- GTEMatchExpression gte;
- ASSERT(gte.init("a", operand["$gte"]).isOK());
+ GTEMatchExpression gte("a", operand["$gte"]);
ASSERT(gte.matchesBSON(BSON("a" << 5.5), NULL));
ASSERT(!gte.matchesBSON(BSON("a" << 4), NULL));
}
TEST(GteOp, MatchesArrayValue) {
BSONObj operand = BSON("$gte" << 5);
- GTEMatchExpression gte;
- ASSERT(gte.init("a", operand["$gte"]).isOK());
+ GTEMatchExpression gte("a", operand["$gte"]);
ASSERT(gte.matchesBSON(BSON("a" << BSON_ARRAY(4 << 5.5)), NULL));
ASSERT(!gte.matchesBSON(BSON("a" << BSON_ARRAY(1 << 2)), NULL));
}
TEST(GteOp, MatchesWholeArray) {
BSONObj operand = BSON("$gte" << BSON_ARRAY(5));
- GTEMatchExpression gte;
- ASSERT(gte.init("a", operand["$gte"]).isOK());
+ GTEMatchExpression gte("a", operand["$gte"]);
ASSERT(!gte.matchesBSON(BSON("a" << BSON_ARRAY(4)), NULL));
ASSERT(gte.matchesBSON(BSON("a" << BSON_ARRAY(5)), NULL));
ASSERT(gte.matchesBSON(BSON("a" << BSON_ARRAY(6)), NULL));
@@ -842,8 +572,7 @@ TEST(GteOp, MatchesWholeArray) {
TEST(GteOp, MatchesNull) {
BSONObj operand = BSON("$gte" << BSONNULL);
- GTEMatchExpression gte;
- ASSERT(gte.init("a", operand["$gte"]).isOK());
+ GTEMatchExpression gte("a", operand["$gte"]);
ASSERT(gte.matchesBSON(BSONObj(), NULL));
ASSERT(gte.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!gte.matchesBSON(BSON("a" << 4), NULL));
@@ -853,8 +582,7 @@ TEST(GteOp, MatchesNull) {
TEST(GteOp, MatchesDotNotationNull) {
BSONObj operand = BSON("$gte" << BSONNULL);
- GTEMatchExpression gte;
- ASSERT(gte.init("a.b", operand["$gte"]).isOK());
+ GTEMatchExpression gte("a.b", operand["$gte"]);
ASSERT(gte.matchesBSON(BSONObj(), NULL));
ASSERT(gte.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(gte.matchesBSON(BSON("a" << 4), NULL));
@@ -867,8 +595,7 @@ TEST(GteOp, MatchesDotNotationNull) {
TEST(GteOp, MatchesMinKey) {
BSONObj operand = BSON("a" << MinKey);
- GTEMatchExpression gte;
- ASSERT(gte.init("a", operand["a"]).isOK());
+ GTEMatchExpression gte("a", operand["a"]);
ASSERT(gte.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(gte.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(gte.matchesBSON(BSON("a" << 4), NULL));
@@ -876,8 +603,7 @@ TEST(GteOp, MatchesMinKey) {
TEST(GteOp, MatchesMaxKey) {
BSONObj operand = BSON("a" << MaxKey);
- GTEMatchExpression gte;
- ASSERT(gte.init("a", operand["a"]).isOK());
+ GTEMatchExpression gte("a", operand["a"]);
ASSERT(gte.matchesBSON(BSON("a" << MaxKey), NULL));
ASSERT(!gte.matchesBSON(BSON("a" << MinKey), NULL));
ASSERT(!gte.matchesBSON(BSON("a" << 4), NULL));
@@ -885,8 +611,7 @@ TEST(GteOp, MatchesMaxKey) {
TEST(GteOp, ElemMatchKey) {
BSONObj operand = BSON("$gte" << 5);
- GTEMatchExpression gte;
- ASSERT(gte.init("a", operand["$gte"]).isOK());
+ GTEMatchExpression gte("a", operand["$gte"]);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!gte.matchesBSON(BSON("a" << 4), &details));
@@ -903,16 +628,16 @@ TEST(RegexMatchExpression, MatchesElementExact) {
<< "b");
BSONObj notMatch = BSON("a"
<< "c");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "b", "").isOK());
+ RegexMatchExpression regex("", "b", "");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
}
TEST(RegexMatchExpression, TooLargePattern) {
string tooLargePattern(50 * 1000, 'z');
- RegexMatchExpression regex;
- ASSERT(!regex.init("a", tooLargePattern, "").isOK());
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("a", tooLargePattern, ""),
+ AssertionException,
+ ErrorCodes::BadValue);
}
TEST(RegexMatchExpression, MatchesElementSimplePrefix) {
@@ -920,8 +645,7 @@ TEST(RegexMatchExpression, MatchesElementSimplePrefix) {
<< "abc");
BSONObj notMatch = BSON("x"
<< "adz");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "^ab", "").isOK());
+ RegexMatchExpression regex("", "^ab", "");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
}
@@ -931,8 +655,7 @@ TEST(RegexMatchExpression, MatchesElementCaseSensitive) {
<< "abc");
BSONObj notMatch = BSON("x"
<< "ABC");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "abc", "").isOK());
+ RegexMatchExpression regex("", "abc", "");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
}
@@ -944,8 +667,7 @@ TEST(RegexMatchExpression, MatchesElementCaseInsensitive) {
<< "ABC");
BSONObj notMatch = BSON("x"
<< "abz");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "abc", "i").isOK());
+ RegexMatchExpression regex("", "abc", "i");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(regex.matchesSingleElement(matchUppercase.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
@@ -956,8 +678,7 @@ TEST(RegexMatchExpression, MatchesElementMultilineOff) {
<< "az");
BSONObj notMatch = BSON("x"
<< "\naz");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "^a", "").isOK());
+ RegexMatchExpression regex("", "^a", "");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
}
@@ -969,8 +690,7 @@ TEST(RegexMatchExpression, MatchesElementMultilineOn) {
<< "\naz");
BSONObj notMatch = BSON("x"
<< "\n\n");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "^a", "m").isOK());
+ RegexMatchExpression regex("", "^a", "m");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(regex.matchesSingleElement(matchMultiline.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
@@ -981,8 +701,7 @@ TEST(RegexMatchExpression, MatchesElementExtendedOff) {
<< "a b");
BSONObj notMatch = BSON("x"
<< "ab");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "a b", "").isOK());
+ RegexMatchExpression regex("", "a b", "");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
}
@@ -992,8 +711,7 @@ TEST(RegexMatchExpression, MatchesElementExtendedOn) {
<< "ab");
BSONObj notMatch = BSON("x"
<< "a b");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "a b", "x").isOK());
+ RegexMatchExpression regex("", "a b", "x");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
}
@@ -1003,8 +721,7 @@ TEST(RegexMatchExpression, MatchesElementDotAllOff) {
<< "a b");
BSONObj notMatch = BSON("x"
<< "a\nb");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "a.b", "").isOK());
+ RegexMatchExpression regex("", "a.b", "");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
}
@@ -1016,8 +733,7 @@ TEST(RegexMatchExpression, MatchesElementDotAllOn) {
<< "a\nb");
BSONObj notMatch = BSON("x"
<< "ab");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "a.b", "s").isOK());
+ RegexMatchExpression regex("", "a.b", "s");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(regex.matchesSingleElement(matchDotAll.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
@@ -1026,8 +742,7 @@ TEST(RegexMatchExpression, MatchesElementDotAllOn) {
TEST(RegexMatchExpression, MatchesElementMultipleFlags) {
BSONObj matchMultilineDotAll = BSON("x"
<< "\na\nb");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "^a.b", "ms").isOK());
+ RegexMatchExpression regex("", "^a.b", "ms");
ASSERT(regex.matchesSingleElement(matchMultilineDotAll.firstElement()));
}
@@ -1035,8 +750,7 @@ TEST(RegexMatchExpression, MatchesElementRegexType) {
BSONObj match = BSONObjBuilder().appendRegex("x", "yz", "i").obj();
BSONObj notMatchPattern = BSONObjBuilder().appendRegex("x", "r", "i").obj();
BSONObj notMatchFlags = BSONObjBuilder().appendRegex("x", "yz", "s").obj();
- RegexMatchExpression regex;
- ASSERT(regex.init("", "yz", "i").isOK());
+ RegexMatchExpression regex("", "yz", "i");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatchPattern.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatchFlags.firstElement()));
@@ -1045,8 +759,7 @@ TEST(RegexMatchExpression, MatchesElementRegexType) {
TEST(RegexMatchExpression, MatchesElementSymbolType) {
BSONObj match = BSONObjBuilder().appendSymbol("x", "yz").obj();
BSONObj notMatch = BSONObjBuilder().appendSymbol("x", "gg").obj();
- RegexMatchExpression regex;
- ASSERT(regex.init("", "yz", "").isOK());
+ RegexMatchExpression regex("", "yz", "");
ASSERT(regex.matchesSingleElement(match.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatch.firstElement()));
}
@@ -1054,8 +767,7 @@ TEST(RegexMatchExpression, MatchesElementSymbolType) {
TEST(RegexMatchExpression, MatchesElementWrongType) {
BSONObj notMatchInt = BSON("x" << 1);
BSONObj notMatchBool = BSON("x" << true);
- RegexMatchExpression regex;
- ASSERT(regex.init("", "1", "").isOK());
+ RegexMatchExpression regex("", "1", "");
ASSERT(!regex.matchesSingleElement(notMatchInt.firstElement()));
ASSERT(!regex.matchesSingleElement(notMatchBool.firstElement()));
}
@@ -1063,14 +775,12 @@ TEST(RegexMatchExpression, MatchesElementWrongType) {
TEST(RegexMatchExpression, MatchesElementUtf8) {
BSONObj multiByteCharacter = BSON("x"
<< "\xc2\xa5");
- RegexMatchExpression regex;
- ASSERT(regex.init("", "^.$", "").isOK());
+ RegexMatchExpression regex("", "^.$", "");
ASSERT(regex.matchesSingleElement(multiByteCharacter.firstElement()));
}
TEST(RegexMatchExpression, MatchesScalar) {
- RegexMatchExpression regex;
- ASSERT(regex.init("a", "b", "").isOK());
+ RegexMatchExpression regex("a", "b", "");
ASSERT(regex.matchesBSON(BSON("a"
<< "b"),
NULL));
@@ -1080,8 +790,7 @@ TEST(RegexMatchExpression, MatchesScalar) {
}
TEST(RegexMatchExpression, MatchesArrayValue) {
- RegexMatchExpression regex;
- ASSERT(regex.init("a", "b", "").isOK());
+ RegexMatchExpression regex("a", "b", "");
ASSERT(regex.matchesBSON(BSON("a" << BSON_ARRAY("c"
<< "b")),
NULL));
@@ -1091,15 +800,13 @@ TEST(RegexMatchExpression, MatchesArrayValue) {
}
TEST(RegexMatchExpression, MatchesNull) {
- RegexMatchExpression regex;
- ASSERT(regex.init("a", "b", "").isOK());
+ RegexMatchExpression regex("a", "b", "");
ASSERT(!regex.matchesBSON(BSONObj(), NULL));
ASSERT(!regex.matchesBSON(BSON("a" << BSONNULL), NULL));
}
TEST(RegexMatchExpression, ElemMatchKey) {
- RegexMatchExpression regex;
- ASSERT(regex.init("a", "b", "").isOK());
+ RegexMatchExpression regex("a", "b", "");
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!regex.matchesBSON(BSON("a"
@@ -1118,14 +825,10 @@ TEST(RegexMatchExpression, ElemMatchKey) {
}
TEST(RegexMatchExpression, Equality1) {
- RegexMatchExpression r1;
- RegexMatchExpression r2;
- RegexMatchExpression r3;
- RegexMatchExpression r4;
- ASSERT(r1.init("a", "b", "").isOK());
- ASSERT(r2.init("a", "b", "x").isOK());
- ASSERT(r3.init("a", "c", "").isOK());
- ASSERT(r4.init("b", "b", "").isOK());
+ RegexMatchExpression r1("a", "b", "");
+ RegexMatchExpression r2("a", "b", "x");
+ RegexMatchExpression r3("a", "c", "");
+ RegexMatchExpression r4("b", "b", "");
ASSERT(r1.equivalent(&r1));
ASSERT(!r1.equivalent(&r2));
@@ -1134,55 +837,69 @@ TEST(RegexMatchExpression, Equality1) {
}
TEST(RegexMatchExpression, RegexCannotContainEmbeddedNullByte) {
- RegexMatchExpression regex;
{
const auto embeddedNull = "a\0b"_sd;
- ASSERT_NOT_OK(regex.init("path", embeddedNull, ""));
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("path", embeddedNull, ""),
+ AssertionException,
+ ErrorCodes::BadValue);
}
{
const auto singleNullByte = "\0"_sd;
- ASSERT_NOT_OK(regex.init("path", singleNullByte, ""));
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("path", singleNullByte, ""),
+ AssertionException,
+ ErrorCodes::BadValue);
}
{
const auto leadingNullByte = "\0bbbb"_sd;
- ASSERT_NOT_OK(regex.init("path", leadingNullByte, ""));
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("path", leadingNullByte, ""),
+ AssertionException,
+ ErrorCodes::BadValue);
}
{
const auto trailingNullByte = "bbbb\0"_sd;
- ASSERT_NOT_OK(regex.init("path", trailingNullByte, ""));
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("path", trailingNullByte, ""),
+ AssertionException,
+ ErrorCodes::BadValue);
}
}
TEST(RegexMatchExpression, RegexOptionsStringCannotContainEmbeddedNullByte) {
- RegexMatchExpression regex;
{
const auto embeddedNull = "a\0b"_sd;
- ASSERT_NOT_OK(regex.init("path", "pattern", embeddedNull));
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("path", "pattern", embeddedNull),
+ AssertionException,
+ ErrorCodes::BadValue);
}
{
const auto singleNullByte = "\0"_sd;
- ASSERT_NOT_OK(regex.init("path", "pattern", singleNullByte));
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("path", "pattern", singleNullByte),
+ AssertionException,
+ ErrorCodes::BadValue);
}
{
const auto leadingNullByte = "\0bbbb"_sd;
- ASSERT_NOT_OK(regex.init("path", "pattern", leadingNullByte));
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("path", "pattern", leadingNullByte),
+ AssertionException,
+ ErrorCodes::BadValue);
}
{
const auto trailingNullByte = "bbbb\0"_sd;
- ASSERT_NOT_OK(regex.init("path", "pattern", trailingNullByte));
+ ASSERT_THROWS_CODE(RegexMatchExpression regex("path", "pattern", trailingNullByte),
+ AssertionException,
+ ErrorCodes::BadValue);
}
}
TEST(RegexMatchExpression, RegexCannotBeInvalid) {
- RegexMatchExpression regex;
const auto invalid = "["_sd;
- ASSERT_NOT_OK(regex.init("path", invalid, ""));
+ ASSERT_THROWS_CODE(
+ RegexMatchExpression regex("path", invalid, ""), AssertionException, ErrorCodes::BadValue);
}
TEST(ModMatchExpression, MatchesElement) {
@@ -1191,8 +908,7 @@ TEST(ModMatchExpression, MatchesElement) {
BSONObj longLongMatch = BSON("a" << 68719476736LL);
BSONObj notMatch = BSON("a" << 6);
BSONObj negativeNotMatch = BSON("a" << -2);
- ModMatchExpression mod;
- ASSERT(mod.init("", 3, 1).isOK());
+ ModMatchExpression mod("", 3, 1);
ASSERT(mod.matchesSingleElement(match.firstElement()));
ASSERT(mod.matchesSingleElement(largerMatch.firstElement()));
ASSERT(mod.matchesSingleElement(longLongMatch.firstElement()));
@@ -1201,34 +917,29 @@ TEST(ModMatchExpression, MatchesElement) {
}
TEST(ModMatchExpression, ZeroDivisor) {
- ModMatchExpression mod;
- ASSERT(!mod.init("", 0, 1).isOK());
+ ASSERT_THROWS_CODE(ModMatchExpression mod("", 0, 1), AssertionException, ErrorCodes::BadValue);
}
TEST(ModMatchExpression, MatchesScalar) {
- ModMatchExpression mod;
- ASSERT(mod.init("a", 5, 2).isOK());
+ ModMatchExpression mod("a", 5, 2);
ASSERT(mod.matchesBSON(BSON("a" << 7.0), NULL));
ASSERT(!mod.matchesBSON(BSON("a" << 4), NULL));
}
TEST(ModMatchExpression, MatchesArrayValue) {
- ModMatchExpression mod;
- ASSERT(mod.init("a", 5, 2).isOK());
+ ModMatchExpression mod("a", 5, 2);
ASSERT(mod.matchesBSON(BSON("a" << BSON_ARRAY(5 << 12LL)), NULL));
ASSERT(!mod.matchesBSON(BSON("a" << BSON_ARRAY(6 << 8)), NULL));
}
TEST(ModMatchExpression, MatchesNull) {
- ModMatchExpression mod;
- ASSERT(mod.init("a", 5, 2).isOK());
+ ModMatchExpression mod("a", 5, 2);
ASSERT(!mod.matchesBSON(BSONObj(), NULL));
ASSERT(!mod.matchesBSON(BSON("a" << BSONNULL), NULL));
}
TEST(ModMatchExpression, ElemMatchKey) {
- ModMatchExpression mod;
- ASSERT(mod.init("a", 5, 2).isOK());
+ ModMatchExpression mod("a", 5, 2);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!mod.matchesBSON(BSON("a" << 4), &details));
@@ -1241,15 +952,10 @@ TEST(ModMatchExpression, ElemMatchKey) {
}
TEST(ModMatchExpression, Equality1) {
- ModMatchExpression m1;
- ModMatchExpression m2;
- ModMatchExpression m3;
- ModMatchExpression m4;
-
- m1.init("a", 1, 2).transitional_ignore();
- m2.init("a", 2, 2).transitional_ignore();
- m3.init("a", 1, 1).transitional_ignore();
- m4.init("b", 1, 2).transitional_ignore();
+ ModMatchExpression m1("a", 1, 2);
+ ModMatchExpression m2("a", 2, 2);
+ ModMatchExpression m3("a", 1, 1);
+ ModMatchExpression m4("b", 1, 2);
ASSERT(m1.equivalent(&m1));
ASSERT(!m1.equivalent(&m2));
@@ -1257,24 +963,11 @@ TEST(ModMatchExpression, Equality1) {
ASSERT(!m1.equivalent(&m4));
}
-/**
- TEST( ModMatchExpression, MatchesIndexKey ) {
- BSONObj operand = BSON( "$mod" << BSON_ARRAY( 2 << 1 ) );
- ModMatchExpression mod;
- ASSERT( mod.init( "a", operand[ "$mod" ] ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- BSONObj indexKey = BSON( "" << 1 );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- mod.matchesIndexKey( indexKey, indexSpec ) );
- }
-*/
-
TEST(ExistsMatchExpression, MatchesElement) {
BSONObj existsInt = BSON("a" << 5);
BSONObj existsNull = BSON("a" << BSONNULL);
BSONObj doesntExist = BSONObj();
- ExistsMatchExpression exists;
- ASSERT(exists.init("").isOK());
+ ExistsMatchExpression exists("");
ASSERT(exists.matchesSingleElement(existsInt.firstElement()));
ASSERT(exists.matchesSingleElement(existsNull.firstElement()));
ASSERT(!exists.matchesSingleElement(doesntExist.firstElement()));
@@ -1283,29 +976,25 @@ TEST(ExistsMatchExpression, MatchesElement) {
TEST(ExistsMatchExpression, MatchesElementExistsTrueValue) {
BSONObj exists = BSON("a" << 5);
BSONObj missing = BSONObj();
- ExistsMatchExpression existsTrueValue;
- ASSERT(existsTrueValue.init("").isOK());
+ ExistsMatchExpression existsTrueValue("");
ASSERT(existsTrueValue.matchesSingleElement(exists.firstElement()));
ASSERT(!existsTrueValue.matchesSingleElement(missing.firstElement()));
}
TEST(ExistsMatchExpression, MatchesScalar) {
- ExistsMatchExpression exists;
- ASSERT(exists.init("a").isOK());
+ ExistsMatchExpression exists("a");
ASSERT(exists.matchesBSON(BSON("a" << 1), NULL));
ASSERT(exists.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!exists.matchesBSON(BSON("b" << 1), NULL));
}
TEST(ExistsMatchExpression, MatchesArray) {
- ExistsMatchExpression exists;
- ASSERT(exists.init("a").isOK());
+ ExistsMatchExpression exists("a");
ASSERT(exists.matchesBSON(BSON("a" << BSON_ARRAY(4 << 5.5)), NULL));
}
TEST(ExistsMatchExpression, ElemMatchKey) {
- ExistsMatchExpression exists;
- ASSERT(exists.init("a.b").isOK());
+ ExistsMatchExpression exists("a.b");
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!exists.matchesBSON(BSON("a" << 1), &details));
@@ -1318,10 +1007,8 @@ TEST(ExistsMatchExpression, ElemMatchKey) {
}
TEST(ExistsMatchExpression, Equivalent) {
- ExistsMatchExpression e1;
- ExistsMatchExpression e2;
- e1.init("a").transitional_ignore();
- e2.init("b").transitional_ignore();
+ ExistsMatchExpression e1("a");
+ ExistsMatchExpression e2("b");
ASSERT(e1.equivalent(&e1));
ASSERT(!e1.equivalent(&e2));
@@ -1331,7 +1018,7 @@ TEST(InMatchExpression, MatchesElementSingle) {
BSONArray operand = BSON_ARRAY(1);
BSONObj match = BSON("a" << 1);
BSONObj notMatch = BSON("a" << 2);
- InMatchExpression in;
+ InMatchExpression in("");
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
ASSERT(in.matchesSingleElement(match["a"]));
@@ -1339,8 +1026,7 @@ TEST(InMatchExpression, MatchesElementSingle) {
}
TEST(InMatchExpression, MatchesEmpty) {
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
BSONObj notMatch = BSON("a" << 2);
ASSERT(!in.matchesSingleElement(notMatch["a"]));
@@ -1350,7 +1036,7 @@ TEST(InMatchExpression, MatchesEmpty) {
TEST(InMatchExpression, MatchesElementMultiple) {
BSONObj operand = BSON_ARRAY(1 << "r" << true << 1);
- InMatchExpression in;
+ InMatchExpression in("");
std::vector<BSONElement> equalities{operand[0], operand[1], operand[2], operand[3]};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1368,8 +1054,7 @@ TEST(InMatchExpression, MatchesElementMultiple) {
TEST(InMatchExpression, MatchesScalar) {
BSONObj operand = BSON_ARRAY(5);
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1379,8 +1064,7 @@ TEST(InMatchExpression, MatchesScalar) {
TEST(InMatchExpression, MatchesArrayValue) {
BSONObj operand = BSON_ARRAY(5);
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1392,8 +1076,7 @@ TEST(InMatchExpression, MatchesArrayValue) {
TEST(InMatchExpression, MatchesNull) {
BSONObj operand = BSON_ARRAY(BSONNULL);
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1407,16 +1090,14 @@ TEST(InMatchExpression, MatchesNull) {
TEST(InMatchExpression, MatchesUndefined) {
BSONObj operand = BSON_ARRAY(BSONUndefined);
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_NOT_OK(in.setEqualities(std::move(equalities)));
}
TEST(InMatchExpression, MatchesMinKey) {
BSONObj operand = BSON_ARRAY(MinKey);
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1427,8 +1108,7 @@ TEST(InMatchExpression, MatchesMinKey) {
TEST(InMatchExpression, MatchesMaxKey) {
BSONObj operand = BSON_ARRAY(MaxKey);
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1439,8 +1119,7 @@ TEST(InMatchExpression, MatchesMaxKey) {
TEST(InMatchExpression, MatchesFullArray) {
BSONObj operand = BSON_ARRAY(BSON_ARRAY(1 << 2) << 4 << 5);
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
std::vector<BSONElement> equalities{operand[0], operand[1], operand[2]};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1452,8 +1131,7 @@ TEST(InMatchExpression, MatchesFullArray) {
TEST(InMatchExpression, ElemMatchKey) {
BSONObj operand = BSON_ARRAY(5 << 2);
- InMatchExpression in;
- in.init("a").transitional_ignore();
+ InMatchExpression in("a");
std::vector<BSONElement> equalities{operand[0], operand[1]};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1471,8 +1149,8 @@ TEST(InMatchExpression, ElemMatchKey) {
TEST(InMatchExpression, InMatchExpressionsWithDifferentNumbersOfElementsAreUnequal) {
BSONObj obj = BSON(""
<< "string");
- InMatchExpression eq1;
- InMatchExpression eq2;
+ InMatchExpression eq1("");
+ InMatchExpression eq2("");
std::vector<BSONElement> equalities{obj.firstElement()};
ASSERT_OK(eq1.setEqualities(std::move(equalities)));
ASSERT(!eq1.equivalent(&eq2));
@@ -1480,20 +1158,20 @@ TEST(InMatchExpression, InMatchExpressionsWithDifferentNumbersOfElementsAreUnequ
TEST(InMatchExpression, InMatchExpressionsWithUnequalCollatorsAreUnequal) {
CollatorInterfaceMock collator1(CollatorInterfaceMock::MockType::kReverseString);
- InMatchExpression eq1;
+ InMatchExpression eq1("");
eq1.setCollator(&collator1);
CollatorInterfaceMock collator2(CollatorInterfaceMock::MockType::kAlwaysEqual);
- InMatchExpression eq2;
+ InMatchExpression eq2("");
eq2.setCollator(&collator2);
ASSERT(!eq1.equivalent(&eq2));
}
TEST(InMatchExpression, InMatchExpressionsWithEqualCollatorsAreEqual) {
CollatorInterfaceMock collator1(CollatorInterfaceMock::MockType::kAlwaysEqual);
- InMatchExpression eq1;
+ InMatchExpression eq1("");
eq1.setCollator(&collator1);
CollatorInterfaceMock collator2(CollatorInterfaceMock::MockType::kAlwaysEqual);
- InMatchExpression eq2;
+ InMatchExpression eq2("");
eq2.setCollator(&collator2);
ASSERT(eq1.equivalent(&eq2));
}
@@ -1504,10 +1182,10 @@ TEST(InMatchExpression, InMatchExpressionsWithCollationEquivalentElementsAreEqua
BSONObj obj2 = BSON(""
<< "string2");
CollatorInterfaceMock collator1(CollatorInterfaceMock::MockType::kAlwaysEqual);
- InMatchExpression eq1;
+ InMatchExpression eq1("");
eq1.setCollator(&collator1);
CollatorInterfaceMock collator2(CollatorInterfaceMock::MockType::kAlwaysEqual);
- InMatchExpression eq2;
+ InMatchExpression eq2("");
eq2.setCollator(&collator2);
std::vector<BSONElement> equalities1{obj1.firstElement()};
@@ -1525,10 +1203,10 @@ TEST(InMatchExpression, InMatchExpressionsWithCollationNonEquivalentElementsAreU
BSONObj obj2 = BSON(""
<< "string2");
CollatorInterfaceMock collator1(CollatorInterfaceMock::MockType::kReverseString);
- InMatchExpression eq1;
+ InMatchExpression eq1("");
eq1.setCollator(&collator1);
CollatorInterfaceMock collator2(CollatorInterfaceMock::MockType::kReverseString);
- InMatchExpression eq2;
+ InMatchExpression eq2("");
eq2.setCollator(&collator2);
std::vector<BSONElement> equalities1{obj1.firstElement()};
@@ -1544,7 +1222,7 @@ TEST(InMatchExpression, StringMatchingWithNullCollatorUsesBinaryComparison) {
BSONArray operand = BSON_ARRAY("string");
BSONObj notMatch = BSON("a"
<< "string2");
- InMatchExpression in;
+ InMatchExpression in("");
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
ASSERT(!in.matchesSingleElement(notMatch["a"]));
@@ -1555,7 +1233,7 @@ TEST(InMatchExpression, StringMatchingRespectsCollation) {
BSONObj match = BSON("a"
<< "string2");
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- InMatchExpression in;
+ InMatchExpression in("");
in.setCollator(&collator);
std::vector<BSONElement> equalities{operand.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1569,7 +1247,7 @@ TEST(InMatchExpression, ChangingCollationAfterAddingEqualitiesPreservesEqualitie
<< "string2");
CollatorInterfaceMock collatorAlwaysEqual(CollatorInterfaceMock::MockType::kAlwaysEqual);
CollatorInterfaceMock collatorReverseString(CollatorInterfaceMock::MockType::kReverseString);
- InMatchExpression in;
+ InMatchExpression in("");
in.setCollator(&collatorAlwaysEqual);
std::vector<BSONElement> equalities{obj1.firstElement(), obj2.firstElement()};
ASSERT_OK(in.setEqualities(std::move(equalities)));
@@ -1605,15 +1283,11 @@ TEST(BitTestMatchExpression, DoesNotMatchOther) {
BSONObj notMatch9 = fromjson("{a: ObjectId('000000000000000000000000')}"); // OID
BSONObj notMatch10 = fromjson("{a: Date(54)}"); // Date
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositions);
+ BitsAllClearMatchExpression ballc("a", bitPositions);
+ BitsAnySetMatchExpression banys("a", bitPositions);
+ BitsAnyClearMatchExpression banyc("a", bitPositions);
- ASSERT_OK(balls.init("a", bitPositions));
- ASSERT_OK(ballc.init("a", bitPositions));
- ASSERT_OK(banys.init("a", bitPositions));
- ASSERT_OK(banyc.init("a", bitPositions));
ASSERT_EQ((size_t)0, balls.numBitPositions());
ASSERT_EQ((size_t)0, ballc.numBitPositions());
ASSERT_EQ((size_t)0, banys.numBitPositions());
@@ -1665,15 +1339,11 @@ TEST(BitTestMatchExpression, MatchBinaryWithLongBitMask) {
BSONObj match = fromjson("{a: {$binary: 'NgAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitMask);
+ BitsAllClearMatchExpression ballc("a", bitMask);
+ BitsAnySetMatchExpression banys("a", bitMask);
+ BitsAnyClearMatchExpression banyc("a", bitMask);
- ASSERT_OK(balls.init("a", bitMask));
- ASSERT_OK(ballc.init("a", bitMask));
- ASSERT_OK(banys.init("a", bitMask));
- ASSERT_OK(banyc.init("a", bitMask));
std::vector<uint32_t> bitPositions = balls.getBitPositions();
ASSERT(balls.matchesSingleElement(match["a"]));
ASSERT(!ballc.matchesSingleElement(match["a"]));
@@ -1687,15 +1357,11 @@ TEST(BitTestMatchExpression, MatchLongWithBinaryBitMask) {
BSONObj match = fromjson("{a: 54}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitMaskSet, 4);
+ BitsAllClearMatchExpression ballc("a", bitMaskClear, 9);
+ BitsAnySetMatchExpression banys("a", bitMaskSet, 4);
+ BitsAnyClearMatchExpression banyc("a", bitMaskClear, 9);
- ASSERT_OK(balls.init("a", bitMaskSet, 4));
- ASSERT_OK(ballc.init("a", bitMaskClear, 9));
- ASSERT_OK(banys.init("a", bitMaskSet, 4));
- ASSERT_OK(banyc.init("a", bitMaskClear, 9));
ASSERT(balls.matchesSingleElement(match["a"]));
ASSERT(ballc.matchesSingleElement(match["a"]));
ASSERT(banys.matchesSingleElement(match["a"]));
@@ -1710,15 +1376,11 @@ TEST(BitTestMatchExpression, MatchesEmpty) {
BSONObj match3 = fromjson("{a: 54.0}");
BSONObj match4 = fromjson("{a: {$binary: '2AAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositions);
+ BitsAllClearMatchExpression ballc("a", bitPositions);
+ BitsAnySetMatchExpression banys("a", bitPositions);
+ BitsAnyClearMatchExpression banyc("a", bitPositions);
- ASSERT_OK(balls.init("a", bitPositions));
- ASSERT_OK(ballc.init("a", bitPositions));
- ASSERT_OK(banys.init("a", bitPositions));
- ASSERT_OK(banyc.init("a", bitPositions));
ASSERT_EQ((size_t)0, balls.numBitPositions());
ASSERT_EQ((size_t)0, ballc.numBitPositions());
ASSERT_EQ((size_t)0, banys.numBitPositions());
@@ -1751,15 +1413,11 @@ TEST(BitTestMatchExpression, MatchesInteger) {
BSONObj match2 = fromjson("{a: NumberLong(54)}");
BSONObj match3 = fromjson("{a: 54.0}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositionsSet);
+ BitsAllClearMatchExpression ballc("a", bitPositionsClear);
+ BitsAnySetMatchExpression banys("a", bitPositionsSet);
+ BitsAnyClearMatchExpression banyc("a", bitPositionsClear);
- ASSERT_OK(balls.init("a", bitPositionsSet));
- ASSERT_OK(ballc.init("a", bitPositionsClear));
- ASSERT_OK(banys.init("a", bitPositionsSet));
- ASSERT_OK(banyc.init("a", bitPositionsClear));
ASSERT_EQ((size_t)4, balls.numBitPositions());
ASSERT_EQ((size_t)3, ballc.numBitPositions());
ASSERT_EQ((size_t)4, banys.numBitPositions());
@@ -1788,15 +1446,11 @@ TEST(BitTestMatchExpression, MatchesNegativeInteger) {
BSONObj match2 = fromjson("{a: NumberLong(-54)}");
BSONObj match3 = fromjson("{a: -54.0}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositionsSet);
+ BitsAllClearMatchExpression ballc("a", bitPositionsClear);
+ BitsAnySetMatchExpression banys("a", bitPositionsSet);
+ BitsAnyClearMatchExpression banyc("a", bitPositionsClear);
- ASSERT_OK(balls.init("a", bitPositionsSet));
- ASSERT_OK(ballc.init("a", bitPositionsClear));
- ASSERT_OK(banys.init("a", bitPositionsSet));
- ASSERT_OK(banyc.init("a", bitPositionsClear));
ASSERT_EQ((size_t)5, balls.numBitPositions());
ASSERT_EQ((size_t)4, ballc.numBitPositions());
ASSERT_EQ((size_t)5, banys.numBitPositions());
@@ -1823,15 +1477,11 @@ TEST(BitTestMatchExpression, MatchesIntegerWithBitMask) {
BSONObj match2 = fromjson("{a: NumberLong(54)}");
BSONObj match3 = fromjson("{a: 54.0}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitMaskSet);
+ BitsAllClearMatchExpression ballc("a", bitMaskClear);
+ BitsAnySetMatchExpression banys("a", bitMaskSet);
+ BitsAnyClearMatchExpression banyc("a", bitMaskClear);
- ASSERT_OK(balls.init("a", bitMaskSet));
- ASSERT_OK(ballc.init("a", bitMaskClear));
- ASSERT_OK(banys.init("a", bitMaskSet));
- ASSERT_OK(banyc.init("a", bitMaskClear));
ASSERT(balls.matchesSingleElement(match1["a"]));
ASSERT(balls.matchesSingleElement(match2["a"]));
ASSERT(balls.matchesSingleElement(match3["a"]));
@@ -1854,15 +1504,11 @@ TEST(BitTestMatchExpression, MatchesNegativeIntegerWithBitMask) {
BSONObj match2 = fromjson("{a: NumberLong(-54)}");
BSONObj match3 = fromjson("{a: -54.0}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitMaskSet);
+ BitsAllClearMatchExpression ballc("a", bitMaskClear);
+ BitsAnySetMatchExpression banys("a", bitMaskSet);
+ BitsAnyClearMatchExpression banyc("a", bitMaskClear);
- ASSERT_OK(balls.init("a", bitMaskSet));
- ASSERT_OK(ballc.init("a", bitMaskClear));
- ASSERT_OK(banys.init("a", bitMaskSet));
- ASSERT_OK(banyc.init("a", bitMaskClear));
ASSERT(balls.matchesSingleElement(match1["a"]));
ASSERT(balls.matchesSingleElement(match2["a"]));
ASSERT(balls.matchesSingleElement(match3["a"]));
@@ -1887,15 +1533,11 @@ TEST(BitTestMatchExpression, DoesNotMatchInteger) {
BSONObj match2 = fromjson("{a: NumberLong(54)}");
BSONObj match3 = fromjson("{a: 54.0}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositionsSet);
+ BitsAllClearMatchExpression ballc("a", bitPositionsClear);
+ BitsAnySetMatchExpression banys("a", bitPositionsSet);
+ BitsAnyClearMatchExpression banyc("a", bitPositionsClear);
- ASSERT_OK(balls.init("a", bitPositionsSet));
- ASSERT_OK(ballc.init("a", bitPositionsClear));
- ASSERT_OK(banys.init("a", bitPositionsSet));
- ASSERT_OK(banyc.init("a", bitPositionsClear));
ASSERT_EQ((size_t)5, balls.numBitPositions());
ASSERT_EQ((size_t)3, ballc.numBitPositions());
ASSERT_EQ((size_t)5, banys.numBitPositions());
@@ -1922,15 +1564,11 @@ TEST(BitTestMatchExpression, DoesNotMatchIntegerWithBitMask) {
BSONObj match2 = fromjson("{a: NumberLong(54)}");
BSONObj match3 = fromjson("{a: 54.0}");
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitMaskSet);
+ BitsAllClearMatchExpression ballc("a", bitMaskClear);
+ BitsAnySetMatchExpression banys("a", bitMaskSet);
+ BitsAnyClearMatchExpression banyc("a", bitMaskClear);
- ASSERT_OK(balls.init("a", bitMaskSet));
- ASSERT_OK(ballc.init("a", bitMaskClear));
- ASSERT_OK(banys.init("a", bitMaskSet));
- ASSERT_OK(banyc.init("a", bitMaskClear));
ASSERT(!balls.matchesSingleElement(match1["a"]));
ASSERT(!balls.matchesSingleElement(match2["a"]));
ASSERT(!balls.matchesSingleElement(match3["a"]));
@@ -1956,15 +1594,11 @@ TEST(BitTestMatchExpression, MatchesBinary1) {
BSONObj match2 = fromjson("{a: {$binary: 'NgAjqwetkqwklEWRbWERKKJREtbq', $type: '00'}}");
// Base64 to Binary: 00110110...
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositionsSet);
+ BitsAllClearMatchExpression ballc("a", bitPositionsClear);
+ BitsAnySetMatchExpression banys("a", bitPositionsSet);
+ BitsAnyClearMatchExpression banyc("a", bitPositionsClear);
- ASSERT_OK(balls.init("a", bitPositionsSet));
- ASSERT_OK(ballc.init("a", bitPositionsClear));
- ASSERT_OK(banys.init("a", bitPositionsSet));
- ASSERT_OK(banyc.init("a", bitPositionsClear));
ASSERT_EQ((size_t)4, balls.numBitPositions());
ASSERT_EQ((size_t)3, ballc.numBitPositions());
ASSERT_EQ((size_t)4, banys.numBitPositions());
@@ -1990,15 +1624,11 @@ TEST(BitTestMatchExpression, MatchesBinary2) {
BSONObj match2 = fromjson("{a: {$binary: 'JANgqwetkqwklEWRbWERKKJREtbq', $type: '00'}}");
// Base64 to Binary: ........ 00000011 01100000
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositionsSet);
+ BitsAllClearMatchExpression ballc("a", bitPositionsClear);
+ BitsAnySetMatchExpression banys("a", bitPositionsSet);
+ BitsAnyClearMatchExpression banyc("a", bitPositionsClear);
- ASSERT_OK(balls.init("a", bitPositionsSet));
- ASSERT_OK(ballc.init("a", bitPositionsClear));
- ASSERT_OK(banys.init("a", bitPositionsSet));
- ASSERT_OK(banyc.init("a", bitPositionsClear));
ASSERT_EQ((size_t)4, balls.numBitPositions());
ASSERT_EQ((size_t)3, ballc.numBitPositions());
ASSERT_EQ((size_t)4, banys.numBitPositions());
@@ -2022,14 +1652,11 @@ TEST(BitTestMatchExpression, MatchesBinaryWithBitMask) {
BSONObj match2 = fromjson("{a: {$binary: 'JANgAwetkqwklEWRbWERKKJREtbq', $type: '00'}}");
// Base64 to Binary: ........ 00000011 01100000
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
- ASSERT_OK(balls.init("a", bas, 21));
- ASSERT_OK(ballc.init("a", bac, 21));
- ASSERT_OK(banys.init("a", bas, 21));
- ASSERT_OK(banyc.init("a", bac, 21));
+ BitsAllSetMatchExpression balls("a", bas, 21);
+ BitsAllClearMatchExpression ballc("a", bac, 21);
+ BitsAnySetMatchExpression banys("a", bas, 21);
+ BitsAnyClearMatchExpression banyc("a", bac, 21);
+
ASSERT(balls.matchesSingleElement(match1["a"]));
ASSERT(balls.matchesSingleElement(match2["a"]));
ASSERT(ballc.matchesSingleElement(match1["a"]));
@@ -2051,15 +1678,11 @@ TEST(BitTestMatchExpression, DoesNotMatchBinary1) {
BSONObj match2 = fromjson("{a: {$binary: 'NgAjqwetkqwklEWRbWERKKJREtbq', $type: '00'}}");
// Base64 to Binary: 00110110...
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositionsSet);
+ BitsAllClearMatchExpression ballc("a", bitPositionsClear);
+ BitsAnySetMatchExpression banys("a", bitPositionsSet);
+ BitsAnyClearMatchExpression banyc("a", bitPositionsClear);
- ASSERT_OK(balls.init("a", bitPositionsSet));
- ASSERT_OK(ballc.init("a", bitPositionsClear));
- ASSERT_OK(banys.init("a", bitPositionsSet));
- ASSERT_OK(banyc.init("a", bitPositionsClear));
ASSERT_EQ((size_t)5, balls.numBitPositions());
ASSERT_EQ((size_t)3, ballc.numBitPositions());
ASSERT_EQ((size_t)5, banys.numBitPositions());
@@ -2085,15 +1708,11 @@ TEST(BitTestMatchExpression, DoesNotMatchBinary2) {
BSONObj match2 = fromjson("{a: {$binary: 'JANgqwetkqwklEWRbWERKKJREtbq', $type: '00'}}");
// Base64 to Binary: ........ 00000011 01100000
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
+ BitsAllSetMatchExpression balls("a", bitPositionsSet);
+ BitsAllClearMatchExpression ballc("a", bitPositionsClear);
+ BitsAnySetMatchExpression banys("a", bitPositionsSet);
+ BitsAnyClearMatchExpression banyc("a", bitPositionsClear);
- ASSERT_OK(balls.init("a", bitPositionsSet));
- ASSERT_OK(ballc.init("a", bitPositionsClear));
- ASSERT_OK(banys.init("a", bitPositionsSet));
- ASSERT_OK(banyc.init("a", bitPositionsClear));
ASSERT_EQ((size_t)5, balls.numBitPositions());
ASSERT_EQ((size_t)3, ballc.numBitPositions());
ASSERT_EQ((size_t)5, banys.numBitPositions());
@@ -2117,14 +1736,10 @@ TEST(BitTestMatchExpression, DoesNotMatchBinaryWithBitMask) {
BSONObj match2 = fromjson("{a: {$binary: 'JANgAwetkqwklEWRbWERKKJREtbq', $type: '00'}}");
// Base64 to Binary: ........ 00000011 01100000
- BitsAllSetMatchExpression balls;
- BitsAllClearMatchExpression ballc;
- BitsAnySetMatchExpression banys;
- BitsAnyClearMatchExpression banyc;
- ASSERT_OK(balls.init("a", bas, 22));
- ASSERT_OK(ballc.init("a", bac, 22));
- ASSERT_OK(banys.init("a", bas, 22));
- ASSERT_OK(banyc.init("a", bac, 22));
+ BitsAllSetMatchExpression balls("a", bas, 22);
+ BitsAllClearMatchExpression ballc("a", bac, 22);
+ BitsAnySetMatchExpression banys("a", bas, 22);
+ BitsAnyClearMatchExpression banyc("a", bac, 22);
ASSERT(!balls.matchesSingleElement(match1["a"]));
ASSERT(!balls.matchesSingleElement(match2["a"]));
ASSERT(!ballc.matchesSingleElement(match1["a"]));
diff --git a/src/mongo/db/matcher/expression_optimize_test.cpp b/src/mongo/db/matcher/expression_optimize_test.cpp
index acbd7bc4ecb..93f7a49882f 100644
--- a/src/mongo/db/matcher/expression_optimize_test.cpp
+++ b/src/mongo/db/matcher/expression_optimize_test.cpp
@@ -339,7 +339,7 @@ TEST(ExpressionOptimizeTest, NormalizeWithInAndRegexPreservesTags) {
TEST(ExpressionOptimizeTest, NormalizeWithInPreservesCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
BSONObj obj = fromjson("{'': 'string'}");
- auto inMatchExpression = stdx::make_unique<InMatchExpression>();
+ auto inMatchExpression = stdx::make_unique<InMatchExpression>("");
inMatchExpression->setCollator(&collator);
std::vector<BSONElement> equalities{obj.firstElement()};
ASSERT_OK(inMatchExpression->setEqualities(std::move(equalities)));
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp
index 6e7098a9b75..aad03b33342 100644
--- a/src/mongo/db/matcher/expression_parser.cpp
+++ b/src/mongo/db/matcher/expression_parser.cpp
@@ -218,37 +218,25 @@ StatusWithMatchExpression parseRegexElement(StringData name, BSONElement e) {
if (e.type() != BSONType::RegEx)
return {Status(ErrorCodes::BadValue, "not a regex")};
- auto temp = stdx::make_unique<RegexMatchExpression>();
- auto s = temp->init(name, e.regex(), e.regexFlags());
- if (!s.isOK())
- return s;
- return {std::move(temp)};
+ return {stdx::make_unique<RegexMatchExpression>(name, e.regex(), e.regexFlags())};
}
StatusWithMatchExpression parseComparison(
StringData name,
- ComparisonMatchExpression* cmp,
+ std::unique_ptr<ComparisonMatchExpression> cmp,
BSONElement e,
const boost::intrusive_ptr<ExpressionContext>& expCtx,
MatchExpressionParser::AllowedFeatureSet allowedFeatures) {
- std::unique_ptr<ComparisonMatchExpression> temp(cmp);
-
// Non-equality comparison match expressions cannot have a regular expression as the argument.
// (e.g. {a: {$gt: /b/}} is illegal).
if (MatchExpression::EQ != cmp->matchType() && BSONType::RegEx == e.type()) {
- return {Status(ErrorCodes::BadValue,
- str::stream() << "Can't have RegEx as arg to predicate over field '" << name
- << "'.")};
- }
-
- auto s = temp->init(name, e);
- if (!s.isOK()) {
- return s;
+ return {ErrorCodes::BadValue,
+ str::stream() << "Can't have RegEx as arg to predicate over field '" << name
+ << "'."};
}
- temp->setCollator(expCtx->getCollator());
-
- return {std::move(temp)};
+ cmp->setCollator(expCtx->getCollator());
+ return {std::move(cmp)};
}
/**
@@ -391,8 +379,12 @@ StatusWithMatchExpression parse(const BSONObj& obj,
continue;
}
- auto eq = parseComparison(
- e.fieldNameStringData(), new EqualityMatchExpression(), e, expCtx, allowedFeatures);
+ auto eq =
+ parseComparison(e.fieldNameStringData(),
+ stdx::make_unique<EqualityMatchExpression>(e.fieldNameStringData(), e),
+ e,
+ expCtx,
+ allowedFeatures);
if (!eq.isOK())
return eq;
@@ -467,11 +459,8 @@ StatusWithMatchExpression parseDBRef(StringData name,
const ExtensionsCallback* extensionsCallback,
MatchExpressionParser::AllowedFeatureSet allowedFeatures,
DocumentParseLevel currentLevel) {
- auto eq = stdx::make_unique<EqualityMatchExpression>();
- auto s = eq->init(elem.fieldName(), elem);
- if (!s.isOK()) {
- return s;
- }
+ auto eq = stdx::make_unique<EqualityMatchExpression>(elem.fieldName(), elem);
+
// 'id' is collation-aware. 'ref' and 'db' are compared using binary comparison.
eq->setCollator("id"_sd == name ? expCtx->getCollator() : nullptr);
@@ -556,11 +545,7 @@ StatusWithMatchExpression parseMOD(StringData name, BSONElement e) {
if (i.more())
return {Status(ErrorCodes::BadValue, "malformed mod, too many elements")};
- auto temp = stdx::make_unique<ModMatchExpression>();
- auto s = temp->init(name, d.numberInt(), r.numberInt());
- if (!s.isOK())
- return s;
- return {std::move(temp)};
+ return {stdx::make_unique<ModMatchExpression>(name, d.numberInt(), r.numberInt())};
}
StatusWithMatchExpression parseRegexDocument(StringData name, const BSONObj& doc) {
@@ -595,11 +580,7 @@ StatusWithMatchExpression parseRegexDocument(StringData name, const BSONObj& doc
}
}
- auto temp = stdx::make_unique<RegexMatchExpression>();
- auto s = temp->init(name, regex, regexOptions);
- if (!s.isOK())
- return s;
- return {std::move(temp)};
+ return {stdx::make_unique<RegexMatchExpression>(name, regex, regexOptions)};
}
Status parseInExpression(InMatchExpression* inExpression,
@@ -614,13 +595,10 @@ Status parseInExpression(InMatchExpression* inExpression,
}
if (e.type() == BSONType::RegEx) {
- auto r = stdx::make_unique<RegexMatchExpression>();
- auto s = r->init("", e);
- if (!s.isOK())
- return s;
- s = inExpression->addRegex(std::move(r));
- if (!s.isOK())
- return s;
+ auto status = inExpression->addRegex(stdx::make_unique<RegexMatchExpression>(""_sd, e));
+ if (!status.isOK()) {
+ return status;
+ }
} else {
equalities.push_back(e);
}
@@ -635,19 +613,12 @@ StatusWithMatchExpression parseType(StringData name, BSONElement elt) {
return typeSet.getStatus();
}
- auto typeExpr = stdx::make_unique<T>();
-
if (typeSet.getValue().isEmpty()) {
return {Status(ErrorCodes::FailedToParse,
- str::stream() << typeExpr->name() << " must match at least one type")};
- }
-
- auto status = typeExpr->init(name, std::move(typeSet.getValue()));
- if (!status.isOK()) {
- return status;
+ str::stream() << name << " must match at least one type")};
}
- return {std::move(typeExpr)};
+ return {stdx::make_unique<T>(name, std::move(typeSet.getValue()))};
}
/**
@@ -722,41 +693,27 @@ StatusWith<std::vector<uint32_t>> parseBitPositionsArray(const BSONObj& theArray
*/
template <class T>
StatusWithMatchExpression parseBitTest(StringData name, BSONElement e) {
- auto bitTestMatchExpression = stdx::make_unique<T>();
+ std::unique_ptr<BitTestMatchExpression> bitTestMatchExpression;
if (e.type() == BSONType::Array) {
// Array of bit positions provided as value.
- auto statusWithBitPositions = parseBitPositionsArray(e.Obj());
- if (!statusWithBitPositions.isOK()) {
- return statusWithBitPositions.getStatus();
- }
-
- std::vector<uint32_t> bitPositions = statusWithBitPositions.getValue();
- auto s = bitTestMatchExpression->init(name, bitPositions);
- if (!s.isOK()) {
- return s;
+ auto bitPositions = parseBitPositionsArray(e.Obj());
+ if (!bitPositions.isOK()) {
+ return bitPositions.getStatus();
}
+ bitTestMatchExpression = stdx::make_unique<T>(name, std::move(bitPositions.getValue()));
} else if (e.isNumber()) {
// Integer bitmask provided as value.
auto bitMask = MatchExpressionParser::parseIntegerElementToNonNegativeLong(e);
if (!bitMask.isOK()) {
return bitMask.getStatus();
}
-
- auto s = bitTestMatchExpression->init(name, bitMask.getValue());
- if (!s.isOK()) {
- return s;
- }
+ bitTestMatchExpression = stdx::make_unique<T>(name, bitMask.getValue());
} else if (e.type() == BSONType::BinData) {
// Binary bitmask provided as value.
-
int eBinaryLen;
auto eBinary = e.binData(eBinaryLen);
-
- auto s = bitTestMatchExpression->init(name, eBinary, eBinaryLen);
- if (!s.isOK()) {
- return s;
- }
+ bitTestMatchExpression = stdx::make_unique<T>(name, eBinary, eBinaryLen);
} else {
return Status(
ErrorCodes::BadValue,
@@ -767,35 +724,36 @@ StatusWithMatchExpression parseBitTest(StringData name, BSONElement e) {
}
StatusWithMatchExpression parseInternalSchemaFmod(StringData name, BSONElement elem) {
- auto path(name);
+ StringData path(name);
if (elem.type() != BSONType::Array)
return {ErrorCodes::BadValue,
str::stream() << path << " must be an array, but got type " << elem.type()};
BSONObjIterator i(elem.embeddedObject());
-
- if (!i.more())
+ if (!i.more()) {
return {ErrorCodes::BadValue, str::stream() << path << " does not have enough elements"};
+ }
auto d = i.next();
- if (!d.isNumber())
+ if (!d.isNumber()) {
return {ErrorCodes::TypeMismatch,
str::stream() << path << " does not have a numeric divisor"};
+ }
- if (!i.more())
+ if (!i.more()) {
return {ErrorCodes::BadValue, str::stream() << path << " does not have enough elements"};
+ }
auto r = i.next();
- if (!d.isNumber())
+ if (!d.isNumber()) {
return {ErrorCodes::TypeMismatch,
str::stream() << path << " does not have a numeric remainder"};
+ }
- if (i.more())
+ if (i.more()) {
return {ErrorCodes::BadValue, str::stream() << path << " has too many elements"};
+ }
- auto result = stdx::make_unique<InternalSchemaFmodMatchExpression>();
- auto s = result->init(name, d.numberDecimal(), r.numberDecimal());
- if (!s.isOK())
- return s;
- return {std::move(result)};
+ return {stdx::make_unique<InternalSchemaFmodMatchExpression>(
+ name, d.numberDecimal(), r.numberDecimal())};
}
StatusWithMatchExpression parseInternalSchemaRootDocEq(
@@ -817,8 +775,8 @@ StatusWithMatchExpression parseInternalSchemaRootDocEq(
<< " must be an object, found type "
<< elem.type())};
}
- auto rootDocEq = stdx::make_unique<InternalSchemaRootDocEqMatchExpression>();
- rootDocEq->init(elem.embeddedObject());
+ auto rootDocEq =
+ stdx::make_unique<InternalSchemaRootDocEqMatchExpression>(elem.embeddedObject());
return {std::move(rootDocEq)};
}
@@ -834,13 +792,7 @@ StatusWithMatchExpression parseInternalSchemaSingleIntegerArgument(StringData na
return parsedInt.getStatus();
}
- auto matchExpression = stdx::make_unique<T>();
- auto status = matchExpression->init(name, parsedInt.getValue());
- if (!status.isOK()) {
- return status;
- }
-
- return {std::move(matchExpression)};
+ return {stdx::make_unique<T>(name, parsedInt.getValue())};
}
/**
@@ -859,12 +811,7 @@ StatusWithMatchExpression parseTopLevelInternalSchemaSingleIntegerArgument(
if (!parsedInt.isOK()) {
return parsedInt.getStatus();
}
- auto matchExpression = stdx::make_unique<T>();
- auto status = matchExpression->init(parsedInt.getValue());
- if (!status.isOK()) {
- return status;
- }
- return {std::move(matchExpression)};
+ return {stdx::make_unique<T>(parsedInt.getValue())};
}
/**
@@ -1102,17 +1049,11 @@ StatusWithMatchExpression parseInternalSchemaAllowedProperties(
return properties.getStatus();
}
- auto allowedPropertiesExpr =
- stdx::make_unique<InternalSchemaAllowedPropertiesMatchExpression>();
- auto status = allowedPropertiesExpr->init(std::move(properties.getValue()),
- namePlaceholder.getValue(),
- std::move(patternProperties.getValue()),
- std::move(otherwise.getValue()));
- if (!status.isOK()) {
- return status;
- }
-
- return {std::move(allowedPropertiesExpr)};
+ return {stdx::make_unique<InternalSchemaAllowedPropertiesMatchExpression>(
+ std::move(properties.getValue()),
+ namePlaceholder.getValue(),
+ std::move(patternProperties.getValue()),
+ std::move(otherwise.getValue()))};
}
/**
@@ -1163,13 +1104,8 @@ StatusWithMatchExpression parseInternalSchemaMatchArrayIndex(
return expressionWithPlaceholder.getStatus();
}
- auto matchArrayIndexExpr = stdx::make_unique<InternalSchemaMatchArrayIndexMatchExpression>();
- auto initStatus = matchArrayIndexExpr->init(
- path, index.getValue(), std::move(expressionWithPlaceholder.getValue()));
- if (!initStatus.isOK()) {
- return initStatus;
- }
- return {std::move(matchArrayIndexExpr)};
+ return {stdx::make_unique<InternalSchemaMatchArrayIndexMatchExpression>(
+ path, index.getValue(), std::move(expressionWithPlaceholder.getValue()))};
}
StatusWithMatchExpression parseGeo(StringData name,
@@ -1179,16 +1115,10 @@ StatusWithMatchExpression parseGeo(StringData name,
if (PathAcceptingKeyword::WITHIN == type || PathAcceptingKeyword::GEO_INTERSECTS == type) {
auto gq = stdx::make_unique<GeoExpression>(name.toString());
auto parseStatus = gq->parseFrom(section);
-
- if (!parseStatus.isOK())
- return StatusWithMatchExpression(parseStatus);
-
- auto e = stdx::make_unique<GeoMatchExpression>();
-
- auto s = e->init(name, gq.release(), section);
- if (!s.isOK())
- return StatusWithMatchExpression(s);
- return {std::move(e)};
+ if (!parseStatus.isOK()) {
+ return parseStatus;
+ }
+ return {stdx::make_unique<GeoMatchExpression>(name, gq.release(), section)};
} else {
invariant(PathAcceptingKeyword::GEO_NEAR == type);
@@ -1198,15 +1128,11 @@ StatusWithMatchExpression parseGeo(StringData name,
}
auto nq = stdx::make_unique<GeoNearExpression>(name.toString());
- auto s = nq->parseFrom(section);
- if (!s.isOK()) {
- return StatusWithMatchExpression(s);
+ auto status = nq->parseFrom(section);
+ if (!status.isOK()) {
+ return status;
}
- auto e = stdx::make_unique<GeoNearMatchExpression>();
- s = e->init(name, nq.release(), section);
- if (!s.isOK())
- return StatusWithMatchExpression(s);
- return {std::move(e)};
+ return {stdx::make_unique<GeoNearMatchExpression>(name, nq.release(), section)};
}
}
@@ -1283,10 +1209,7 @@ StatusWithMatchExpression parseElemMatch(StringData name,
if (!s.isOK())
return s;
- auto temp = stdx::make_unique<ElemMatchValueMatchExpression>();
- s = temp->init(name);
- if (!s.isOK())
- return s;
+ auto temp = stdx::make_unique<ElemMatchValueMatchExpression>(name);
for (size_t i = 0; i < theAnd.numChildren(); i++) {
temp->add(theAnd.getChild(i));
@@ -1314,12 +1237,7 @@ StatusWithMatchExpression parseElemMatch(StringData name,
return {Status(ErrorCodes::BadValue, "$elemMatch cannot contain $where expression")};
}
- auto temp = stdx::make_unique<ElemMatchObjectMatchExpression>();
- auto status = temp->init(name, sub.release());
- if (!status.isOK())
- return status;
-
- return {std::move(temp)};
+ return {stdx::make_unique<ElemMatchObjectMatchExpression>(name, sub.release())};
}
StatusWithMatchExpression parseAll(StringData name,
@@ -1369,21 +1287,15 @@ StatusWithMatchExpression parseAll(StringData name,
auto e = i.next();
if (e.type() == BSONType::RegEx) {
- auto r = stdx::make_unique<RegexMatchExpression>();
- auto s = r->init(name, e);
- if (!s.isOK())
- return s;
- myAnd->add(r.release());
+ auto expr = stdx::make_unique<RegexMatchExpression>(name, e);
+ myAnd->add(expr.release());
} else if (e.type() == BSONType::Object &&
MatchExpressionParser::parsePathAcceptingKeyword(e.Obj().firstElement())) {
return {Status(ErrorCodes::BadValue, "no $ expressions in $all")};
} else {
- auto x = stdx::make_unique<EqualityMatchExpression>();
- auto s = x->init(name, e);
- if (!s.isOK())
- return s;
- x->setCollator(expCtx->getCollator());
- myAnd->add(x.release());
+ auto expr = stdx::make_unique<EqualityMatchExpression>(name, e);
+ expr->setCollator(expCtx->getCollator());
+ myAnd->add(expr.release());
}
}
@@ -1442,9 +1354,7 @@ StatusWithMatchExpression parseInternalSchemaFixedArityArgument(
++position;
}
- auto parsedExpression = stdx::make_unique<T>();
- parsedExpression->init(std::move(expressions));
- return {std::move(parsedExpression)};
+ return {stdx::make_unique<T>(std::move(expressions))};
}
StatusWithMatchExpression parseNot(StringData name,
@@ -1454,39 +1364,36 @@ StatusWithMatchExpression parseNot(StringData name,
MatchExpressionParser::AllowedFeatureSet allowedFeatures,
DocumentParseLevel currentLevel) {
if (elem.type() == BSONType::RegEx) {
- auto s = parseRegexElement(name, elem);
- if (!s.isOK())
- return s;
- auto n = stdx::make_unique<NotMatchExpression>();
- auto s2 = n->init(s.getValue().release());
- if (!s2.isOK())
- return StatusWithMatchExpression(s2);
- return {std::move(n)};
+ auto regex = parseRegexElement(name, elem);
+ if (!regex.isOK()) {
+ return regex;
+ }
+ return {stdx::make_unique<NotMatchExpression>(regex.getValue().release())};
}
- if (elem.type() != BSONType::Object)
- return StatusWithMatchExpression(ErrorCodes::BadValue, "$not needs a regex or a document");
+ if (elem.type() != BSONType::Object) {
+ return {ErrorCodes::BadValue, "$not needs a regex or a document"};
+ }
auto notObject = elem.Obj();
- if (notObject.isEmpty())
- return StatusWithMatchExpression(ErrorCodes::BadValue, "$not cannot be empty");
+ if (notObject.isEmpty()) {
+ return {ErrorCodes::BadValue, "$not cannot be empty"};
+ }
auto theAnd = stdx::make_unique<AndMatchExpression>();
- auto s = parseSub(
+ auto parseStatus = parseSub(
name, notObject, theAnd.get(), expCtx, extensionsCallback, allowedFeatures, currentLevel);
- if (!s.isOK())
- return StatusWithMatchExpression(s);
-
- for (size_t i = 0; i < theAnd->numChildren(); i++)
- if (theAnd->getChild(i)->matchType() == MatchExpression::REGEX)
- return StatusWithMatchExpression(ErrorCodes::BadValue, "$not cannot have a regex");
+ if (!parseStatus.isOK()) {
+ return parseStatus;
+ }
- auto theNot = stdx::make_unique<NotMatchExpression>();
- s = theNot->init(theAnd.release());
- if (!s.isOK())
- return StatusWithMatchExpression(s);
+ for (size_t i = 0; i < theAnd->numChildren(); i++) {
+ if (theAnd->getChild(i)->matchType() == MatchExpression::REGEX) {
+ return {ErrorCodes::BadValue, "$not cannot have a regex"};
+ }
+ }
- return {std::move(theNot)};
+ return {stdx::make_unique<NotMatchExpression>(theAnd.release())};
}
/**
@@ -1503,7 +1410,8 @@ StatusWithMatchExpression parseSubField(const BSONObj& context,
MatchExpressionParser::AllowedFeatureSet allowedFeatures,
DocumentParseLevel currentLevel) {
if ("$eq"_sd == e.fieldNameStringData()) {
- return parseComparison(name, new EqualityMatchExpression(), e, expCtx, allowedFeatures);
+ return parseComparison(
+ name, stdx::make_unique<EqualityMatchExpression>(name, e), e, expCtx, allowedFeatures);
}
if ("$not"_sd == e.fieldNameStringData()) {
@@ -1523,62 +1431,60 @@ StatusWithMatchExpression parseSubField(const BSONObj& context,
switch (*parseExpMatchType) {
case PathAcceptingKeyword::LESS_THAN:
- return parseComparison(name, new LTMatchExpression(), e, expCtx, allowedFeatures);
+ return parseComparison(
+ name, stdx::make_unique<LTMatchExpression>(name, e), e, expCtx, allowedFeatures);
case PathAcceptingKeyword::LESS_THAN_OR_EQUAL:
- return parseComparison(name, new LTEMatchExpression(), e, expCtx, allowedFeatures);
+ return parseComparison(
+ name, stdx::make_unique<LTEMatchExpression>(name, e), e, expCtx, allowedFeatures);
case PathAcceptingKeyword::GREATER_THAN:
- return parseComparison(name, new GTMatchExpression(), e, expCtx, allowedFeatures);
+ return parseComparison(
+ name, stdx::make_unique<GTMatchExpression>(name, e), e, expCtx, allowedFeatures);
case PathAcceptingKeyword::GREATER_THAN_OR_EQUAL:
- return parseComparison(name, new GTEMatchExpression(), e, expCtx, allowedFeatures);
+ return parseComparison(
+ name, stdx::make_unique<GTEMatchExpression>(name, e), e, expCtx, allowedFeatures);
case PathAcceptingKeyword::NOT_EQUAL: {
if (BSONType::RegEx == e.type()) {
// Just because $ne can be rewritten as the negation of an equality does not mean
// that $ne of a regex is allowed. See SERVER-1705.
return {Status(ErrorCodes::BadValue, "Can't have regex as arg to $ne.")};
}
- auto s =
- parseComparison(name, new EqualityMatchExpression(), e, expCtx, allowedFeatures);
- if (!s.isOK())
- return s;
- auto n = stdx::make_unique<NotMatchExpression>();
- auto s2 = n->init(s.getValue().release());
- if (!s2.isOK())
- return s2;
- return {std::move(n)};
+ StatusWithMatchExpression s =
+ parseComparison(name,
+ stdx::make_unique<EqualityMatchExpression>(name, e),
+ e,
+ expCtx,
+ allowedFeatures);
+ return {stdx::make_unique<NotMatchExpression>(s.getValue().release())};
}
case PathAcceptingKeyword::EQUALITY:
- return parseComparison(name, new EqualityMatchExpression(), e, expCtx, allowedFeatures);
+ return parseComparison(name,
+ stdx::make_unique<EqualityMatchExpression>(name, e),
+ e,
+ expCtx,
+ allowedFeatures);
case PathAcceptingKeyword::IN_EXPR: {
- if (e.type() != BSONType::Array)
+ if (e.type() != BSONType::Array) {
return {Status(ErrorCodes::BadValue, "$in needs an array")};
- auto temp = stdx::make_unique<InMatchExpression>();
- auto s = temp->init(name);
- if (!s.isOK())
- return s;
- s = parseInExpression(temp.get(), e.Obj(), expCtx);
- if (!s.isOK())
- return s;
+ }
+ auto temp = stdx::make_unique<InMatchExpression>(name);
+ auto parseStatus = parseInExpression(temp.get(), e.Obj(), expCtx);
+ if (!parseStatus.isOK()) {
+ return parseStatus;
+ }
return {std::move(temp)};
}
case PathAcceptingKeyword::NOT_IN: {
- if (e.type() != BSONType::Array)
+ if (e.type() != Array) {
return {Status(ErrorCodes::BadValue, "$nin needs an array")};
- auto temp = stdx::make_unique<InMatchExpression>();
- auto s = temp->init(name);
- if (!s.isOK())
- return s;
- s = parseInExpression(temp.get(), e.Obj(), expCtx);
- if (!s.isOK())
- return s;
-
- auto temp2 = stdx::make_unique<NotMatchExpression>();
- s = temp2->init(temp.release());
- if (!s.isOK())
- return s;
-
- return {std::move(temp2)};
+ }
+ auto temp = stdx::make_unique<InMatchExpression>(name);
+ auto parseStatus = parseInExpression(temp.get(), e.Obj(), expCtx);
+ if (!parseStatus.isOK()) {
+ return parseStatus;
+ }
+ return {stdx::make_unique<NotMatchExpression>(temp.release())};
}
case PathAcceptingKeyword::SIZE: {
@@ -1601,31 +1507,24 @@ StatusWithMatchExpression parseSubField(const BSONObj& context,
} else {
return {Status(ErrorCodes::BadValue, "$size needs a number")};
}
+
if (size < 0) {
return {Status(ErrorCodes::BadValue, "$size may not be negative")};
}
-
- auto temp = stdx::make_unique<SizeMatchExpression>();
- auto s = temp->init(name, size);
- if (!s.isOK())
- return s;
- return {std::move(temp)};
+ return {stdx::make_unique<SizeMatchExpression>(name, size)};
}
case PathAcceptingKeyword::EXISTS: {
- if (!e)
+ if (e.eoo()) {
return {Status(ErrorCodes::BadValue, "$exists can't be eoo")};
- auto temp = stdx::make_unique<ExistsMatchExpression>();
- auto s = temp->init(name);
- if (!s.isOK())
- return s;
- if (e.trueValue())
- return {std::move(temp)};
- auto temp2 = stdx::make_unique<NotMatchExpression>();
- s = temp2->init(temp.release());
- if (!s.isOK())
- return s;
- return {std::move(temp2)};
+ }
+
+ auto existsExpr = stdx::make_unique<ExistsMatchExpression>(name);
+ if (e.trueValue()) {
+ return {std::move(existsExpr)};
+ }
+
+ return {stdx::make_unique<NotMatchExpression>(existsExpr.release())};
}
case PathAcceptingKeyword::TYPE:
@@ -1711,12 +1610,8 @@ StatusWithMatchExpression parseSubField(const BSONObj& context,
return parsedSubObjExpr;
}
- auto expr = stdx::make_unique<InternalSchemaObjectMatchExpression>();
- auto status = expr->init(std::move(parsedSubObjExpr.getValue()), name);
- if (!status.isOK()) {
- return status;
- }
- return {std::move(expr)};
+ return {stdx::make_unique<InternalSchemaObjectMatchExpression>(
+ name, std::move(parsedSubObjExpr.getValue()))};
}
case PathAcceptingKeyword::INTERNAL_SCHEMA_UNIQUE_ITEMS: {
@@ -1725,12 +1620,7 @@ StatusWithMatchExpression parseSubField(const BSONObj& context,
str::stream() << name << " must be a boolean of value true"};
}
- auto expr = stdx::make_unique<InternalSchemaUniqueItemsMatchExpression>();
- auto status = expr->init(name);
- if (!status.isOK()) {
- return status;
- }
- return {std::move(expr)};
+ return {stdx::make_unique<InternalSchemaUniqueItemsMatchExpression>(name)};
}
case PathAcceptingKeyword::INTERNAL_SCHEMA_MIN_LENGTH: {
@@ -1808,14 +1698,8 @@ StatusWithMatchExpression parseSubField(const BSONObj& context,
if (!exprWithPlaceholder.isOK()) {
return exprWithPlaceholder.getStatus();
}
-
- auto expr = stdx::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>();
- auto status =
- expr->init(name, parsedIndex.getValue(), std::move(exprWithPlaceholder.getValue()));
- if (!status.isOK()) {
- return status;
- }
- return {std::move(expr)};
+ return {stdx::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>(
+ name, parsedIndex.getValue(), std::move(exprWithPlaceholder.getValue()))};
}
case PathAcceptingKeyword::INTERNAL_SCHEMA_TYPE: {
@@ -1823,12 +1707,7 @@ StatusWithMatchExpression parseSubField(const BSONObj& context,
}
case PathAcceptingKeyword::INTERNAL_SCHEMA_EQ: {
- auto eqExpr = stdx::make_unique<InternalSchemaEqMatchExpression>();
- auto status = eqExpr->init(name, e);
- if (!status.isOK()) {
- return status;
- }
- return {std::move(eqExpr)};
+ return {stdx::make_unique<InternalSchemaEqMatchExpression>(name, e)};
}
}
diff --git a/src/mongo/db/matcher/expression_parser_tree.cpp b/src/mongo/db/matcher/expression_parser_tree.cpp
index 04680e16532..d8632e64fad 100644
--- a/src/mongo/db/matcher/expression_parser_tree.cpp
+++ b/src/mongo/db/matcher/expression_parser_tree.cpp
@@ -73,19 +73,16 @@ StatusWithMatchExpression MatchExpressionParser::_parseNot(
StatusWithMatchExpression s = _parseRegexElement(name, e);
if (!s.isOK())
return s;
- std::unique_ptr<NotMatchExpression> n = stdx::make_unique<NotMatchExpression>();
- Status s2 = n->init(s.getValue().release());
- if (!s2.isOK())
- return StatusWithMatchExpression(s2);
+ std::unique_ptr<NotMatchExpression> n =
+ stdx::make_unique<NotMatchExpression>(s.getValue().release());
return {std::move(n)};
}
- if (e.type() != Object)
- return StatusWithMatchExpression(ErrorCodes::BadValue, "$not needs a regex or a document");
+ uassert(ErrorCodes::BadValue, "$not needs a regex or a document", e.type() == Object);
BSONObj notObject = e.Obj();
- if (notObject.isEmpty())
- return StatusWithMatchExpression(ErrorCodes::BadValue, "$not cannot be empty");
+
+ uassert(ErrorCodes::BadValue, "$not cannot be empty", !notObject.isEmpty());
std::unique_ptr<AndMatchExpression> theAnd = stdx::make_unique<AndMatchExpression>();
Status s = _parseSub(name, notObject, theAnd.get(), expCtx, allowedFeatures, currentLevel);
@@ -98,10 +95,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseNot(
if (theAnd->getChild(i)->matchType() == MatchExpression::REGEX)
return StatusWithMatchExpression(ErrorCodes::BadValue, "$not cannot have a regex");
- std::unique_ptr<NotMatchExpression> theNot = stdx::make_unique<NotMatchExpression>();
- s = theNot->init(theAnd.release());
- if (!s.isOK())
- return StatusWithMatchExpression(s);
+ std::unique_ptr<NotMatchExpression> theNot =
+ stdx::make_unique<NotMatchExpression>(theAnd.release());
return {std::move(theNot)};
}
diff --git a/src/mongo/db/matcher/expression_path.h b/src/mongo/db/matcher/expression_path.h
index 4fb98d84d62..b0a1ee5354c 100644
--- a/src/mongo/db/matcher/expression_path.h
+++ b/src/mongo/db/matcher/expression_path.h
@@ -41,7 +41,10 @@ namespace mongo {
*/
class PathMatchExpression : public MatchExpression {
public:
- PathMatchExpression(MatchType matchType) : MatchExpression(matchType) {}
+ explicit PathMatchExpression(MatchType matchType, StringData path)
+ : MatchExpression(matchType), _path(path) {
+ _elementPath.init(_path);
+ }
virtual ~PathMatchExpression() {}
@@ -74,15 +77,13 @@ public:
return _path;
}
- Status setPath(StringData path) {
+ void setPath(StringData path) {
_path = path;
- auto status = _elementPath.init(_path);
- if (!status.isOK()) {
- return status;
- }
+ _elementPath.init(_path);
+ }
+ void setTraverseLeafArray() {
_elementPath.setTraverseLeafArray(shouldExpandLeafArray());
- return Status::OK();
}
/**
@@ -98,7 +99,7 @@ public:
for (auto rename : renameList) {
if (rename.first == _path) {
_rewrittenPath = rename.second;
- invariantOK(setPath(_rewrittenPath));
+ setPath(_rewrittenPath);
++renamesFound;
}
@@ -112,7 +113,7 @@ public:
// Replace the chopped off components with the component names resulting from the
// rename.
_rewrittenPath = str::stream() << rename.second << "." << pathTail.toString();
- invariantOK(setPath(_rewrittenPath));
+ setPath(_rewrittenPath);
++renamesFound;
}
diff --git a/src/mongo/db/matcher/expression_test.cpp b/src/mongo/db/matcher/expression_test.cpp
index 9b65644042d..a6d8bbec44d 100644
--- a/src/mongo/db/matcher/expression_test.cpp
+++ b/src/mongo/db/matcher/expression_test.cpp
@@ -42,8 +42,7 @@ namespace mongo {
TEST(LeafMatchExpressionTest, Equal1) {
BSONObj temp = BSON("x" << 5);
- EqualityMatchExpression e;
- e.init("x", temp["x"]).transitional_ignore();
+ EqualityMatchExpression e("x", temp["x"]);
ASSERT_TRUE(e.matchesBSON(fromjson("{ x : 5 }")));
ASSERT_TRUE(e.matchesBSON(fromjson("{ x : [5] }")));
@@ -61,8 +60,7 @@ TEST(LeafMatchExpressionTest, Comp1) {
BSONObj temp = BSON("x" << 5);
{
- LTEMatchExpression e;
- e.init("x", temp["x"]).transitional_ignore();
+ LTEMatchExpression e("x", temp["x"]);
ASSERT_TRUE(e.matchesBSON(fromjson("{ x : 5 }")));
ASSERT_TRUE(e.matchesBSON(fromjson("{ x : 4 }")));
ASSERT_FALSE(e.matchesBSON(fromjson("{ x : 6 }")));
@@ -70,8 +68,7 @@ TEST(LeafMatchExpressionTest, Comp1) {
}
{
- LTMatchExpression e;
- e.init("x", temp["x"]).transitional_ignore();
+ LTMatchExpression e("x", temp["x"]);
ASSERT_FALSE(e.matchesBSON(fromjson("{ x : 5 }")));
ASSERT_TRUE(e.matchesBSON(fromjson("{ x : 4 }")));
ASSERT_FALSE(e.matchesBSON(fromjson("{ x : 6 }")));
@@ -79,8 +76,7 @@ TEST(LeafMatchExpressionTest, Comp1) {
}
{
- GTEMatchExpression e;
- e.init("x", temp["x"]).transitional_ignore();
+ GTEMatchExpression e("x", temp["x"]);
ASSERT_TRUE(e.matchesBSON(fromjson("{ x : 5 }")));
ASSERT_FALSE(e.matchesBSON(fromjson("{ x : 4 }")));
ASSERT_TRUE(e.matchesBSON(fromjson("{ x : 6 }")));
@@ -88,8 +84,7 @@ TEST(LeafMatchExpressionTest, Comp1) {
}
{
- GTMatchExpression e;
- e.init("x", temp["x"]).transitional_ignore();
+ GTMatchExpression e("x", temp["x"]);
ASSERT_FALSE(e.matchesBSON(fromjson("{ x : 5 }")));
ASSERT_FALSE(e.matchesBSON(fromjson("{ x : 4 }")));
ASSERT_TRUE(e.matchesBSON(fromjson("{ x : 6 }")));
@@ -99,8 +94,7 @@ TEST(LeafMatchExpressionTest, Comp1) {
TEST(MatchesBSONElement, ScalarEquality) {
auto filterObj = fromjson("{i: 5}");
- EqualityMatchExpression filter;
- ASSERT_OK(filter.init("i", filterObj["i"]));
+ EqualityMatchExpression filter("i", filterObj["i"]);
auto aFive = fromjson("{a: 5}");
auto iFive = fromjson("{i: 5}");
@@ -140,8 +134,7 @@ TEST(MatchesBSONElement, ScalarEquality) {
TEST(MatchesBSONElement, DottedPathEquality) {
auto filterObj = fromjson("{'i.a': 5}");
- EqualityMatchExpression filter;
- ASSERT_OK(filter.init("i.a", filterObj["i.a"]));
+ EqualityMatchExpression filter("i.a", filterObj["i.a"]);
auto aFive = fromjson("{a: 5}");
auto iFive = fromjson("{i: 5}");
@@ -191,8 +184,7 @@ TEST(MatchesBSONElement, DottedPathEquality) {
TEST(MatchesBSONElement, ArrayIndexEquality) {
auto filterObj = fromjson("{'i.1': 5}");
- EqualityMatchExpression filter;
- ASSERT_OK(filter.init("i.1", filterObj["i.1"]));
+ EqualityMatchExpression filter("i.1", filterObj["i.1"]);
auto aFive = fromjson("{a: 5}");
auto iFive = fromjson("{i: 5}");
@@ -237,8 +229,7 @@ TEST(MatchesBSONElement, ArrayIndexEquality) {
TEST(MatchesBSONElement, ObjectEquality) {
auto filterObj = fromjson("{i: {a: 5}}");
- EqualityMatchExpression filter;
- ASSERT_OK(filter.init("i", filterObj["i"]));
+ EqualityMatchExpression filter("i", filterObj["i"]);
auto aFive = fromjson("{a: 5}");
auto iFive = fromjson("{i: 5}");
@@ -288,8 +279,7 @@ TEST(MatchesBSONElement, ObjectEquality) {
TEST(MatchesBSONElement, ArrayEquality) {
auto filterObj = fromjson("{i: [5]}");
- EqualityMatchExpression filter;
- ASSERT_OK(filter.init("i", filterObj["i"]));
+ EqualityMatchExpression filter("i", filterObj["i"]);
auto aFive = fromjson("{a: 5}");
auto iFive = fromjson("{i: 5}");
@@ -320,10 +310,10 @@ TEST(MatchesBSONElement, ArrayEquality) {
TEST(MatchesBSONElement, LogicalExpression) {
auto clauseObj1 = fromjson("{i: 5}");
auto clauseObj2 = fromjson("{'i.a': 6}");
- std::unique_ptr<ComparisonMatchExpression> clause1(new EqualityMatchExpression());
- ASSERT_OK(clause1->init("i", clauseObj1["i"]));
- std::unique_ptr<ComparisonMatchExpression> clause2(new EqualityMatchExpression());
- ASSERT_OK(clause2->init("i.a", clauseObj2["i.a"]));
+ std::unique_ptr<ComparisonMatchExpression> clause1(
+ new EqualityMatchExpression("i", clauseObj1["i"]));
+ std::unique_ptr<ComparisonMatchExpression> clause2(
+ new EqualityMatchExpression("i.a", clauseObj2["i.a"]));
OrMatchExpression filter;
filter.add(clause1.release());
diff --git a/src/mongo/db/matcher/expression_text.cpp b/src/mongo/db/matcher/expression_text.cpp
index 1719cda7a21..33c388bd607 100644
--- a/src/mongo/db/matcher/expression_text.cpp
+++ b/src/mongo/db/matcher/expression_text.cpp
@@ -42,9 +42,13 @@
namespace mongo {
-Status TextMatchExpression::init(OperationContext* opCtx,
- const NamespaceString& nss,
- TextParams params) {
+TextMatchExpression::TextMatchExpression(fts::FTSQueryImpl ftsQuery)
+ : TextMatchExpressionBase("_fts"), _ftsQuery(ftsQuery) {}
+
+TextMatchExpression::TextMatchExpression(OperationContext* opCtx,
+ const NamespaceString& nss,
+ TextParams params)
+ : TextMatchExpressionBase("_fts") {
_ftsQuery.setQuery(std::move(params.query));
_ftsQuery.setLanguage(std::move(params.language));
_ftsQuery.setCaseSensitive(params.caseSensitive);
@@ -56,28 +60,31 @@ Status TextMatchExpression::init(OperationContext* opCtx,
AutoGetDb autoDb(opCtx, nss.db(), MODE_IS);
Lock::CollectionLock collLock(opCtx->lockState(), nss.ns(), MODE_IS);
Database* db = autoDb.getDb();
- if (!db) {
- return {ErrorCodes::IndexNotFound,
- str::stream() << "text index required for $text query (no such collection '"
- << nss.ns()
- << "')"};
- }
+
+ uassert(ErrorCodes::IndexNotFound,
+ str::stream() << "text index required for $text query (no such collection '"
+ << nss.ns()
+ << "')",
+ db);
+
Collection* collection = db->getCollection(opCtx, nss);
- if (!collection) {
- return {ErrorCodes::IndexNotFound,
- str::stream() << "text index required for $text query (no such collection '"
- << nss.ns()
- << "')"};
- }
+
+ uassert(ErrorCodes::IndexNotFound,
+ str::stream() << "text index required for $text query (no such collection '"
+ << nss.ns()
+ << "')",
+ collection);
+
std::vector<IndexDescriptor*> idxMatches;
collection->getIndexCatalog()->findIndexByType(opCtx, IndexNames::TEXT, idxMatches);
- if (idxMatches.empty()) {
- return {ErrorCodes::IndexNotFound, "text index required for $text query"};
- }
- if (idxMatches.size() > 1) {
- return {ErrorCodes::IndexNotFound, "more than one text index found for $text query"};
- }
+
+ uassert(
+ ErrorCodes::IndexNotFound, "text index required for $text query", !idxMatches.empty());
+ uassert(ErrorCodes::IndexNotFound,
+ "more than one text index found for $text query",
+ idxMatches.size() < 2);
invariant(idxMatches.size() == 1);
+
IndexDescriptor* index = idxMatches[0];
const FTSAccessMethod* fam =
static_cast<FTSAccessMethod*>(collection->getIndexCatalog()->getIndex(index));
@@ -91,19 +98,14 @@ Status TextMatchExpression::init(OperationContext* opCtx,
}
Status parseStatus = _ftsQuery.parse(version);
- if (!parseStatus.isOK()) {
- return parseStatus;
- }
-
- return setPath("_fts");
+ uassertStatusOK(parseStatus);
}
std::unique_ptr<MatchExpression> TextMatchExpression::shallowClone() const {
- auto expr = stdx::make_unique<TextMatchExpression>();
- // We initialize _ftsQuery here directly rather than calling init(), to avoid needing to examine
+ auto expr = stdx::make_unique<TextMatchExpression>(_ftsQuery);
+ // We use the query-only constructor here directly rather than using the full constructor, to
+ // avoid needing to examine
// the index catalog.
- expr->_ftsQuery = _ftsQuery;
- invariantOK(expr->setPath("_fts"));
if (getTag()) {
expr->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/expression_text.h b/src/mongo/db/matcher/expression_text.h
index 2a3ac4a3c36..1bf453906bd 100644
--- a/src/mongo/db/matcher/expression_text.h
+++ b/src/mongo/db/matcher/expression_text.h
@@ -41,7 +41,8 @@ class OperationContext;
class TextMatchExpression : public TextMatchExpressionBase {
public:
- Status init(OperationContext* opCtx, const NamespaceString& nss, TextParams params);
+ explicit TextMatchExpression(fts::FTSQueryImpl ftsQuery);
+ TextMatchExpression(OperationContext* opCtx, const NamespaceString& nss, TextParams params);
const fts::FTSQuery& getFTSQuery() const final {
return _ftsQuery;
diff --git a/src/mongo/db/matcher/expression_text_base.cpp b/src/mongo/db/matcher/expression_text_base.cpp
index 625107d4aca..925d2bbb7a0 100644
--- a/src/mongo/db/matcher/expression_text_base.cpp
+++ b/src/mongo/db/matcher/expression_text_base.cpp
@@ -37,7 +37,8 @@ namespace mongo {
const bool TextMatchExpressionBase::kCaseSensitiveDefault = false;
const bool TextMatchExpressionBase::kDiacriticSensitiveDefault = false;
-TextMatchExpressionBase::TextMatchExpressionBase() : LeafMatchExpression(TEXT) {}
+TextMatchExpressionBase::TextMatchExpressionBase(StringData path)
+ : LeafMatchExpression(TEXT, path) {}
void TextMatchExpressionBase::debugString(StringBuilder& debug, int level) const {
const fts::FTSQuery& ftsQuery = getFTSQuery();
diff --git a/src/mongo/db/matcher/expression_text_base.h b/src/mongo/db/matcher/expression_text_base.h
index ac51e137ee1..8c34126888e 100644
--- a/src/mongo/db/matcher/expression_text_base.h
+++ b/src/mongo/db/matcher/expression_text_base.h
@@ -51,7 +51,7 @@ public:
static const bool kCaseSensitiveDefault;
static const bool kDiacriticSensitiveDefault;
- TextMatchExpressionBase();
+ explicit TextMatchExpressionBase(StringData path);
virtual ~TextMatchExpressionBase() {}
/**
diff --git a/src/mongo/db/matcher/expression_text_noop.cpp b/src/mongo/db/matcher/expression_text_noop.cpp
index 5e6ef901b5c..a42845d4e63 100644
--- a/src/mongo/db/matcher/expression_text_noop.cpp
+++ b/src/mongo/db/matcher/expression_text_noop.cpp
@@ -34,13 +34,13 @@
namespace mongo {
-Status TextNoOpMatchExpression::init(TextParams params) {
+TextNoOpMatchExpression::TextNoOpMatchExpression(TextParams params)
+ : TextMatchExpressionBase("_fts") {
_ftsQuery.setQuery(std::move(params.query));
_ftsQuery.setLanguage(std::move(params.language));
_ftsQuery.setCaseSensitive(params.caseSensitive);
_ftsQuery.setDiacriticSensitive(params.diacriticSensitive);
invariantOK(_ftsQuery.parse(fts::TEXT_INDEX_VERSION_INVALID));
- return setPath("_fts");
}
std::unique_ptr<MatchExpression> TextNoOpMatchExpression::shallowClone() const {
@@ -50,8 +50,7 @@ std::unique_ptr<MatchExpression> TextNoOpMatchExpression::shallowClone() const {
params.caseSensitive = _ftsQuery.getCaseSensitive();
params.diacriticSensitive = _ftsQuery.getDiacriticSensitive();
- auto expr = stdx::make_unique<TextNoOpMatchExpression>();
- invariantOK(expr->init(std::move(params)));
+ auto expr = stdx::make_unique<TextNoOpMatchExpression>(std::move(params));
if (getTag()) {
expr->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/expression_text_noop.h b/src/mongo/db/matcher/expression_text_noop.h
index 429fecff05d..3c2316595a9 100644
--- a/src/mongo/db/matcher/expression_text_noop.h
+++ b/src/mongo/db/matcher/expression_text_noop.h
@@ -35,7 +35,7 @@ namespace mongo {
class TextNoOpMatchExpression : public TextMatchExpressionBase {
public:
- Status init(TextParams params);
+ explicit TextNoOpMatchExpression(TextParams params);
const fts::FTSQuery& getFTSQuery() const final {
return _ftsQuery;
diff --git a/src/mongo/db/matcher/expression_tree.cpp b/src/mongo/db/matcher/expression_tree.cpp
index df8ab0b4012..5e1a9f5d83d 100644
--- a/src/mongo/db/matcher/expression_tree.cpp
+++ b/src/mongo/db/matcher/expression_tree.cpp
@@ -122,8 +122,7 @@ MatchExpression::ExpressionOptimizerFunc ListOfMatchExpression::getOptimizer() c
return std::unique_ptr<MatchExpression>(simplifiedExpression);
} else if (matchType == NOR) {
// Simplify NOR of exactly one operand to NOT of that operand.
- auto simplifiedExpression = stdx::make_unique<NotMatchExpression>();
- invariantOK(simplifiedExpression->init(children.front()));
+ auto simplifiedExpression = stdx::make_unique<NotMatchExpression>(children.front());
children.clear();
return std::move(simplifiedExpression);
}
diff --git a/src/mongo/db/matcher/expression_tree.h b/src/mongo/db/matcher/expression_tree.h
index 074ed6c728a..1368567e912 100644
--- a/src/mongo/db/matcher/expression_tree.h
+++ b/src/mongo/db/matcher/expression_tree.h
@@ -41,7 +41,7 @@ namespace mongo {
class ListOfMatchExpression : public MatchExpression {
public:
- ListOfMatchExpression(MatchType type) : MatchExpression(type) {}
+ explicit ListOfMatchExpression(MatchType type) : MatchExpression(type) {}
virtual ~ListOfMatchExpression();
/**
@@ -187,19 +187,11 @@ public:
class NotMatchExpression final : public MatchExpression {
public:
- NotMatchExpression() : MatchExpression(NOT) {}
- NotMatchExpression(MatchExpression* e) : MatchExpression(NOT), _exp(e) {}
- /**
- * @param exp - I own it, and will delete
- */
- virtual Status init(MatchExpression* exp) {
- _exp.reset(exp);
- return Status::OK();
- }
+ explicit NotMatchExpression(MatchExpression* e) : MatchExpression(NOT), _exp(e) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
- std::unique_ptr<NotMatchExpression> self = stdx::make_unique<NotMatchExpression>();
- self->init(_exp->shallowClone().release()).transitional_ignore();
+ std::unique_ptr<NotMatchExpression> self =
+ stdx::make_unique<NotMatchExpression>(_exp->shallowClone().release());
if (getTag()) {
self->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/expression_tree_test.cpp b/src/mongo/db/matcher/expression_tree_test.cpp
index 6b65006cdd1..54e85206d75 100644
--- a/src/mongo/db/matcher/expression_tree_test.cpp
+++ b/src/mongo/db/matcher/expression_tree_test.cpp
@@ -43,20 +43,16 @@ using std::unique_ptr;
TEST(NotMatchExpression, MatchesScalar) {
BSONObj baseOperand = BSON("$lt" << 5);
- unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression());
- ASSERT(lt->init("a", baseOperand["$lt"]).isOK());
- NotMatchExpression notOp;
- ASSERT(notOp.init(lt.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression("a", baseOperand["$lt"]));
+ NotMatchExpression notOp(lt.release());
ASSERT(notOp.matchesBSON(BSON("a" << 6), NULL));
ASSERT(!notOp.matchesBSON(BSON("a" << 4), NULL));
}
TEST(NotMatchExpression, MatchesArray) {
BSONObj baseOperand = BSON("$lt" << 5);
- unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression());
- ASSERT(lt->init("a", baseOperand["$lt"]).isOK());
- NotMatchExpression notOp;
- ASSERT(notOp.init(lt.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression("a", baseOperand["$lt"]));
+ NotMatchExpression notOp(lt.release());
ASSERT(notOp.matchesBSON(BSON("a" << BSON_ARRAY(6)), NULL));
ASSERT(!notOp.matchesBSON(BSON("a" << BSON_ARRAY(4)), NULL));
// All array elements must match.
@@ -65,10 +61,8 @@ TEST(NotMatchExpression, MatchesArray) {
TEST(NotMatchExpression, ElemMatchKey) {
BSONObj baseOperand = BSON("$lt" << 5);
- unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression());
- ASSERT(lt->init("a", baseOperand["$lt"]).isOK());
- NotMatchExpression notOp;
- ASSERT(notOp.init(lt.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression("a", baseOperand["$lt"]));
+ NotMatchExpression notOp(lt.release());
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!notOp.matchesBSON(BSON("a" << BSON_ARRAY(1)), &details));
@@ -83,10 +77,8 @@ TEST(NotMatchExpression, ElemMatchKey) {
TEST(NotMatchExpression, SetCollatorPropagatesToChild) {
BSONObj baseOperand = BSON("a"
<< "string");
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("a", baseOperand["a"]).isOK());
- NotMatchExpression notOp;
- ASSERT(notOp.init(eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("a", baseOperand["a"]));
+ NotMatchExpression notOp(eq.release());
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
notOp.setCollator(&collator);
ASSERT(!notOp.matchesBSON(BSON("a"
@@ -94,36 +86,6 @@ TEST(NotMatchExpression, SetCollatorPropagatesToChild) {
nullptr));
}
-/*
- TEST( NotMatchExpression, MatchesIndexKey ) {
- BSONObj baseOperand = BSON( "$lt" << 5 );
- unique_ptr<ComparisonMatchExpression> lt( new ComparisonMatchExpression() );
- ASSERT( lt->init( "a", baseOperand[ "$lt" ] ).isOK() );
- NotMatchExpression notOp;
- ASSERT( notOp.init( lt.release() ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- BSONObj indexKey = BSON( "" << "7" );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- notOp.matchesIndexKey( indexKey, indexSpec ) );
- }
-*/
-
-/**
-TEST( AndOp, MatchesElementSingleClause ) {
- BSONObj baseOperand = BSON( "$lt" << 5 );
- BSONObj match = BSON( "a" << 4 );
- BSONObj notMatch = BSON( "a" << 5 );
- unique_ptr<ComparisonMatchExpression> lt( new ComparisonMatchExpression() );
- ASSERT( lt->init( "", baseOperand[ "$lt" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( lt.release() );
- AndOp andOp;
- ASSERT( andOp.init( &subMatchExpressions ).isOK() );
- ASSERT( andOp.matchesSingleElement( match[ "a" ] ) );
- ASSERT( !andOp.matchesSingleElement( notMatch[ "a" ] ) );
-}
-*/
-
TEST(AndOp, NoClauses) {
AndMatchExpression andMatchExpression;
ASSERT(andMatchExpression.matchesBSON(BSONObj(), NULL));
@@ -143,12 +105,9 @@ TEST(AndOp, MatchesElementThreeClauses) {
BSONObj notMatch3 = BSON("a"
<< "r");
- unique_ptr<ComparisonMatchExpression> sub1(new LTMatchExpression());
- ASSERT(sub1->init("a", baseOperand1["$lt"]).isOK());
- unique_ptr<ComparisonMatchExpression> sub2(new GTMatchExpression());
- ASSERT(sub2->init("a", baseOperand2["$gt"]).isOK());
- unique_ptr<RegexMatchExpression> sub3(new RegexMatchExpression());
- ASSERT(sub3->init("a", "1", "").isOK());
+ unique_ptr<ComparisonMatchExpression> sub1(new LTMatchExpression("a", baseOperand1["$lt"]));
+ unique_ptr<ComparisonMatchExpression> sub2(new GTMatchExpression("a", baseOperand2["$gt"]));
+ unique_ptr<RegexMatchExpression> sub3(new RegexMatchExpression("a", "1", ""));
AndMatchExpression andOp;
andOp.add(sub1.release());
@@ -163,10 +122,8 @@ TEST(AndOp, MatchesElementThreeClauses) {
TEST(AndOp, MatchesSingleClause) {
BSONObj baseOperand = BSON("$ne" << 5);
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("a", baseOperand["$ne"]).isOK());
- unique_ptr<NotMatchExpression> ne(new NotMatchExpression());
- ASSERT(ne->init(eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("a", baseOperand["$ne"]));
+ unique_ptr<NotMatchExpression> ne(new NotMatchExpression(eq.release()));
AndMatchExpression andOp;
andOp.add(ne.release());
@@ -182,14 +139,9 @@ TEST(AndOp, MatchesThreeClauses) {
BSONObj baseOperand2 = BSON("$lt" << 10);
BSONObj baseOperand3 = BSON("$lt" << 100);
- unique_ptr<ComparisonMatchExpression> sub1(new GTMatchExpression());
- ASSERT(sub1->init("a", baseOperand1["$gt"]).isOK());
-
- unique_ptr<ComparisonMatchExpression> sub2(new LTMatchExpression());
- ASSERT(sub2->init("a", baseOperand2["$lt"]).isOK());
-
- unique_ptr<ComparisonMatchExpression> sub3(new LTMatchExpression());
- ASSERT(sub3->init("b", baseOperand3["$lt"]).isOK());
+ unique_ptr<ComparisonMatchExpression> sub1(new GTMatchExpression("a", baseOperand1["$gt"]));
+ unique_ptr<ComparisonMatchExpression> sub2(new LTMatchExpression("a", baseOperand2["$lt"]));
+ unique_ptr<ComparisonMatchExpression> sub3(new LTMatchExpression("b", baseOperand3["$lt"]));
AndMatchExpression andOp;
andOp.add(sub1.release());
@@ -207,11 +159,8 @@ TEST(AndOp, ElemMatchKey) {
BSONObj baseOperand1 = BSON("a" << 1);
BSONObj baseOperand2 = BSON("b" << 2);
- unique_ptr<ComparisonMatchExpression> sub1(new EqualityMatchExpression());
- ASSERT(sub1->init("a", baseOperand1["a"]).isOK());
-
- unique_ptr<ComparisonMatchExpression> sub2(new EqualityMatchExpression());
- ASSERT(sub2->init("b", baseOperand2["b"]).isOK());
+ unique_ptr<ComparisonMatchExpression> sub1(new EqualityMatchExpression("a", baseOperand1["a"]));
+ unique_ptr<ComparisonMatchExpression> sub2(new EqualityMatchExpression("b", baseOperand2["b"]));
AndMatchExpression andOp;
andOp.add(sub1.release());
@@ -229,108 +178,15 @@ TEST(AndOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
-/**
-TEST( AndOp, MatchesIndexKeyWithoutUnknown ) {
- BSONObj baseOperand1 = BSON( "$gt" << 1 );
- BSONObj baseOperand2 = BSON( "$lt" << 5 );
- unique_ptr<ComparisonMatchExpression> sub1( new ComparisonMatchExpression() );
- ASSERT( sub1->init( "a", baseOperand1[ "$gt" ] ).isOK() );
- unique_ptr<ComparisonMatchExpression> sub2( new ComparisonMatchExpression() );
- ASSERT( sub2->init( "a", baseOperand2[ "$lt" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( sub1.release() );
- subMatchExpressions.mutableVector().push_back( sub2.release() );
- AndOp andOp;
- ASSERT( andOp.init( &subMatchExpressions ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- andOp.matchesIndexKey( BSON( "" << 3 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- andOp.matchesIndexKey( BSON( "" << 0 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- andOp.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
-}
-
-TEST( AndOp, MatchesIndexKeyWithUnknown ) {
- BSONObj baseOperand1 = BSON( "$gt" << 1 );
- BSONObj baseOperand2 = BSON( "$lt" << 5 );
- // This part will return PartialMatchResult_Unknown.
- BSONObj baseOperand3 = BSON( "$ne" << 5 );
- unique_ptr<ComparisonMatchExpression> sub1( new ComparisonMatchExpression() );
- ASSERT( sub1->init( "a", baseOperand1[ "$gt" ] ).isOK() );
- unique_ptr<ComparisonMatchExpression> sub2( new ComparisonMatchExpression() );
- ASSERT( sub2->init( "a", baseOperand2[ "$lt" ] ).isOK() );
- unique_ptr<NeOp> sub3( new NeOp() );
- ASSERT( sub3->init( "a", baseOperand3[ "$ne" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( sub1.release() );
- subMatchExpressions.mutableVector().push_back( sub2.release() );
- subMatchExpressions.mutableVector().push_back( sub3.release() );
- AndOp andOp;
- ASSERT( andOp.init( &subMatchExpressions ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- andOp.matchesIndexKey( BSON( "" << 3 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- andOp.matchesIndexKey( BSON( "" << 0 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- andOp.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
-}
-*/
-
-/**
-TEST( OrOp, MatchesElementSingleClause ) {
- BSONObj baseOperand = BSON( "$lt" << 5 );
- BSONObj match = BSON( "a" << 4 );
- BSONObj notMatch = BSON( "a" << 5 );
- unique_ptr<ComparisonMatchExpression> lt( new ComparisonMatchExpression() );
- ASSERT( lt->init( "a", baseOperand[ "$lt" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( lt.release() );
- OrOp orOp;
- ASSERT( orOp.init( &subMatchExpressions ).isOK() );
- ASSERT( orOp.matchesSingleElement( match[ "a" ] ) );
- ASSERT( !orOp.matchesSingleElement( notMatch[ "a" ] ) );
-}
-*/
-
TEST(OrOp, NoClauses) {
OrMatchExpression orOp;
ASSERT(!orOp.matchesBSON(BSONObj(), NULL));
}
-/*
-TEST( OrOp, MatchesElementThreeClauses ) {
- BSONObj baseOperand1 = BSON( "$lt" << 0 );
- BSONObj baseOperand2 = BSON( "$gt" << 10 );
- BSONObj baseOperand3 = BSON( "a" << 5 );
- BSONObj match1 = BSON( "a" << -1 );
- BSONObj match2 = BSON( "a" << 11 );
- BSONObj match3 = BSON( "a" << 5 );
- BSONObj notMatch = BSON( "a" << "6" );
- unique_ptr<ComparisonMatchExpression> sub1( new ComparisonMatchExpression() );
- ASSERT( sub1->init( "a", baseOperand1[ "$lt" ] ).isOK() );
- unique_ptr<ComparisonMatchExpression> sub2( new ComparisonMatchExpression() );
- ASSERT( sub2->init( "a", baseOperand2[ "$gt" ] ).isOK() );
- unique_ptr<ComparisonMatchExpression> sub3( new ComparisonMatchExpression() );
- ASSERT( sub3->init( "a", baseOperand3[ "a" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( sub1.release() );
- subMatchExpressions.mutableVector().push_back( sub2.release() );
- subMatchExpressions.mutableVector().push_back( sub3.release() );
- OrOp orOp;
- ASSERT( orOp.init( &subMatchExpressions ).isOK() );
- ASSERT( orOp.matchesSingleElement( match1[ "a" ] ) );
- ASSERT( orOp.matchesSingleElement( match2[ "a" ] ) );
- ASSERT( orOp.matchesSingleElement( match3[ "a" ] ) );
- ASSERT( !orOp.matchesSingleElement( notMatch[ "a" ] ) );
-}
-*/
+
TEST(OrOp, MatchesSingleClause) {
BSONObj baseOperand = BSON("$ne" << 5);
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("a", baseOperand["$ne"]).isOK());
- unique_ptr<NotMatchExpression> ne(new NotMatchExpression());
- ASSERT(ne->init(eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("a", baseOperand["$ne"]));
+ unique_ptr<NotMatchExpression> ne(new NotMatchExpression(eq.release()));
OrMatchExpression orOp;
orOp.add(ne.release());
@@ -345,12 +201,9 @@ TEST(OrOp, MatchesThreeClauses) {
BSONObj baseOperand1 = BSON("$gt" << 10);
BSONObj baseOperand2 = BSON("$lt" << 0);
BSONObj baseOperand3 = BSON("b" << 100);
- unique_ptr<ComparisonMatchExpression> sub1(new GTMatchExpression());
- ASSERT(sub1->init("a", baseOperand1["$gt"]).isOK());
- unique_ptr<ComparisonMatchExpression> sub2(new LTMatchExpression());
- ASSERT(sub2->init("a", baseOperand2["$lt"]).isOK());
- unique_ptr<ComparisonMatchExpression> sub3(new EqualityMatchExpression());
- ASSERT(sub3->init("b", baseOperand3["b"]).isOK());
+ unique_ptr<ComparisonMatchExpression> sub1(new GTMatchExpression("a", baseOperand1["$gt"]));
+ unique_ptr<ComparisonMatchExpression> sub2(new LTMatchExpression("a", baseOperand2["$lt"]));
+ unique_ptr<ComparisonMatchExpression> sub3(new EqualityMatchExpression("b", baseOperand3["b"]));
OrMatchExpression orOp;
orOp.add(sub1.release());
@@ -369,10 +222,8 @@ TEST(OrOp, MatchesThreeClauses) {
TEST(OrOp, ElemMatchKey) {
BSONObj baseOperand1 = BSON("a" << 1);
BSONObj baseOperand2 = BSON("b" << 2);
- unique_ptr<ComparisonMatchExpression> sub1(new EqualityMatchExpression());
- ASSERT(sub1->init("a", baseOperand1["a"]).isOK());
- unique_ptr<ComparisonMatchExpression> sub2(new EqualityMatchExpression());
- ASSERT(sub2->init("b", baseOperand2["b"]).isOK());
+ unique_ptr<ComparisonMatchExpression> sub1(new EqualityMatchExpression("a", baseOperand1["a"]));
+ unique_ptr<ComparisonMatchExpression> sub2(new EqualityMatchExpression("b", baseOperand2["b"]));
OrMatchExpression orOp;
orOp.add(sub1.release());
@@ -389,109 +240,15 @@ TEST(OrOp, ElemMatchKey) {
ASSERT(!details.hasElemMatchKey());
}
-/**
-TEST( OrOp, MatchesIndexKeyWithoutUnknown ) {
- BSONObj baseOperand1 = BSON( "$gt" << 5 );
- BSONObj baseOperand2 = BSON( "$lt" << 1 );
- unique_ptr<ComparisonMatchExpression> sub1( new ComparisonMatchExpression() );
- ASSERT( sub1->init( "a", baseOperand1[ "$gt" ] ).isOK() );
- unique_ptr<ComparisonMatchExpression> sub2( new ComparisonMatchExpression() );
- ASSERT( sub2->init( "a", baseOperand2[ "$lt" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( sub1.release() );
- subMatchExpressions.mutableVector().push_back( sub2.release() );
- OrOp orOp;
- ASSERT( orOp.init( &subMatchExpressions ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_False ==
- orOp.matchesIndexKey( BSON( "" << 3 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- orOp.matchesIndexKey( BSON( "" << 0 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- orOp.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
-}
-
-TEST( OrOp, MatchesIndexKeyWithUnknown ) {
- BSONObj baseOperand1 = BSON( "$gt" << 5 );
- BSONObj baseOperand2 = BSON( "$lt" << 1 );
- // This part will return PartialMatchResult_Unknown.
- BSONObj baseOperand3 = BSON( "$ne" << 5 );
- unique_ptr<ComparisonMatchExpression> sub1( new ComparisonMatchExpression() );
- ASSERT( sub1->init( "a", baseOperand1[ "$gt" ] ).isOK() );
- unique_ptr<ComparisonMatchExpression> sub2( new ComparisonMatchExpression() );
- ASSERT( sub2->init( "a", baseOperand2[ "$lt" ] ).isOK() );
- unique_ptr<NeOp> sub3( new NeOp() );
- ASSERT( sub3->init( "a", baseOperand3[ "$ne" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( sub1.release() );
- subMatchExpressions.mutableVector().push_back( sub2.release() );
- subMatchExpressions.mutableVector().push_back( sub3.release() );
- OrOp orOp;
- ASSERT( orOp.init( &subMatchExpressions ).isOK() );
- IndexSpec indexSpec( BSON( "a" << 1 ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_Unknown ==
- orOp.matchesIndexKey( BSON( "" << 3 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- orOp.matchesIndexKey( BSON( "" << 0 ), indexSpec ) );
- ASSERT( MatchMatchExpression::PartialMatchResult_True ==
- orOp.matchesIndexKey( BSON( "" << 6 ), indexSpec ) );
-}
-*/
-
-/**
-TEST( NorOp, MatchesElementSingleClause ) {
- BSONObj baseOperand = BSON( "$lt" << 5 );
- BSONObj match = BSON( "a" << 5 );
- BSONObj notMatch = BSON( "a" << 4 );
- unique_ptr<ComparisonMatchExpression> lt( new ComparisonMatchExpression() );
- ASSERT( lt->init( "a", baseOperand[ "$lt" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( lt.release() );
- NorOp norOp;
- ASSERT( norOp.init( &subMatchExpressions ).isOK() );
- ASSERT( norOp.matchesSingleElement( match[ "a" ] ) );
- ASSERT( !norOp.matchesSingleElement( notMatch[ "a" ] ) );
-}
-*/
-
TEST(NorOp, NoClauses) {
NorMatchExpression norOp;
ASSERT(norOp.matchesBSON(BSONObj(), NULL));
}
-/*
-TEST( NorOp, MatchesElementThreeClauses ) {
- BSONObj baseOperand1 = BSON( "$lt" << 0 );
- BSONObj baseOperand2 = BSON( "$gt" << 10 );
- BSONObj baseOperand3 = BSON( "a" << 5 );
- BSONObj notMatch1 = BSON( "a" << -1 );
- BSONObj notMatch2 = BSON( "a" << 11 );
- BSONObj notMatch3 = BSON( "a" << 5 );
- BSONObj match = BSON( "a" << "6" );
- unique_ptr<ComparisonMatchExpression> sub1( new ComparisonMatchExpression() );
- ASSERT( sub1->init( "a", baseOperand1[ "$lt" ] ).isOK() );
- unique_ptr<ComparisonMatchExpression> sub2( new ComparisonMatchExpression() );
- ASSERT( sub2->init( "a", baseOperand2[ "$gt" ] ).isOK() );
- unique_ptr<ComparisonMatchExpression> sub3( new ComparisonMatchExpression() );
- ASSERT( sub3->init( "a", baseOperand3[ "a" ] ).isOK() );
- std::vector<std::unique_ptr<<MatchMatchExpression>> subMatchExpressions;
- subMatchExpressions.mutableVector().push_back( sub1.release() );
- subMatchExpressions.mutableVector().push_back( sub2.release() );
- subMatchExpressions.mutableVector().push_back( sub3.release() );
- NorOp norOp;
- ASSERT( norOp.init( &subMatchExpressions ).isOK() );
- ASSERT( !norOp.matchesSingleElement( notMatch1[ "a" ] ) );
- ASSERT( !norOp.matchesSingleElement( notMatch2[ "a" ] ) );
- ASSERT( !norOp.matchesSingleElement( notMatch3[ "a" ] ) );
- ASSERT( norOp.matchesSingleElement( match[ "a" ] ) );
-}
-*/
TEST(NorOp, MatchesSingleClause) {
BSONObj baseOperand = BSON("$ne" << 5);
- unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression());
- ASSERT(eq->init("a", baseOperand["$ne"]).isOK());
- unique_ptr<NotMatchExpression> ne(new NotMatchExpression());
- ASSERT(ne->init(eq.release()).isOK());
+ unique_ptr<ComparisonMatchExpression> eq(new EqualityMatchExpression("a", baseOperand["$ne"]));
+ unique_ptr<NotMatchExpression> ne(new NotMatchExpression(eq.release()));
NorMatchExpression norOp;
norOp.add(ne.release());
@@ -507,12 +264,9 @@ TEST(NorOp, MatchesThreeClauses) {
BSONObj baseOperand2 = BSON("$lt" << 0);
BSONObj baseOperand3 = BSON("b" << 100);
- unique_ptr<ComparisonMatchExpression> sub1(new GTMatchExpression());
- ASSERT(sub1->init("a", baseOperand1["$gt"]).isOK());
- unique_ptr<ComparisonMatchExpression> sub2(new LTMatchExpression());
- ASSERT(sub2->init("a", baseOperand2["$lt"]).isOK());
- unique_ptr<ComparisonMatchExpression> sub3(new EqualityMatchExpression());
- ASSERT(sub3->init("b", baseOperand3["b"]).isOK());
+ unique_ptr<ComparisonMatchExpression> sub1(new GTMatchExpression("a", baseOperand1["$gt"]));
+ unique_ptr<ComparisonMatchExpression> sub2(new LTMatchExpression("a", baseOperand2["$lt"]));
+ unique_ptr<ComparisonMatchExpression> sub3(new EqualityMatchExpression("b", baseOperand3["b"]));
NorMatchExpression norOp;
norOp.add(sub1.release());
@@ -531,10 +285,8 @@ TEST(NorOp, MatchesThreeClauses) {
TEST(NorOp, ElemMatchKey) {
BSONObj baseOperand1 = BSON("a" << 1);
BSONObj baseOperand2 = BSON("b" << 2);
- unique_ptr<ComparisonMatchExpression> sub1(new EqualityMatchExpression());
- ASSERT(sub1->init("a", baseOperand1["a"]).isOK());
- unique_ptr<ComparisonMatchExpression> sub2(new EqualityMatchExpression());
- ASSERT(sub2->init("b", baseOperand2["b"]).isOK());
+ unique_ptr<ComparisonMatchExpression> sub1(new EqualityMatchExpression("a", baseOperand1["a"]));
+ unique_ptr<ComparisonMatchExpression> sub2(new EqualityMatchExpression("b", baseOperand2["b"]));
NorMatchExpression norOp;
norOp.add(sub1.release());
@@ -555,10 +307,8 @@ TEST(NorOp, ElemMatchKey) {
TEST(NorOp, Equivalent) {
BSONObj baseOperand1 = BSON("a" << 1);
BSONObj baseOperand2 = BSON("b" << 2);
- EqualityMatchExpression sub1;
- ASSERT(sub1.init("a", baseOperand1["a"]).isOK());
- EqualityMatchExpression sub2;
- ASSERT(sub2.init("b", baseOperand2["b"]).isOK());
+ EqualityMatchExpression sub1("a", baseOperand1["a"]);
+ EqualityMatchExpression sub2("b", baseOperand2["b"]);
NorMatchExpression e1;
e1.add(sub1.shallowClone().release());
diff --git a/src/mongo/db/matcher/expression_type.h b/src/mongo/db/matcher/expression_type.h
index c9ac6a2129d..9ccdbe62b63 100644
--- a/src/mongo/db/matcher/expression_type.h
+++ b/src/mongo/db/matcher/expression_type.h
@@ -36,7 +36,8 @@ namespace mongo {
template <class T>
class TypeMatchExpressionBase : public LeafMatchExpression {
public:
- explicit TypeMatchExpressionBase(MatchType matchType) : LeafMatchExpression(matchType) {}
+ explicit TypeMatchExpressionBase(MatchType matchType, StringData path, MatcherTypeSet typeSet)
+ : LeafMatchExpression(matchType, path), _typeSet(std::move(typeSet)) {}
virtual ~TypeMatchExpressionBase() = default;
@@ -45,14 +46,8 @@ public:
*/
virtual StringData name() const = 0;
- Status init(StringData path, MatcherTypeSet typeSet) {
- _typeSet = std::move(typeSet);
- return setPath(path);
- }
-
std::unique_ptr<MatchExpression> shallowClone() const final {
- auto expr = stdx::make_unique<T>();
- invariantOK(expr->init(path(), _typeSet));
+ auto expr = stdx::make_unique<T>(path(), _typeSet);
if (getTag()) {
expr->setTag(getTag()->clone());
}
@@ -117,7 +112,8 @@ class TypeMatchExpression final : public TypeMatchExpressionBase<TypeMatchExpres
public:
static constexpr StringData kName = "$type"_sd;
- TypeMatchExpression() : TypeMatchExpressionBase(MatchExpression::TYPE_OPERATOR) {}
+ TypeMatchExpression(StringData path, MatcherTypeSet typeSet)
+ : TypeMatchExpressionBase(MatchExpression::TYPE_OPERATOR, path, typeSet) {}
StringData name() const final {
return kName;
@@ -134,8 +130,10 @@ class InternalSchemaTypeExpression final
public:
static constexpr StringData kName = "$_internalSchemaType"_sd;
- InternalSchemaTypeExpression()
- : TypeMatchExpressionBase(MatchExpression::INTERNAL_SCHEMA_TYPE) {}
+ InternalSchemaTypeExpression(StringData path, MatcherTypeSet typeSet)
+ : TypeMatchExpressionBase(MatchExpression::INTERNAL_SCHEMA_TYPE, path, typeSet) {
+ setTraverseLeafArray();
+ }
StringData name() const final {
return kName;
diff --git a/src/mongo/db/matcher/expression_type_test.cpp b/src/mongo/db/matcher/expression_type_test.cpp
index 91c8c7429be..e50f30b9b45 100644
--- a/src/mongo/db/matcher/expression_type_test.cpp
+++ b/src/mongo/db/matcher/expression_type_test.cpp
@@ -37,8 +37,7 @@ TEST(ExpressionTypeTest, MatchesElementStringType) {
BSONObj match = BSON("a"
<< "abc");
BSONObj notMatch = BSON("a" << 5);
- TypeMatchExpression type;
- ASSERT(type.init("", String).isOK());
+ TypeMatchExpression type("", String);
ASSERT(type.matchesSingleElement(match["a"]));
ASSERT(!type.matchesSingleElement(notMatch["a"]));
}
@@ -47,8 +46,7 @@ TEST(ExpressionTypeTest, MatchesElementNullType) {
BSONObj match = BSON("a" << BSONNULL);
BSONObj notMatch = BSON("a"
<< "abc");
- TypeMatchExpression type;
- ASSERT(type.init("", jstNULL).isOK());
+ TypeMatchExpression type("", jstNULL);
ASSERT(type.matchesSingleElement(match["a"]));
ASSERT(!type.matchesSingleElement(notMatch["a"]));
}
@@ -63,10 +61,10 @@ TEST(ExpressionTypeTest, MatchesElementNumber) {
ASSERT_EQ(BSONType::NumberLong, match2["a"].type());
ASSERT_EQ(BSONType::NumberDouble, match3["a"].type());
- TypeMatchExpression typeExpr;
MatcherTypeSet typeSet;
typeSet.allNumbers = true;
- ASSERT_OK(typeExpr.init("a", std::move(typeSet)));
+ TypeMatchExpression typeExpr("a", std::move(typeSet));
+
ASSERT_EQ("a", typeExpr.path());
ASSERT_TRUE(typeExpr.matchesSingleElement(match1["a"]));
ASSERT_TRUE(typeExpr.matchesSingleElement(match2["a"]));
@@ -75,15 +73,13 @@ TEST(ExpressionTypeTest, MatchesElementNumber) {
}
TEST(ExpressionTypeTest, MatchesScalar) {
- TypeMatchExpression type;
- ASSERT(type.init("a", Bool).isOK());
+ TypeMatchExpression type("a", Bool);
ASSERT(type.matchesBSON(BSON("a" << true), NULL));
ASSERT(!type.matchesBSON(BSON("a" << 1), NULL));
}
TEST(ExpressionTypeTest, MatchesArray) {
- TypeMatchExpression type;
- ASSERT(type.init("a", NumberInt).isOK());
+ TypeMatchExpression type("a", NumberInt);
ASSERT(type.matchesBSON(BSON("a" << BSON_ARRAY(4)), NULL));
ASSERT(type.matchesBSON(BSON("a" << BSON_ARRAY(4 << "a")), NULL));
ASSERT(type.matchesBSON(BSON("a" << BSON_ARRAY("a" << 4)), NULL));
@@ -92,8 +88,7 @@ TEST(ExpressionTypeTest, MatchesArray) {
}
TEST(ExpressionTypeTest, TypeArrayMatchesOuterAndInnerArray) {
- TypeMatchExpression type;
- ASSERT(type.init("a", Array).isOK());
+ TypeMatchExpression type("a", Array);
ASSERT(type.matchesBSON(BSON("a" << BSONArray()), nullptr));
ASSERT(type.matchesBSON(BSON("a" << BSON_ARRAY(4 << "a")), nullptr));
ASSERT(type.matchesBSON(BSON("a" << BSON_ARRAY(BSONArray() << 2)), nullptr));
@@ -103,51 +98,44 @@ TEST(ExpressionTypeTest, TypeArrayMatchesOuterAndInnerArray) {
}
TEST(ExpressionTypeTest, MatchesObject) {
- TypeMatchExpression type;
- ASSERT(type.init("a", Object).isOK());
+ TypeMatchExpression type("a", Object);
ASSERT(type.matchesBSON(BSON("a" << BSON("b" << 1)), NULL));
ASSERT(!type.matchesBSON(BSON("a" << 1), NULL));
}
TEST(ExpressionTypeTest, MatchesDotNotationFieldObject) {
- TypeMatchExpression type;
- ASSERT(type.init("a.b", Object).isOK());
+ TypeMatchExpression type("a.b", Object);
ASSERT(type.matchesBSON(BSON("a" << BSON("b" << BSON("c" << 1))), NULL));
ASSERT(!type.matchesBSON(BSON("a" << BSON("b" << 1)), NULL));
}
TEST(ExpressionTypeTest, MatchesDotNotationArrayElementArray) {
- TypeMatchExpression type;
- ASSERT(type.init("a.0", Array).isOK());
+ TypeMatchExpression type("a.0", Array);
ASSERT(type.matchesBSON(BSON("a" << BSON_ARRAY(BSON_ARRAY(1))), NULL));
ASSERT(!type.matchesBSON(BSON("a" << BSON_ARRAY("b")), NULL));
}
TEST(ExpressionTypeTest, MatchesDotNotationArrayElementScalar) {
- TypeMatchExpression type;
- ASSERT(type.init("a.0", String).isOK());
+ TypeMatchExpression type("a.0", String);
ASSERT(type.matchesBSON(BSON("a" << BSON_ARRAY("b")), NULL));
ASSERT(!type.matchesBSON(BSON("a" << BSON_ARRAY(1)), NULL));
}
TEST(ExpressionTypeTest, MatchesDotNotationArrayElementObject) {
- TypeMatchExpression type;
- ASSERT(type.init("a.0", Object).isOK());
+ TypeMatchExpression type("a.0", Object);
ASSERT(type.matchesBSON(BSON("a" << BSON_ARRAY(BSON("b" << 1))), NULL));
ASSERT(!type.matchesBSON(BSON("a" << BSON_ARRAY(1)), NULL));
}
TEST(ExpressionTypeTest, MatchesNull) {
- TypeMatchExpression type;
- ASSERT(type.init("a", jstNULL).isOK());
+ TypeMatchExpression type("a", jstNULL);
ASSERT(type.matchesBSON(BSON("a" << BSONNULL), NULL));
ASSERT(!type.matchesBSON(BSON("a" << 4), NULL));
ASSERT(!type.matchesBSON(BSONObj(), NULL));
}
TEST(ExpressionTypeTest, ElemMatchKey) {
- TypeMatchExpression type;
- ASSERT(type.init("a.b", String).isOK());
+ TypeMatchExpression type("a.b", String);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!type.matchesBSON(BSON("a" << 1), &details));
@@ -166,12 +154,9 @@ TEST(ExpressionTypeTest, ElemMatchKey) {
}
TEST(ExpressionTypeTest, Equivalent) {
- TypeMatchExpression e1;
- TypeMatchExpression e2;
- TypeMatchExpression e3;
- ASSERT_OK(e1.init("a", BSONType::String));
- ASSERT_OK(e2.init("a", BSONType::NumberDouble));
- ASSERT_OK(e3.init("b", BSONType::String));
+ TypeMatchExpression e1("a", BSONType::String);
+ TypeMatchExpression e2("a", BSONType::NumberDouble);
+ TypeMatchExpression e3("b", BSONType::String);
ASSERT(e1.equivalent(&e1));
ASSERT(!e1.equivalent(&e2));
@@ -179,8 +164,7 @@ TEST(ExpressionTypeTest, Equivalent) {
}
TEST(ExpressionTypeTest, InternalSchemaTypeArrayOnlyMatchesArrays) {
- InternalSchemaTypeExpression expr;
- ASSERT_OK(expr.init("a", BSONType::Array));
+ InternalSchemaTypeExpression expr("a", BSONType::Array);
ASSERT_TRUE(expr.matchesBSON(fromjson("{a: []}")));
ASSERT_TRUE(expr.matchesBSON(fromjson("{a: [1]}")));
ASSERT_TRUE(expr.matchesBSON(fromjson("{a: [{b: 1}, {b: 2}]}")));
@@ -189,10 +173,9 @@ TEST(ExpressionTypeTest, InternalSchemaTypeArrayOnlyMatchesArrays) {
}
TEST(ExpressionTypeTest, InternalSchemaTypeNumberDoesNotMatchArrays) {
- InternalSchemaTypeExpression expr;
MatcherTypeSet typeSet;
typeSet.allNumbers = true;
- ASSERT_OK(expr.init("a", std::move(typeSet)));
+ InternalSchemaTypeExpression expr("a", std::move(typeSet));
ASSERT_FALSE(expr.matchesBSON(fromjson("{a: []}")));
ASSERT_FALSE(expr.matchesBSON(fromjson("{a: [1]}")));
ASSERT_FALSE(expr.matchesBSON(fromjson("{a: ['b', 2, 3]}")));
@@ -202,12 +185,11 @@ TEST(ExpressionTypeTest, InternalSchemaTypeNumberDoesNotMatchArrays) {
}
TEST(ExpressionTypeTest, TypeExprWithMultipleTypesMatchesAllSuchTypes) {
- TypeMatchExpression expr;
MatcherTypeSet typeSet;
typeSet.allNumbers = true;
typeSet.bsonTypes.insert(BSONType::String);
typeSet.bsonTypes.insert(BSONType::Object);
- ASSERT_OK(expr.init("a", std::move(typeSet)));
+ TypeMatchExpression expr("a", std::move(typeSet));
ASSERT_FALSE(expr.matchesBSON(fromjson("{a: []}")));
ASSERT_TRUE(expr.matchesBSON(fromjson("{a: 1}")));
@@ -219,12 +201,11 @@ TEST(ExpressionTypeTest, TypeExprWithMultipleTypesMatchesAllSuchTypes) {
}
TEST(ExpressionTypeTest, InternalSchemaTypeExprWithMultipleTypesMatchesAllSuchTypes) {
- InternalSchemaTypeExpression expr;
MatcherTypeSet typeSet;
typeSet.allNumbers = true;
typeSet.bsonTypes.insert(BSONType::String);
typeSet.bsonTypes.insert(BSONType::Object);
- ASSERT_OK(expr.init("a", std::move(typeSet)));
+ InternalSchemaTypeExpression expr("a", std::move(typeSet));
ASSERT_FALSE(expr.matchesBSON(fromjson("{a: []}")));
ASSERT_TRUE(expr.matchesBSON(fromjson("{a: 1}")));
diff --git a/src/mongo/db/matcher/expression_where.cpp b/src/mongo/db/matcher/expression_where.cpp
index 35f53f1ac14..dea7756f923 100644
--- a/src/mongo/db/matcher/expression_where.cpp
+++ b/src/mongo/db/matcher/expression_where.cpp
@@ -50,38 +50,24 @@ using std::string;
using std::stringstream;
using stdx::make_unique;
-WhereMatchExpression::WhereMatchExpression(OperationContext* opCtx, WhereParams params)
- : WhereMatchExpressionBase(std::move(params)), _opCtx(opCtx) {
+WhereMatchExpression::WhereMatchExpression(OperationContext* opCtx,
+ WhereParams params,
+ StringData dbName)
+ : WhereMatchExpressionBase(std::move(params)), _dbName(dbName.toString()), _opCtx(opCtx) {
invariant(_opCtx != NULL);
- _func = 0;
-}
-
-Status WhereMatchExpression::init(StringData dbName) {
- if (!getGlobalScriptEngine()) {
- return Status(ErrorCodes::BadValue, "no globalScriptEngine in $where parsing");
- }
+ uassert(
+ ErrorCodes::BadValue, "no globalScriptEngine in $where parsing", getGlobalScriptEngine());
- if (dbName.size() == 0) {
- return Status(ErrorCodes::BadValue, "ns for $where cannot be empty");
- }
-
- _dbName = dbName.toString();
+ uassert(ErrorCodes::BadValue, "ns for $where cannot be empty", dbName.size() != 0);
const string userToken =
AuthorizationSession::get(Client::getCurrent())->getAuthenticatedUserNamesToken();
- try {
- _scope = getGlobalScriptEngine()->getPooledScope(_opCtx, _dbName, "where" + userToken);
- _func = _scope->createFunction(getCode().c_str());
- } catch (...) {
- return exceptionToStatus();
- }
-
- if (!_func)
- return Status(ErrorCodes::BadValue, "$where compile error");
+ _scope = getGlobalScriptEngine()->getPooledScope(_opCtx, _dbName, "where" + userToken);
+ _func = _scope->createFunction(getCode().c_str());
- return Status::OK();
+ uassert(ErrorCodes::BadValue, "$where compile error", _func);
}
bool WhereMatchExpression::matches(const MatchableDocument* doc, MatchDetails* details) const {
@@ -113,8 +99,7 @@ unique_ptr<MatchExpression> WhereMatchExpression::shallowClone() const {
params.code = getCode();
params.scope = getScope();
unique_ptr<WhereMatchExpression> e =
- make_unique<WhereMatchExpression>(_opCtx, std::move(params));
- uassertStatusOK(e->init(_dbName));
+ make_unique<WhereMatchExpression>(_opCtx, std::move(params), _dbName);
if (getTag()) {
e->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/expression_where.h b/src/mongo/db/matcher/expression_where.h
index 26b55e4f2ea..50062d6583a 100644
--- a/src/mongo/db/matcher/expression_where.h
+++ b/src/mongo/db/matcher/expression_where.h
@@ -37,9 +37,7 @@ class OperationContext;
class WhereMatchExpression final : public WhereMatchExpressionBase {
public:
- WhereMatchExpression(OperationContext* opCtx, WhereParams params);
-
- Status init(StringData dbName);
+ WhereMatchExpression(OperationContext* opCtx, WhereParams params, StringData dbName);
bool matches(const MatchableDocument* doc, MatchDetails* details = nullptr) const final;
diff --git a/src/mongo/db/matcher/expression_where_base.h b/src/mongo/db/matcher/expression_where_base.h
index 32033ea675a..12e7fd86322 100644
--- a/src/mongo/db/matcher/expression_where_base.h
+++ b/src/mongo/db/matcher/expression_where_base.h
@@ -42,7 +42,7 @@ public:
BSONObj scope; // Owned.
};
- WhereMatchExpressionBase(WhereParams params);
+ explicit WhereMatchExpressionBase(WhereParams params);
size_t numChildren() const final {
return 0;
diff --git a/src/mongo/db/matcher/expression_where_noop.h b/src/mongo/db/matcher/expression_where_noop.h
index 10235e3176f..0ee8a835c02 100644
--- a/src/mongo/db/matcher/expression_where_noop.h
+++ b/src/mongo/db/matcher/expression_where_noop.h
@@ -40,7 +40,7 @@ namespace mongo {
*/
class WhereNoOpMatchExpression final : public WhereMatchExpressionBase {
public:
- WhereNoOpMatchExpression(WhereParams params);
+ explicit WhereNoOpMatchExpression(WhereParams params);
bool matches(const MatchableDocument* doc, MatchDetails* details = nullptr) const final;
diff --git a/src/mongo/db/matcher/extensions_callback_noop.cpp b/src/mongo/db/matcher/extensions_callback_noop.cpp
index 10026370e64..9662559ed07 100644
--- a/src/mongo/db/matcher/extensions_callback_noop.cpp
+++ b/src/mongo/db/matcher/extensions_callback_noop.cpp
@@ -41,11 +41,7 @@ StatusWithMatchExpression ExtensionsCallbackNoop::parseText(BSONElement text) co
return textParams.getStatus();
}
- auto expr = stdx::make_unique<TextNoOpMatchExpression>();
- Status initStatus = expr->init(std::move(textParams.getValue()));
- if (!initStatus.isOK()) {
- return initStatus;
- }
+ auto expr = stdx::make_unique<TextNoOpMatchExpression>(std::move(textParams.getValue()));
return {std::move(expr)};
}
diff --git a/src/mongo/db/matcher/extensions_callback_real.cpp b/src/mongo/db/matcher/extensions_callback_real.cpp
index f61928b4e2c..a962efe386a 100644
--- a/src/mongo/db/matcher/extensions_callback_real.cpp
+++ b/src/mongo/db/matcher/extensions_callback_real.cpp
@@ -45,11 +45,9 @@ StatusWithMatchExpression ExtensionsCallbackReal::parseText(BSONElement text) co
return textParams.getStatus();
}
- auto exp = stdx::make_unique<TextMatchExpression>();
- Status status = exp->init(_opCtx, *_nss, std::move(textParams.getValue()));
- if (!status.isOK()) {
- return status;
- }
+ auto exp =
+ stdx::make_unique<TextMatchExpression>(_opCtx, *_nss, std::move(textParams.getValue()));
+
return {std::move(exp)};
}
@@ -59,11 +57,8 @@ StatusWithMatchExpression ExtensionsCallbackReal::parseWhere(BSONElement where)
return whereParams.getStatus();
}
- auto exp = stdx::make_unique<WhereMatchExpression>(_opCtx, std::move(whereParams.getValue()));
- Status status = exp->init(_nss->db());
- if (!status.isOK()) {
- return status;
- }
+ auto exp = stdx::make_unique<WhereMatchExpression>(
+ _opCtx, std::move(whereParams.getValue()), _nss->db());
return {std::move(exp)};
}
diff --git a/src/mongo/db/matcher/path.cpp b/src/mongo/db/matcher/path.cpp
index a55da25879d..8ecd2a99473 100644
--- a/src/mongo/db/matcher/path.cpp
+++ b/src/mongo/db/matcher/path.cpp
@@ -35,11 +35,10 @@
namespace mongo {
-Status ElementPath::init(StringData path) {
+void ElementPath::init(StringData path) {
_shouldTraverseNonleafArrays = true;
_shouldTraverseLeafArray = true;
_fieldRef.parse(path);
- return Status::OK();
}
// -----
@@ -194,10 +193,8 @@ bool BSONElementIterator::subCursorHasMore() {
}
_subCursorPath.reset(new ElementPath());
- _subCursorPath
- ->init(_arrayIterationState.restOfPath.substr(
- _arrayIterationState.nextPieceOfPath.size() + 1))
- .transitional_ignore();
+ _subCursorPath->init(_arrayIterationState.restOfPath.substr(
+ _arrayIterationState.nextPieceOfPath.size() + 1));
_subCursorPath->setTraverseLeafArray(_path->shouldTraverseLeafArray());
// If we're here, we must be able to traverse nonleaf arrays.
@@ -277,7 +274,7 @@ bool BSONElementIterator::more() {
// The current array element is a subdocument. See if the subdocument generates
// any elements matching the remaining subpath.
_subCursorPath.reset(new ElementPath());
- _subCursorPath->init(_arrayIterationState.restOfPath).transitional_ignore();
+ _subCursorPath->init(_arrayIterationState.restOfPath);
_subCursorPath->setTraverseLeafArray(_path->shouldTraverseLeafArray());
_subCursor.reset(new BSONElementIterator(_subCursorPath.get(), eltInArray.Obj()));
@@ -303,10 +300,8 @@ bool BSONElementIterator::more() {
// The current array element is itself an array. See if the nested array
// has any elements matching the remainihng.
_subCursorPath.reset(new ElementPath());
- _subCursorPath
- ->init(_arrayIterationState.restOfPath.substr(
- _arrayIterationState.nextPieceOfPath.size() + 1))
- .transitional_ignore();
+ _subCursorPath->init(_arrayIterationState.restOfPath.substr(
+ _arrayIterationState.nextPieceOfPath.size() + 1));
_subCursorPath->setTraverseLeafArray(_path->shouldTraverseLeafArray());
BSONElementIterator* real = new BSONElementIterator(
_subCursorPath.get(), _arrayIterationState._current.Obj());
diff --git a/src/mongo/db/matcher/path.h b/src/mongo/db/matcher/path.h
index cb0c5fbe40c..b769bd35c7e 100644
--- a/src/mongo/db/matcher/path.h
+++ b/src/mongo/db/matcher/path.h
@@ -47,7 +47,7 @@ public:
// TODO: replace uses of members below with regular construction.
ElementPath() {}
- Status init(StringData path);
+ void init(StringData path);
void setTraverseNonleafArrays(bool b) {
_shouldTraverseNonleafArrays = b;
diff --git a/src/mongo/db/matcher/path_test.cpp b/src/mongo/db/matcher/path_test.cpp
index 26bbed840f9..f66b4764fad 100644
--- a/src/mongo/db/matcher/path_test.cpp
+++ b/src/mongo/db/matcher/path_test.cpp
@@ -41,7 +41,7 @@ using std::string;
TEST(Path, Root1) {
ElementPath p;
- ASSERT(p.init("a").isOK());
+ p.init("a");
BSONObj doc = BSON("x" << 4 << "a" << 5);
@@ -55,7 +55,7 @@ TEST(Path, Root1) {
TEST(Path, RootArray1) {
ElementPath p;
- ASSERT(p.init("a").isOK());
+ p.init("a");
BSONObj doc = BSON("x" << 4 << "a" << BSON_ARRAY(5 << 6));
@@ -78,7 +78,7 @@ TEST(Path, RootArray1) {
TEST(Path, RootArray2) {
ElementPath p;
- ASSERT(p.init("a").isOK());
+ p.init("a");
p.setTraverseLeafArray(false);
BSONObj doc = BSON("x" << 4 << "a" << BSON_ARRAY(5 << 6));
@@ -94,7 +94,7 @@ TEST(Path, RootArray2) {
TEST(Path, Nested1) {
ElementPath p;
- ASSERT(p.init("a.b").isOK());
+ p.init("a.b");
BSONObj doc =
BSON("a" << BSON_ARRAY(BSON("b" << 5) << 3 << BSONObj() << BSON("b" << BSON_ARRAY(9 << 11))
@@ -133,7 +133,7 @@ TEST(Path, Nested1) {
TEST(Path, NestedPartialMatchScalar) {
ElementPath p;
- ASSERT(p.init("a.b").isOK());
+ p.init("a.b");
BSONObj doc = BSON("a" << 4);
@@ -152,7 +152,7 @@ TEST(Path, NestedPartialMatchScalar) {
// what we want ideally.
TEST(Path, NestedPartialMatchArray) {
ElementPath p;
- ASSERT(p.init("a.b").isOK());
+ p.init("a.b");
BSONObj doc = BSON("a" << BSON_ARRAY(4));
@@ -164,7 +164,7 @@ TEST(Path, NestedPartialMatchArray) {
// Note that this describes existing behavior and not necessarily
TEST(Path, NestedEmptyArray) {
ElementPath p;
- ASSERT(p.init("a.b").isOK());
+ p.init("a.b");
BSONObj doc = BSON("a" << BSON("b" << BSONArray()));
@@ -180,7 +180,7 @@ TEST(Path, NestedEmptyArray) {
TEST(Path, NestedNoLeaf1) {
ElementPath p;
- ASSERT(p.init("a.b").isOK());
+ p.init("a.b");
p.setTraverseLeafArray(false);
BSONObj doc =
@@ -213,7 +213,7 @@ TEST(Path, NestedNoLeaf1) {
TEST(Path, ArrayIndex1) {
ElementPath p;
- ASSERT(p.init("a.1").isOK());
+ p.init("a.1");
BSONObj doc = BSON("a" << BSON_ARRAY(5 << 7 << 3));
@@ -228,7 +228,7 @@ TEST(Path, ArrayIndex1) {
TEST(Path, ArrayIndex2) {
ElementPath p;
- ASSERT(p.init("a.1").isOK());
+ p.init("a.1");
BSONObj doc = BSON("a" << BSON_ARRAY(5 << BSON_ARRAY(2 << 4) << 3));
@@ -243,7 +243,7 @@ TEST(Path, ArrayIndex2) {
TEST(Path, ArrayIndex3) {
ElementPath p;
- ASSERT(p.init("a.1").isOK());
+ p.init("a.1");
BSONObj doc = BSON("a" << BSON_ARRAY(5 << BSON("1" << 4) << 3));
@@ -262,7 +262,7 @@ TEST(Path, ArrayIndex3) {
TEST(Path, ArrayIndexNested1) {
ElementPath p;
- ASSERT(p.init("a.1.b").isOK());
+ p.init("a.1.b");
BSONObj doc = BSON("a" << BSON_ARRAY(5 << BSON("b" << 4) << 3));
@@ -282,7 +282,7 @@ TEST(Path, ArrayIndexNested1) {
TEST(Path, ArrayIndexNested2) {
ElementPath p;
- ASSERT(p.init("a.1.b").isOK());
+ p.init("a.1.b");
BSONObj doc = BSON("a" << BSON_ARRAY(5 << BSON_ARRAY(BSON("b" << 4)) << 3));
@@ -300,7 +300,7 @@ TEST(Path, ArrayIndexNested2) {
// array containing subdocuments with nested arrays.
TEST(Path, NonMatchingLongArrayOfSubdocumentsWithNestedArrays) {
ElementPath p;
- ASSERT(p.init("a.b.x").isOK());
+ p.init("a.b.x");
// Build the document {a: [{b: []}, {b: []}, {b: []}, ...]}.
BSONObj subdoc = BSON("b" << BSONArray());
@@ -321,7 +321,7 @@ TEST(Path, NonMatchingLongArrayOfSubdocumentsWithNestedArrays) {
// outermost array that is implicitly traversed.
TEST(Path, NestedArrayImplicitTraversal) {
ElementPath p;
- ASSERT(p.init("a.b").isOK());
+ p.init("a.b");
BSONObj doc = fromjson("{a: [{b: [2, 3]}, {b: [4, 5]}]}");
BSONElementIterator cursor(&p, doc);
@@ -369,7 +369,7 @@ TEST(Path, NestedArrayImplicitTraversal) {
// current offset of the array being implicitly traversed.
TEST(Path, ArrayOffsetWithImplicitAndExplicitTraversal) {
ElementPath p;
- ASSERT(p.init("a.0.b").isOK());
+ p.init("a.0.b");
BSONObj doc = fromjson("{a: [{b: [2, 3]}, {b: [4, 5]}]}");
BSONElementIterator cursor(&p, doc);
diff --git a/src/mongo/db/matcher/rewrite_expr.cpp b/src/mongo/db/matcher/rewrite_expr.cpp
index 304a850f592..655384047bf 100644
--- a/src/mongo/db/matcher/rewrite_expr.cpp
+++ b/src/mongo/db/matcher/rewrite_expr.cpp
@@ -150,9 +150,8 @@ std::unique_ptr<MatchExpression> RewriteExpr::_rewriteInExpression(
std::vector<BSONElement> elementList;
inValues.elems(elementList);
- auto matchInExpr = stdx::make_unique<InMatchExpression>();
+ auto matchInExpr = stdx::make_unique<InMatchExpression>(fieldPath);
matchInExpr->setCollator(_collator);
- uassertStatusOK(matchInExpr->init(fieldPath));
uassertStatusOK(matchInExpr->setEqualities(elementList));
return std::move(matchInExpr);
@@ -226,42 +225,46 @@ std::unique_ptr<MatchExpression> RewriteExpr::_buildComparisonMatchExpression(
switch (comparisonOp) {
case ExpressionCompare::EQ: {
- compMatchExpr = stdx::make_unique<EqualityMatchExpression>();
+ compMatchExpr = stdx::make_unique<EqualityMatchExpression>(fieldAndValue.fieldName(),
+ fieldAndValue);
break;
}
case ExpressionCompare::NE: {
- compMatchExpr = stdx::make_unique<EqualityMatchExpression>();
- notMatchExpr = stdx::make_unique<NotMatchExpression>();
+ compMatchExpr = stdx::make_unique<EqualityMatchExpression>(fieldAndValue.fieldName(),
+ fieldAndValue);
+ notMatchExpr = stdx::make_unique<NotMatchExpression>(compMatchExpr.release());
break;
}
case ExpressionCompare::GT: {
- compMatchExpr = stdx::make_unique<GTMatchExpression>();
+ compMatchExpr =
+ stdx::make_unique<GTMatchExpression>(fieldAndValue.fieldName(), fieldAndValue);
break;
}
case ExpressionCompare::GTE: {
- compMatchExpr = stdx::make_unique<GTEMatchExpression>();
+ compMatchExpr =
+ stdx::make_unique<GTEMatchExpression>(fieldAndValue.fieldName(), fieldAndValue);
break;
}
case ExpressionCompare::LT: {
- compMatchExpr = stdx::make_unique<LTMatchExpression>();
+ compMatchExpr =
+ stdx::make_unique<LTMatchExpression>(fieldAndValue.fieldName(), fieldAndValue);
break;
}
case ExpressionCompare::LTE: {
- compMatchExpr = stdx::make_unique<LTEMatchExpression>();
+ compMatchExpr =
+ stdx::make_unique<LTEMatchExpression>(fieldAndValue.fieldName(), fieldAndValue);
break;
}
default:
MONGO_UNREACHABLE;
}
- uassertStatusOK(compMatchExpr->init(fieldAndValue.fieldName(), fieldAndValue));
- compMatchExpr->setCollator(_collator);
-
if (notMatchExpr) {
- uassertStatusOK(notMatchExpr->init(compMatchExpr.release()));
+ notMatchExpr->setCollator(_collator);
return std::move(notMatchExpr);
}
+ compMatchExpr->setCollator(_collator);
return std::move(compMatchExpr);
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.cpp
index 6384bebe775..f6c84c6006e 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.cpp
@@ -36,10 +36,18 @@ namespace mongo {
constexpr StringData InternalSchemaAllElemMatchFromIndexMatchExpression::kName;
+InternalSchemaAllElemMatchFromIndexMatchExpression::
+ InternalSchemaAllElemMatchFromIndexMatchExpression(
+ StringData path, long long index, std::unique_ptr<ExpressionWithPlaceholder> expression)
+ : ArrayMatchingMatchExpression(MatchExpression::INTERNAL_SCHEMA_ALL_ELEM_MATCH_FROM_INDEX,
+ path),
+ _index(index),
+ _expression(std::move(expression)) {}
+
std::unique_ptr<MatchExpression> InternalSchemaAllElemMatchFromIndexMatchExpression::shallowClone()
const {
- auto clone = stdx::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>();
- invariantOK(clone->init(path(), _index, _expression->shallowClone()));
+ auto clone = stdx::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>(
+ path(), _index, _expression->shallowClone());
if (getTag()) {
clone->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.h b/src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.h
index 625cf025583..ecc61250317 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.h
@@ -42,17 +42,8 @@ class InternalSchemaAllElemMatchFromIndexMatchExpression final
public:
static constexpr StringData kName = "$_internalSchemaAllElemMatchFromIndex"_sd;
- InternalSchemaAllElemMatchFromIndexMatchExpression()
- : ArrayMatchingMatchExpression(MatchExpression::INTERNAL_SCHEMA_ALL_ELEM_MATCH_FROM_INDEX) {
- }
-
- Status init(StringData path,
- long long index,
- std::unique_ptr<ExpressionWithPlaceholder> expression) {
- _index = index;
- _expression = std::move(expression);
- return setPath(path);
- }
+ InternalSchemaAllElemMatchFromIndexMatchExpression(
+ StringData path, long long index, std::unique_ptr<ExpressionWithPlaceholder> expression);
std::unique_ptr<MatchExpression> shallowClone() const final;
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.cpp
index 76244991508..5fa61fd23ea 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.cpp
@@ -33,25 +33,23 @@
namespace mongo {
constexpr StringData InternalSchemaAllowedPropertiesMatchExpression::kName;
-Status InternalSchemaAllowedPropertiesMatchExpression::init(
+InternalSchemaAllowedPropertiesMatchExpression::InternalSchemaAllowedPropertiesMatchExpression(
boost::container::flat_set<StringData> properties,
StringData namePlaceholder,
std::vector<PatternSchema> patternProperties,
- std::unique_ptr<ExpressionWithPlaceholder> otherwise) {
- _properties = std::move(properties);
- _namePlaceholder = namePlaceholder;
- _patternProperties = std::move(patternProperties);
- _otherwise = std::move(otherwise);
+ std::unique_ptr<ExpressionWithPlaceholder> otherwise)
+ : MatchExpression(MatchExpression::INTERNAL_SCHEMA_ALLOWED_PROPERTIES),
+ _properties(std::move(properties)),
+ _namePlaceholder(namePlaceholder),
+ _patternProperties(std::move(patternProperties)),
+ _otherwise(std::move(otherwise)) {
for (auto&& constraint : _patternProperties) {
const auto& errorStr = constraint.first.regex->error();
- if (!errorStr.empty()) {
- return {ErrorCodes::BadValue,
- str::stream() << "Invalid regular expression: " << errorStr};
- }
+ uassert(ErrorCodes::BadValue,
+ str::stream() << "Invalid regular expression: " << errorStr,
+ errorStr.empty());
}
-
- return Status::OK();
}
void InternalSchemaAllowedPropertiesMatchExpression::debugString(StringBuilder& debug,
@@ -165,11 +163,11 @@ std::unique_ptr<MatchExpression> InternalSchemaAllowedPropertiesMatchExpression:
constraint.second->shallowClone());
}
- auto clone = stdx::make_unique<InternalSchemaAllowedPropertiesMatchExpression>();
- invariantOK(clone->init(_properties,
- _namePlaceholder,
- std::move(clonedPatternProperties),
- _otherwise->shallowClone()));
+ auto clone = stdx::make_unique<InternalSchemaAllowedPropertiesMatchExpression>(
+ _properties,
+ _namePlaceholder,
+ std::move(clonedPatternProperties),
+ _otherwise->shallowClone());
return {std::move(clone)};
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.h b/src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.h
index b539318dfe8..89c7448ec79 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_allowed_properties.h
@@ -108,13 +108,11 @@ public:
static constexpr StringData kName = "$_internalSchemaAllowedProperties"_sd;
- explicit InternalSchemaAllowedPropertiesMatchExpression()
- : MatchExpression(MatchExpression::INTERNAL_SCHEMA_ALLOWED_PROPERTIES) {}
-
- Status init(boost::container::flat_set<StringData> properties,
- StringData namePlaceholder,
- std::vector<PatternSchema> patternProperties,
- std::unique_ptr<ExpressionWithPlaceholder> otherwise);
+ explicit InternalSchemaAllowedPropertiesMatchExpression(
+ boost::container::flat_set<StringData> properties,
+ StringData namePlaceholder,
+ std::vector<PatternSchema> patternProperties,
+ std::unique_ptr<ExpressionWithPlaceholder> otherwise);
void debugString(StringBuilder& debug, int level) const final;
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_cond.h b/src/mongo/db/matcher/schema/expression_internal_schema_cond.h
index 94da4bc3781..ab5f38b4d01 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_cond.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_cond.h
@@ -41,8 +41,9 @@ class InternalSchemaCondMatchExpression final
public:
static constexpr StringData kName = "$_internalSchemaCond"_sd;
- InternalSchemaCondMatchExpression()
- : FixedArityMatchExpression(MatchType::INTERNAL_SCHEMA_COND) {}
+ explicit InternalSchemaCondMatchExpression(
+ std::array<std::unique_ptr<MatchExpression>, 3> expressions)
+ : FixedArityMatchExpression(MatchType::INTERNAL_SCHEMA_COND, std::move(expressions)) {}
const MatchExpression* condition() const {
return expressions()[0].get();
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_cond_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_cond_test.cpp
index f1a022da7c4..79d4a7c5d6e 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_cond_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_cond_test.cpp
@@ -43,8 +43,6 @@ namespace {
std::unique_ptr<InternalSchemaCondMatchExpression> createCondMatchExpression(BSONObj condition,
BSONObj thenBranch,
BSONObj elseBranch) {
- auto cond = stdx::make_unique<InternalSchemaCondMatchExpression>();
-
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
auto conditionExpr = MatchExpressionParser::parse(condition, expCtx);
ASSERT_OK(conditionExpr.getStatus());
@@ -52,9 +50,12 @@ std::unique_ptr<InternalSchemaCondMatchExpression> createCondMatchExpression(BSO
ASSERT_OK(thenBranchExpr.getStatus());
auto elseBranchExpr = MatchExpressionParser::parse(elseBranch, expCtx);
- cond->init({{std::move(conditionExpr.getValue()),
- std::move(thenBranchExpr.getValue()),
- std::move(elseBranchExpr.getValue())}});
+ std::array<std::unique_ptr<MatchExpression>, 3> expressions = {
+ {std::move(conditionExpr.getValue()),
+ std::move(thenBranchExpr.getValue()),
+ std::move(elseBranchExpr.getValue())}};
+
+ auto cond = stdx::make_unique<InternalSchemaCondMatchExpression>(std::move(expressions));
return cond;
}
@@ -103,9 +104,8 @@ TEST(InternalSchemaCondMatchExpressionTest, AppliesToSubobjectsViaObjectMatch) {
auto elseQuery = BSON("interests"
<< "query optimization");
- InternalSchemaObjectMatchExpression objMatch;
- ASSERT_OK(
- objMatch.init(createCondMatchExpression(conditionQuery, thenQuery, elseQuery), "job"_sd));
+ InternalSchemaObjectMatchExpression objMatch(
+ "job"_sd, createCondMatchExpression(conditionQuery, thenQuery, elseQuery));
ASSERT_TRUE(objMatch.matchesBSON(
fromjson("{name: 'anne', job: {team: 'engineering', subteam: 'query'}}")));
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_eq.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_eq.cpp
index 20de5d876e9..54ec03a0bed 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_eq.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_eq.cpp
@@ -38,10 +38,10 @@ namespace mongo {
constexpr StringData InternalSchemaEqMatchExpression::kName;
-Status InternalSchemaEqMatchExpression::init(StringData path, BSONElement rhs) {
- invariant(rhs);
- _rhsElem = rhs;
- return setPath(path);
+InternalSchemaEqMatchExpression::InternalSchemaEqMatchExpression(StringData path, BSONElement rhs)
+ : LeafMatchExpression(MatchType::INTERNAL_SCHEMA_EQ, path), _rhsElem(rhs) {
+ invariant(_rhsElem);
+ setTraverseLeafArray();
}
bool InternalSchemaEqMatchExpression::matchesSingleElement(const BSONElement& elem,
@@ -78,8 +78,7 @@ bool InternalSchemaEqMatchExpression::equivalent(const MatchExpression* other) c
}
std::unique_ptr<MatchExpression> InternalSchemaEqMatchExpression::shallowClone() const {
- auto clone = stdx::make_unique<InternalSchemaEqMatchExpression>();
- invariantOK(clone->init(path(), _rhsElem));
+ auto clone = stdx::make_unique<InternalSchemaEqMatchExpression>(path(), _rhsElem);
if (getTag()) {
clone->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_eq.h b/src/mongo/db/matcher/schema/expression_internal_schema_eq.h
index 2f73ccf534e..a8f85a2843e 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_eq.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_eq.h
@@ -45,9 +45,7 @@ class InternalSchemaEqMatchExpression final : public LeafMatchExpression {
public:
static constexpr StringData kName = "$_internalSchemaEq"_sd;
- InternalSchemaEqMatchExpression() : LeafMatchExpression(MatchType::INTERNAL_SCHEMA_EQ) {}
-
- Status init(StringData path, BSONElement rhs);
+ InternalSchemaEqMatchExpression(StringData path, BSONElement rhs);
std::unique_ptr<MatchExpression> shallowClone() const final;
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_eq_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_eq_test.cpp
index 3ccc5175092..868c8337450 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_eq_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_eq_test.cpp
@@ -40,26 +40,24 @@ namespace {
TEST(InternalSchemaEqMatchExpression, CorrectlyMatchesScalarElements) {
BSONObj numberOperand = BSON("a" << 5);
- InternalSchemaEqMatchExpression eq;
- ASSERT_OK(eq.init("a", numberOperand["a"]));
- ASSERT_TRUE(eq.matchesBSON(BSON("a" << 5.0)));
- ASSERT_FALSE(eq.matchesBSON(BSON("a" << 6)));
+ InternalSchemaEqMatchExpression eqNumberOperand("a", numberOperand["a"]);
+ ASSERT_TRUE(eqNumberOperand.matchesBSON(BSON("a" << 5.0)));
+ ASSERT_FALSE(eqNumberOperand.matchesBSON(BSON("a" << 6)));
BSONObj stringOperand = BSON("a"
<< "str");
- ASSERT_OK(eq.init("a", stringOperand["a"]));
- ASSERT_TRUE(eq.matchesBSON(BSON("a"
- << "str")));
- ASSERT_FALSE(eq.matchesBSON(BSON("a"
- << "string")));
+ InternalSchemaEqMatchExpression eqStringOperand("a", stringOperand["a"]);
+ ASSERT_TRUE(eqStringOperand.matchesBSON(BSON("a"
+ << "str")));
+ ASSERT_FALSE(eqStringOperand.matchesBSON(BSON("a"
+ << "string")));
}
TEST(InternalSchemaEqMatchExpression, CorrectlyMatchesArrayElement) {
BSONObj operand = BSON("a" << BSON_ARRAY("b" << 5));
- InternalSchemaEqMatchExpression eq;
- ASSERT_OK(eq.init("a", operand["a"]));
+ InternalSchemaEqMatchExpression eq("a", operand["a"]);
ASSERT_TRUE(eq.matchesBSON(BSON("a" << BSON_ARRAY("b" << 5))));
ASSERT_FALSE(eq.matchesBSON(BSON("a" << BSON_ARRAY(5 << "b"))));
ASSERT_FALSE(eq.matchesBSON(BSON("a" << BSON_ARRAY("b" << 5 << 5))));
@@ -69,8 +67,7 @@ TEST(InternalSchemaEqMatchExpression, CorrectlyMatchesArrayElement) {
TEST(InternalSchemaEqMatchExpression, CorrectlyMatchesNullElement) {
BSONObj operand = BSON("a" << BSONNULL);
- InternalSchemaEqMatchExpression eq;
- ASSERT_OK(eq.init("a", operand["a"]));
+ InternalSchemaEqMatchExpression eq("a", operand["a"]);
ASSERT_TRUE(eq.matchesBSON(BSON("a" << BSONNULL)));
ASSERT_FALSE(eq.matchesBSON(BSON("a" << 4)));
}
@@ -78,8 +75,7 @@ TEST(InternalSchemaEqMatchExpression, CorrectlyMatchesNullElement) {
TEST(InternalSchemaEqMatchExpression, NullElementDoesNotMatchMissing) {
BSONObj operand = BSON("a" << BSONNULL);
- InternalSchemaEqMatchExpression eq;
- ASSERT_OK(eq.init("a", operand["a"]));
+ InternalSchemaEqMatchExpression eq("a", operand["a"]);
ASSERT_FALSE(eq.matchesBSON(BSONObj()));
ASSERT_FALSE(eq.matchesBSON(BSON("b" << 4)));
}
@@ -87,17 +83,14 @@ TEST(InternalSchemaEqMatchExpression, NullElementDoesNotMatchMissing) {
TEST(InternalSchemaEqMatchExpression, NullElementDoesNotMatchUndefinedOrMissing) {
BSONObj operand = BSON("a" << BSONNULL);
- InternalSchemaEqMatchExpression eq;
- ASSERT_OK(eq.init("a", operand["a"]));
+ InternalSchemaEqMatchExpression eq("a", operand["a"]);
ASSERT_FALSE(eq.matchesBSON(BSONObj()));
ASSERT_FALSE(eq.matchesBSON(fromjson("{a: undefined}")));
}
TEST(InternalSchemaEqMatchExpression, DoesNotTraverseLeafArrays) {
BSONObj operand = BSON("a" << 5);
-
- InternalSchemaEqMatchExpression eq;
- ASSERT_OK(eq.init("a", operand["a"]));
+ InternalSchemaEqMatchExpression eq("a", operand["a"]);
ASSERT_TRUE(eq.matchesBSON(BSON("a" << 5.0)));
ASSERT_FALSE(eq.matchesBSON(BSON("a" << BSON_ARRAY(5))));
}
@@ -105,8 +98,7 @@ TEST(InternalSchemaEqMatchExpression, DoesNotTraverseLeafArrays) {
TEST(InternalSchemaEqMatchExpression, MatchesObjectsIndependentOfFieldOrder) {
BSONObj operand = fromjson("{a: {b: 1, c: {d: 2, e: 3}}}");
- InternalSchemaEqMatchExpression eq;
- ASSERT_OK(eq.init("a", operand["a"]));
+ InternalSchemaEqMatchExpression eq("a", operand["a"]);
ASSERT_TRUE(eq.matchesBSON(fromjson("{a: {b: 1, c: {d: 2, e: 3}}}")));
ASSERT_TRUE(eq.matchesBSON(fromjson("{a: {c: {e: 3, d: 2}, b: 1}}")));
ASSERT_FALSE(eq.matchesBSON(fromjson("{a: {b: 1, c: {d: 2}, e: 3}}")));
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_fmod.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_fmod.cpp
index dcbe8c2b93b..3cc617d94bb 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_fmod.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_fmod.cpp
@@ -36,21 +36,15 @@
namespace mongo {
-Status InternalSchemaFmodMatchExpression::init(StringData path,
- Decimal128 divisor,
- Decimal128 remainder) {
- if (divisor.isZero()) {
- return Status(ErrorCodes::BadValue, "divisor cannot be 0");
- }
- if (divisor.isNaN()) {
- return Status(ErrorCodes::BadValue, "divisor cannot be NaN");
- }
- if (divisor.isInfinite()) {
- return Status(ErrorCodes::BadValue, "divisor cannot be infinite");
- }
- _divisor = divisor;
- _remainder = remainder;
- return setPath(path);
+InternalSchemaFmodMatchExpression::InternalSchemaFmodMatchExpression(StringData path,
+ Decimal128 divisor,
+ Decimal128 remainder)
+ : LeafMatchExpression(MatchType::INTERNAL_SCHEMA_FMOD, path),
+ _divisor(divisor),
+ _remainder(remainder) {
+ uassert(ErrorCodes::BadValue, "divisor cannot be 0", !divisor.isZero());
+ uassert(ErrorCodes::BadValue, "divisor cannot be NaN", !divisor.isNaN());
+ uassert(ErrorCodes::BadValue, "divisor cannot be infinite", !divisor.isInfinite());
}
bool InternalSchemaFmodMatchExpression::matchesSingleElement(const BSONElement& e,
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_fmod.h b/src/mongo/db/matcher/schema/expression_internal_schema_fmod.h
index 25a7b3c3945..6847913187d 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_fmod.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_fmod.h
@@ -38,14 +38,11 @@ namespace mongo {
*/
class InternalSchemaFmodMatchExpression final : public LeafMatchExpression {
public:
- InternalSchemaFmodMatchExpression() : LeafMatchExpression(MatchType::INTERNAL_SCHEMA_FMOD) {}
-
- Status init(StringData path, Decimal128 divisor, Decimal128 remainder);
+ InternalSchemaFmodMatchExpression(StringData path, Decimal128 divisor, Decimal128 remainder);
std::unique_ptr<MatchExpression> shallowClone() const final {
std::unique_ptr<InternalSchemaFmodMatchExpression> m =
- stdx::make_unique<InternalSchemaFmodMatchExpression>();
- invariantOK(m->init(path(), _divisor, _remainder));
+ stdx::make_unique<InternalSchemaFmodMatchExpression>(path(), _divisor, _remainder);
if (getTag()) {
m->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_fmod_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_fmod_test.cpp
index 2eef5fe0ed5..1701f0b8e29 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_fmod_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_fmod_test.cpp
@@ -40,8 +40,7 @@ TEST(InternalSchemaFmodMatchExpression, MatchesElement) {
BSONObj longLongMatch = BSON("a" << 68719476736LL);
BSONObj notMatch = BSON("a" << 6);
BSONObj negativeNotMatch = BSON("a" << -2);
- InternalSchemaFmodMatchExpression fmod;
- ASSERT_OK(fmod.init("", Decimal128(3), Decimal128(1)));
+ InternalSchemaFmodMatchExpression fmod("", Decimal128(3), Decimal128(1));
ASSERT_TRUE(fmod.matchesSingleElement(match.firstElement()));
ASSERT_TRUE(fmod.matchesSingleElement(largerMatch.firstElement()));
ASSERT_TRUE(fmod.matchesSingleElement(longLongMatch.firstElement()));
@@ -50,49 +49,44 @@ TEST(InternalSchemaFmodMatchExpression, MatchesElement) {
}
TEST(InternalSchemaFmodMatchExpression, ZeroDivisor) {
- InternalSchemaFmodMatchExpression fmod;
- ASSERT_NOT_OK(fmod.init("", Decimal128(0), Decimal128(1)));
+ ASSERT_THROWS_CODE(InternalSchemaFmodMatchExpression fmod("", Decimal128(0), Decimal128(1)),
+ AssertionException,
+ ErrorCodes::BadValue);
}
TEST(InternalSchemaFmodMatchExpression, MatchesScalar) {
- InternalSchemaFmodMatchExpression fmod;
- ASSERT_OK(fmod.init("a", Decimal128(5), Decimal128(2)));
+ InternalSchemaFmodMatchExpression fmod("a", Decimal128(5), Decimal128(2));
ASSERT_TRUE(fmod.matchesBSON(BSON("a" << 7.0)));
ASSERT_FALSE(fmod.matchesBSON(BSON("a" << 4)));
}
TEST(InternalSchemaFmodMatchExpression, MatchesNonIntegralValue) {
- InternalSchemaFmodMatchExpression fmod;
- ASSERT_OK(fmod.init("a", Decimal128(10.5), Decimal128((4.5))));
+ InternalSchemaFmodMatchExpression fmod("a", Decimal128(10.5), Decimal128((4.5)));
ASSERT_TRUE(fmod.matchesBSON(BSON("a" << 15.0)));
ASSERT_FALSE(fmod.matchesBSON(BSON("a" << 10.0)));
}
TEST(InternalSchemaFmodMatchExpression, MatchesArrayValue) {
- InternalSchemaFmodMatchExpression fmod;
- ASSERT_OK(fmod.init("a", Decimal128(5), Decimal128(2)));
+ InternalSchemaFmodMatchExpression fmod("a", Decimal128(5), Decimal128(2));
ASSERT_TRUE(fmod.matchesBSON(BSON("a" << BSON_ARRAY(5 << 12LL))));
ASSERT_FALSE(fmod.matchesBSON(BSON("a" << BSON_ARRAY(6 << 8))));
}
TEST(InternalSchemaFmodMatchExpression, DoesNotMatchNull) {
- InternalSchemaFmodMatchExpression fmod;
- ASSERT_OK(fmod.init("a", Decimal128(5), Decimal128(2)));
+ InternalSchemaFmodMatchExpression fmod("a", Decimal128(5), Decimal128(2));
ASSERT_FALSE(fmod.matchesBSON(BSONObj()));
ASSERT_FALSE(fmod.matchesBSON(BSON("a" << BSONNULL)));
}
TEST(InternalSchemaFmodMatchExpression, NegativeRemainders) {
- InternalSchemaFmodMatchExpression fmod;
- ASSERT_OK(fmod.init("a", Decimal128(5), Decimal128(-2.4)));
+ InternalSchemaFmodMatchExpression fmod("a", Decimal128(5), Decimal128(-2.4));
ASSERT_FALSE(fmod.matchesBSON(BSON("a" << 7.6)));
ASSERT_FALSE(fmod.matchesBSON(BSON("a" << 12.4)));
ASSERT_TRUE(fmod.matchesBSON(BSON("a" << Decimal128(-12.4))));
}
TEST(InternalSchemaFmodMatchExpression, ElemMatchKey) {
- InternalSchemaFmodMatchExpression fmod;
- ASSERT_OK(fmod.init("a", Decimal128(5), Decimal128(2)));
+ InternalSchemaFmodMatchExpression fmod("a", Decimal128(5), Decimal128(2));
MatchDetails details;
details.requestElemMatchKey();
ASSERT_FALSE(fmod.matchesBSON(BSON("a" << 4), &details));
@@ -105,15 +99,10 @@ TEST(InternalSchemaFmodMatchExpression, ElemMatchKey) {
}
TEST(InternalSchemaFmodMatchExpression, Equality) {
- InternalSchemaFmodMatchExpression m1;
- InternalSchemaFmodMatchExpression m2;
- InternalSchemaFmodMatchExpression m3;
- InternalSchemaFmodMatchExpression m4;
-
- ASSERT_OK(m1.init("a", Decimal128(1.7), Decimal128(2)));
- ASSERT_OK(m2.init("a", Decimal128(2), Decimal128(2)));
- ASSERT_OK(m3.init("a", Decimal128(1.7), Decimal128(1)));
- ASSERT_OK(m4.init("b", Decimal128(1.7), Decimal128(2)));
+ InternalSchemaFmodMatchExpression m1("a", Decimal128(1.7), Decimal128(2));
+ InternalSchemaFmodMatchExpression m2("a", Decimal128(2), Decimal128(2));
+ InternalSchemaFmodMatchExpression m3("a", Decimal128(1.7), Decimal128(1));
+ InternalSchemaFmodMatchExpression m4("b", Decimal128(1.7), Decimal128(2));
ASSERT_TRUE(m1.equivalent(&m1));
ASSERT_FALSE(m1.equivalent(&m2));
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.cpp
index c081792b4f1..0bca92144be 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.cpp
@@ -33,6 +33,14 @@
namespace mongo {
constexpr StringData InternalSchemaMatchArrayIndexMatchExpression::kName;
+InternalSchemaMatchArrayIndexMatchExpression::InternalSchemaMatchArrayIndexMatchExpression(
+ StringData path, long long index, std::unique_ptr<ExpressionWithPlaceholder> expression)
+ : ArrayMatchingMatchExpression(MatchExpression::INTERNAL_SCHEMA_MATCH_ARRAY_INDEX, path),
+ _index(index),
+ _expression(std::move(expression)) {
+ invariant(static_cast<bool>(_expression));
+}
+
void InternalSchemaMatchArrayIndexMatchExpression::debugString(StringBuilder& debug,
int level) const {
_debugAddSpace(debug, level);
@@ -59,14 +67,6 @@ bool InternalSchemaMatchArrayIndexMatchExpression::equivalent(const MatchExpress
_expression->equivalent(other->_expression.get());
}
-Status InternalSchemaMatchArrayIndexMatchExpression::init(
- StringData path, long long index, std::unique_ptr<ExpressionWithPlaceholder> expression) {
- invariant(static_cast<bool>(expression));
- _index = index;
- _expression = std::move(expression);
- return setPath(path);
-}
-
void InternalSchemaMatchArrayIndexMatchExpression::serialize(BSONObjBuilder* builder) const {
BSONObjBuilder pathSubobj(builder->subobjStart(path()));
{
@@ -85,8 +85,11 @@ void InternalSchemaMatchArrayIndexMatchExpression::serialize(BSONObjBuilder* bui
std::unique_ptr<MatchExpression> InternalSchemaMatchArrayIndexMatchExpression::shallowClone()
const {
- auto clone = stdx::make_unique<InternalSchemaMatchArrayIndexMatchExpression>();
- invariantOK(clone->init(path(), _index, _expression->shallowClone()));
+ auto clone = stdx::make_unique<InternalSchemaMatchArrayIndexMatchExpression>(
+ path(), _index, _expression->shallowClone());
+ if (getTag()) {
+ clone->setTag(getTag()->clone());
+ }
return std::move(clone);
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.h b/src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.h
index 520ccae568c..8b75d91374d 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_match_array_index.h
@@ -41,12 +41,8 @@ class InternalSchemaMatchArrayIndexMatchExpression final : public ArrayMatchingM
public:
static constexpr StringData kName = "$_internalSchemaMatchArrayIndex"_sd;
- InternalSchemaMatchArrayIndexMatchExpression()
- : ArrayMatchingMatchExpression(MatchExpression::INTERNAL_SCHEMA_MATCH_ARRAY_INDEX) {}
-
- Status init(StringData path,
- long long index,
- std::unique_ptr<ExpressionWithPlaceholder> expression);
+ InternalSchemaMatchArrayIndexMatchExpression(
+ StringData path, long long index, std::unique_ptr<ExpressionWithPlaceholder> expression);
void debugString(StringBuilder& debug, int level) const final;
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_max_items.h b/src/mongo/db/matcher/schema/expression_internal_schema_max_items.h
index 3ba965e298a..814aba1da84 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_max_items.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_max_items.h
@@ -39,9 +39,9 @@ namespace mongo {
class InternalSchemaMaxItemsMatchExpression final
: public InternalSchemaNumArrayItemsMatchExpression {
public:
- InternalSchemaMaxItemsMatchExpression()
- : InternalSchemaNumArrayItemsMatchExpression(INTERNAL_SCHEMA_MAX_ITEMS,
- "$_internalSchemaMaxItems"_sd) {}
+ InternalSchemaMaxItemsMatchExpression(StringData path, long long numItems)
+ : InternalSchemaNumArrayItemsMatchExpression(
+ INTERNAL_SCHEMA_MAX_ITEMS, path, numItems, "$_internalSchemaMaxItems"_sd) {}
bool matchesArray(const BSONObj& anArray, MatchDetails* details) const final {
return (anArray.nFields() <= numItems());
@@ -49,8 +49,7 @@ public:
std::unique_ptr<MatchExpression> shallowClone() const final {
std::unique_ptr<InternalSchemaMaxItemsMatchExpression> maxItems =
- stdx::make_unique<InternalSchemaMaxItemsMatchExpression>();
- invariantOK(maxItems->init(path(), numItems()));
+ stdx::make_unique<InternalSchemaMaxItemsMatchExpression>(path(), numItems());
if (getTag()) {
maxItems->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_max_items_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_max_items_test.cpp
index 27675889dee..88aa6ea1f48 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_max_items_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_max_items_test.cpp
@@ -37,8 +37,7 @@ namespace mongo {
namespace {
TEST(InternalSchemaMaxItemsMatchExpression, RejectsNonArrayElements) {
- InternalSchemaMaxItemsMatchExpression maxItems;
- ASSERT_OK(maxItems.init("a", 1));
+ InternalSchemaMaxItemsMatchExpression maxItems("a", 1);
ASSERT(!maxItems.matchesBSON(BSON("a" << BSONObj())));
ASSERT(!maxItems.matchesBSON(BSON("a" << 1)));
@@ -47,46 +46,40 @@ TEST(InternalSchemaMaxItemsMatchExpression, RejectsNonArrayElements) {
}
TEST(InternalSchemaMaxItemsMatchExpression, RejectsArraysWithTooManyElements) {
- InternalSchemaMaxItemsMatchExpression maxItems;
- ASSERT_OK(maxItems.init("a", 0));
+ InternalSchemaMaxItemsMatchExpression maxItems("a", 0);
ASSERT(!maxItems.matchesBSON(BSON("a" << BSON_ARRAY(1))));
ASSERT(!maxItems.matchesBSON(BSON("a" << BSON_ARRAY(1 << 2))));
}
TEST(InternalSchemaMaxItemsMatchExpression, AcceptsArrayWithLessThanOrEqualToMaxElements) {
- InternalSchemaMaxItemsMatchExpression maxItems;
- ASSERT_OK(maxItems.init("a", 2));
+ InternalSchemaMaxItemsMatchExpression maxItems("a", 2);
ASSERT(maxItems.matchesBSON(BSON("a" << BSON_ARRAY(5 << 6))));
ASSERT(maxItems.matchesBSON(BSON("a" << BSON_ARRAY(5))));
}
TEST(InternalSchemaMaxItemsMatchExpression, MaxItemsZeroAllowsEmptyArrays) {
- InternalSchemaMaxItemsMatchExpression maxItems;
- ASSERT_OK(maxItems.init("a", 0));
+ InternalSchemaMaxItemsMatchExpression maxItems("a", 0);
ASSERT(maxItems.matchesBSON(BSON("a" << BSONArray())));
}
TEST(InternalSchemaMaxItemsMatchExpression, NullArrayEntriesCountAsItems) {
- InternalSchemaMaxItemsMatchExpression maxItems;
- ASSERT_OK(maxItems.init("a", 2));
+ InternalSchemaMaxItemsMatchExpression maxItems("a", 2);
ASSERT(maxItems.matchesBSON(BSON("a" << BSON_ARRAY(BSONNULL << 1))));
ASSERT(!maxItems.matchesBSON(BSON("a" << BSON_ARRAY(BSONNULL << 1 << 2))));
}
TEST(InternalSchemaMaxItemsMatchExpression, NestedArraysAreNotUnwound) {
- InternalSchemaMaxItemsMatchExpression maxItems;
- ASSERT_OK(maxItems.init("a", 2));
+ InternalSchemaMaxItemsMatchExpression maxItems("a", 2);
ASSERT(maxItems.matchesBSON(BSON("a" << BSON_ARRAY(BSON_ARRAY(1 << 2 << 3)))));
}
TEST(InternalSchemaMaxItemsMatchExpression, NestedArraysWorkWithDottedPaths) {
- InternalSchemaMaxItemsMatchExpression maxItems;
- ASSERT_OK(maxItems.init("a.b", 2));
+ InternalSchemaMaxItemsMatchExpression maxItems("a.b", 2);
ASSERT(maxItems.matchesBSON(BSON("a" << BSON("b" << BSON_ARRAY(1)))));
ASSERT(!maxItems.matchesBSON(BSON("a" << BSON("b" << BSON_ARRAY(1 << 2 << 3)))));
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_max_length.h b/src/mongo/db/matcher/schema/expression_internal_schema_max_length.h
index a0e9cbad8bf..377b5b0f174 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_max_length.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_max_length.h
@@ -36,9 +36,10 @@ namespace mongo {
class InternalSchemaMaxLengthMatchExpression final : public InternalSchemaStrLengthMatchExpression {
public:
- InternalSchemaMaxLengthMatchExpression()
- : InternalSchemaStrLengthMatchExpression(MatchType::INTERNAL_SCHEMA_MAX_LENGTH,
- "$_internalSchemaMaxLength"_sd) {}
+ InternalSchemaMaxLengthMatchExpression(StringData path, long long strLen)
+ : InternalSchemaStrLengthMatchExpression(
+ MatchType::INTERNAL_SCHEMA_MAX_LENGTH, path, strLen, "$_internalSchemaMaxLength"_sd) {
+ }
Validator getComparator() const final {
return [strLen = strLen()](int lenWithoutNullTerm) {
@@ -48,8 +49,7 @@ public:
std::unique_ptr<MatchExpression> shallowClone() const final {
std::unique_ptr<InternalSchemaMaxLengthMatchExpression> maxLen =
- stdx::make_unique<InternalSchemaMaxLengthMatchExpression>();
- invariantOK(maxLen->init(path(), strLen()));
+ stdx::make_unique<InternalSchemaMaxLengthMatchExpression>(path(), strLen());
if (getTag()) {
maxLen->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_max_length_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_max_length_test.cpp
index 63b744fc829..55135c0c697 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_max_length_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_max_length_test.cpp
@@ -38,8 +38,7 @@ namespace mongo {
namespace {
TEST(InternalSchemaMaxLengthMatchExpression, RejectsNonStringElements) {
- InternalSchemaMaxLengthMatchExpression maxLength;
- ASSERT_OK(maxLength.init("a", 1));
+ InternalSchemaMaxLengthMatchExpression maxLength("a", 1);
ASSERT_FALSE(maxLength.matchesBSON(BSON("a" << BSONObj())));
ASSERT_FALSE(maxLength.matchesBSON(BSON("a" << 1)));
@@ -47,8 +46,7 @@ TEST(InternalSchemaMaxLengthMatchExpression, RejectsNonStringElements) {
}
TEST(InternalSchemaMaxLengthMatchExpression, RejectsStringsWithTooManyChars) {
- InternalSchemaMaxLengthMatchExpression maxLength;
- ASSERT_OK(maxLength.init("a", 2));
+ InternalSchemaMaxLengthMatchExpression maxLength("a", 2);
ASSERT_FALSE(maxLength.matchesBSON(BSON("a"
<< "abc")));
@@ -57,8 +55,7 @@ TEST(InternalSchemaMaxLengthMatchExpression, RejectsStringsWithTooManyChars) {
}
TEST(InternalSchemaMaxLengthMatchExpression, AcceptsStringsWithLessThanOrEqualToMax) {
- InternalSchemaMaxLengthMatchExpression maxLength;
- ASSERT_OK(maxLength.init("a", 2));
+ InternalSchemaMaxLengthMatchExpression maxLength("a", 2);
ASSERT_TRUE(maxLength.matchesBSON(BSON("a"
<< "ab")));
@@ -69,26 +66,21 @@ TEST(InternalSchemaMaxLengthMatchExpression, AcceptsStringsWithLessThanOrEqualTo
}
TEST(InternalSchemaMaxLengthMatchExpression, MaxLengthZeroAllowsEmptyString) {
- InternalSchemaMaxLengthMatchExpression maxLength;
- ASSERT_OK(maxLength.init("a", 0));
+ InternalSchemaMaxLengthMatchExpression maxLength("a", 0);
ASSERT_TRUE(maxLength.matchesBSON(BSON("a"
<< "")));
}
TEST(InternalSchemaMaxLengthMatchExpression, RejectsNull) {
- InternalSchemaMaxLengthMatchExpression maxLength;
- ASSERT_OK(maxLength.init("a", 1));
+ InternalSchemaMaxLengthMatchExpression maxLength("a", 1);
ASSERT_FALSE(maxLength.matchesBSON(BSON("a" << BSONNULL)));
}
TEST(InternalSchemaMaxLengthMatchExpression, TreatsMultiByteCodepointAsOneCharacter) {
- InternalSchemaMaxLengthMatchExpression nonMatchingMaxLength;
- InternalSchemaMaxLengthMatchExpression matchingMaxLength;
-
- ASSERT_OK(nonMatchingMaxLength.init("a", 0));
- ASSERT_OK(matchingMaxLength.init("a", 1));
+ InternalSchemaMaxLengthMatchExpression nonMatchingMaxLength("a", 0);
+ InternalSchemaMaxLengthMatchExpression matchingMaxLength("a", 1);
// This string has one code point, so it should meet maximum length 1 but not maximum length 0.
constexpr auto testString = u8"\U0001f4a9";
@@ -97,11 +89,8 @@ TEST(InternalSchemaMaxLengthMatchExpression, TreatsMultiByteCodepointAsOneCharac
}
TEST(InternalSchemaMaxLengthMatchExpression, CorectlyCountsUnicodeCodepoints) {
- InternalSchemaMaxLengthMatchExpression nonMatchingMaxLength;
- InternalSchemaMaxLengthMatchExpression matchingMaxLength;
-
- ASSERT_OK(nonMatchingMaxLength.init("a", 4));
- ASSERT_OK(matchingMaxLength.init("a", 5));
+ InternalSchemaMaxLengthMatchExpression nonMatchingMaxLength("a", 4);
+ InternalSchemaMaxLengthMatchExpression matchingMaxLength("a", 5);
// A test string that contains single-byte, 2-byte, 3-byte, and 4-byte codepoints.
constexpr auto testString =
@@ -118,9 +107,7 @@ TEST(InternalSchemaMaxLengthMatchExpression, CorectlyCountsUnicodeCodepoints) {
}
TEST(InternalSchemaMaxLengthMatchExpression, DealsWithInvalidUTF8) {
- InternalSchemaMaxLengthMatchExpression maxLength;
-
- ASSERT_OK(maxLength.init("a", 1));
+ InternalSchemaMaxLengthMatchExpression maxLength("a", 1);
// Several kinds of invalid byte sequences listed in the Wikipedia article about UTF-8:
// https://en.wikipedia.org/wiki/UTF-8
@@ -138,8 +125,7 @@ TEST(InternalSchemaMaxLengthMatchExpression, DealsWithInvalidUTF8) {
}
TEST(InternalSchemaMaxLengthMatchExpression, NestedArraysWorkWithDottedPaths) {
- InternalSchemaMaxLengthMatchExpression maxLength;
- ASSERT_OK(maxLength.init("a.b", 2));
+ InternalSchemaMaxLengthMatchExpression maxLength("a.b", 2);
ASSERT_TRUE(maxLength.matchesBSON(BSON("a" << BSON("b"
<< "a"))));
@@ -150,22 +136,17 @@ TEST(InternalSchemaMaxLengthMatchExpression, NestedArraysWorkWithDottedPaths) {
}
TEST(InternalSchemaMaxLengthMatchExpression, SameMaxLengthTreatedEquivalent) {
- InternalSchemaMaxLengthMatchExpression maxLength1;
- InternalSchemaMaxLengthMatchExpression maxLength2;
- InternalSchemaMaxLengthMatchExpression maxLength3;
- ASSERT_OK(maxLength1.init("a", 2));
- ASSERT_OK(maxLength2.init("a", 2));
- ASSERT_OK(maxLength3.init("a", 3));
+ InternalSchemaMaxLengthMatchExpression maxLength1("a", 2);
+ InternalSchemaMaxLengthMatchExpression maxLength2("a", 2);
+ InternalSchemaMaxLengthMatchExpression maxLength3("a", 3);
ASSERT_TRUE(maxLength1.equivalent(&maxLength2));
ASSERT_FALSE(maxLength1.equivalent(&maxLength3));
}
TEST(InternalSchemaMaxLengthMatchExpression, MinLengthAndMaxLengthAreNotEquivalent) {
- InternalSchemaMinLengthMatchExpression minLength;
- InternalSchemaMaxLengthMatchExpression maxLength;
- ASSERT_OK(minLength.init("a", 2));
- ASSERT_OK(maxLength.init("a", 2));
+ InternalSchemaMinLengthMatchExpression minLength("a", 2);
+ InternalSchemaMaxLengthMatchExpression maxLength("a", 2);
ASSERT_FALSE(maxLength.equivalent(&minLength));
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_max_properties.h b/src/mongo/db/matcher/schema/expression_internal_schema_max_properties.h
index 5736ca08017..82bc65dabef 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_max_properties.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_max_properties.h
@@ -39,8 +39,9 @@ namespace mongo {
class InternalSchemaMaxPropertiesMatchExpression final
: public InternalSchemaNumPropertiesMatchExpression {
public:
- InternalSchemaMaxPropertiesMatchExpression()
+ explicit InternalSchemaMaxPropertiesMatchExpression(long long numProperties)
: InternalSchemaNumPropertiesMatchExpression(MatchType::INTERNAL_SCHEMA_MAX_PROPERTIES,
+ numProperties,
"$_internalSchemaMaxProperties") {}
bool matches(const MatchableDocument* doc, MatchDetails* details) const final {
@@ -57,8 +58,8 @@ public:
}
virtual std::unique_ptr<MatchExpression> shallowClone() const final {
- auto maxProperties = stdx::make_unique<InternalSchemaMaxPropertiesMatchExpression>();
- invariantOK(maxProperties->init(numProperties()));
+ auto maxProperties =
+ stdx::make_unique<InternalSchemaMaxPropertiesMatchExpression>(numProperties());
if (getTag()) {
maxProperties->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_max_properties_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_max_properties_test.cpp
index c626bd81844..16c1c4f1fac 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_max_properties_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_max_properties_test.cpp
@@ -38,16 +38,14 @@ namespace mongo {
namespace {
TEST(InternalSchemaMaxPropertiesMatchExpression, RejectsObjectsWithTooManyElements) {
- InternalSchemaMaxPropertiesMatchExpression maxProperties;
- ASSERT_OK(maxProperties.init(0));
+ InternalSchemaMaxPropertiesMatchExpression maxProperties(0);
ASSERT_FALSE(maxProperties.matchesBSON(BSON("b" << 21)));
ASSERT_FALSE(maxProperties.matchesBSON(BSON("b" << 21 << "c" << 3)));
}
TEST(InternalSchemaMaxPropertiesMatchExpression, AcceptsObjectWithLessThanOrEqualToMaxElements) {
- InternalSchemaMaxPropertiesMatchExpression maxProperties;
- ASSERT_OK(maxProperties.init(2));
+ InternalSchemaMaxPropertiesMatchExpression maxProperties(2);
ASSERT_TRUE(maxProperties.matchesBSON(BSONObj()));
ASSERT_TRUE(maxProperties.matchesBSON(BSON("b" << BSONNULL)));
@@ -56,26 +54,21 @@ TEST(InternalSchemaMaxPropertiesMatchExpression, AcceptsObjectWithLessThanOrEqua
}
TEST(InternalSchemaMaxPropertiesMatchExpression, MaxPropertiesZeroAllowsEmptyObjects) {
- InternalSchemaMaxPropertiesMatchExpression maxProperties;
- ASSERT_OK(maxProperties.init(0));
+ InternalSchemaMaxPropertiesMatchExpression maxProperties(0);
ASSERT_TRUE(maxProperties.matchesBSON(BSONObj()));
}
TEST(InternalSchemaMaxPropertiesMatchExpression, NestedObjectsAreNotUnwound) {
- InternalSchemaMaxPropertiesMatchExpression maxProperties;
- ASSERT_OK(maxProperties.init(1));
+ InternalSchemaMaxPropertiesMatchExpression maxProperties(1);
ASSERT_TRUE(maxProperties.matchesBSON(BSON("b" << BSON("c" << 2 << "d" << 3))));
}
TEST(InternalSchemaMaxPropertiesMatchExpression, EquivalentFunctionIsAccurate) {
- InternalSchemaMaxPropertiesMatchExpression maxProperties1;
- InternalSchemaMaxPropertiesMatchExpression maxProperties2;
- InternalSchemaMaxPropertiesMatchExpression maxProperties3;
- ASSERT_OK(maxProperties1.init(1));
- ASSERT_OK(maxProperties2.init(1));
- ASSERT_OK(maxProperties3.init(2));
+ InternalSchemaMaxPropertiesMatchExpression maxProperties1(1);
+ InternalSchemaMaxPropertiesMatchExpression maxProperties2(1);
+ InternalSchemaMaxPropertiesMatchExpression maxProperties3(2);
ASSERT_TRUE(maxProperties1.equivalent(&maxProperties1));
ASSERT_TRUE(maxProperties1.equivalent(&maxProperties2));
@@ -83,17 +76,14 @@ TEST(InternalSchemaMaxPropertiesMatchExpression, EquivalentFunctionIsAccurate) {
}
TEST(InternalSchemaMaxPropertiesMatchExpression, NestedArraysAreNotUnwound) {
- InternalSchemaMaxPropertiesMatchExpression maxProperties;
- ASSERT_OK(maxProperties.init(2));
+ InternalSchemaMaxPropertiesMatchExpression maxProperties(2);
ASSERT_TRUE(maxProperties.matchesBSON(BSON("a" << (BSON("b" << 2 << "c" << 3 << "d" << 4)))));
}
TEST(InternalSchemaMaxPropertiesMatchExpression, MinPropertiesNotEquivalentToMaxProperties) {
- InternalSchemaMaxPropertiesMatchExpression maxProperties;
- InternalSchemaMinPropertiesMatchExpression minProperties;
- ASSERT_OK(maxProperties.init(5));
- ASSERT_OK(minProperties.init(5));
+ InternalSchemaMaxPropertiesMatchExpression maxProperties(5);
+ InternalSchemaMinPropertiesMatchExpression minProperties(5);
ASSERT_FALSE(maxProperties.equivalent(&minProperties));
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_min_items.h b/src/mongo/db/matcher/schema/expression_internal_schema_min_items.h
index 82eb16b5511..3aaffb62347 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_min_items.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_min_items.h
@@ -39,9 +39,9 @@ namespace mongo {
class InternalSchemaMinItemsMatchExpression final
: public InternalSchemaNumArrayItemsMatchExpression {
public:
- InternalSchemaMinItemsMatchExpression()
- : InternalSchemaNumArrayItemsMatchExpression(INTERNAL_SCHEMA_MIN_ITEMS,
- "$_internalSchemaMinItems"_sd) {}
+ InternalSchemaMinItemsMatchExpression(StringData path, long long numItems)
+ : InternalSchemaNumArrayItemsMatchExpression(
+ INTERNAL_SCHEMA_MIN_ITEMS, path, numItems, "$_internalSchemaMinItems"_sd) {}
bool matchesArray(const BSONObj& anArray, MatchDetails* details) const final {
return (anArray.nFields() >= numItems());
@@ -49,8 +49,7 @@ public:
std::unique_ptr<MatchExpression> shallowClone() const final {
std::unique_ptr<InternalSchemaMinItemsMatchExpression> minItems =
- stdx::make_unique<InternalSchemaMinItemsMatchExpression>();
- invariantOK(minItems->init(path(), numItems()));
+ stdx::make_unique<InternalSchemaMinItemsMatchExpression>(path(), numItems());
if (getTag()) {
minItems->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_min_items_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_min_items_test.cpp
index 2f43c269c7f..1df2e453539 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_min_items_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_min_items_test.cpp
@@ -36,8 +36,7 @@ namespace mongo {
namespace {
TEST(InternalSchemaMinItemsMatchExpression, RejectsNonArrayElements) {
- InternalSchemaMinItemsMatchExpression minItems;
- ASSERT_OK(minItems.init("a", 1));
+ InternalSchemaMinItemsMatchExpression minItems("a", 1);
ASSERT(!minItems.matchesBSON(BSON("a" << BSONObj())));
ASSERT(!minItems.matchesBSON(BSON("a" << 1)));
@@ -46,46 +45,40 @@ TEST(InternalSchemaMinItemsMatchExpression, RejectsNonArrayElements) {
}
TEST(InternalSchemaMinItemsMatchExpression, RejectsArraysWithTooFewElements) {
- InternalSchemaMinItemsMatchExpression minItems;
- ASSERT_OK(minItems.init("a", 2));
+ InternalSchemaMinItemsMatchExpression minItems("a", 2);
ASSERT(!minItems.matchesBSON(BSON("a" << BSONArray())));
ASSERT(!minItems.matchesBSON(BSON("a" << BSON_ARRAY(1))));
}
TEST(InternalSchemaMinItemsMatchExpression, AcceptsArrayWithAtLeastMinElements) {
- InternalSchemaMinItemsMatchExpression minItems;
- ASSERT_OK(minItems.init("a", 2));
+ InternalSchemaMinItemsMatchExpression minItems("a", 2);
ASSERT(minItems.matchesBSON(BSON("a" << BSON_ARRAY(1 << 2))));
ASSERT(minItems.matchesBSON(BSON("a" << BSON_ARRAY(1 << 2 << 3))));
}
TEST(InternalSchemaMinItemsMatchExpression, MinItemsZeroAllowsEmptyArrays) {
- InternalSchemaMinItemsMatchExpression minItems;
- ASSERT_OK(minItems.init("a", 0));
+ InternalSchemaMinItemsMatchExpression minItems("a", 0);
ASSERT(minItems.matchesBSON(BSON("a" << BSONArray())));
}
TEST(InternalSchemaMinItemsMatchExpression, NullArrayEntriesCountAsItems) {
- InternalSchemaMinItemsMatchExpression minItems;
- ASSERT_OK(minItems.init("a", 1));
+ InternalSchemaMinItemsMatchExpression minItems("a", 1);
ASSERT(minItems.matchesBSON(BSON("a" << BSON_ARRAY(BSONNULL))));
ASSERT(minItems.matchesBSON(BSON("a" << BSON_ARRAY(BSONNULL << 1))));
}
TEST(InternalSchemaMinItemsMatchExpression, NestedArraysAreNotUnwound) {
- InternalSchemaMinItemsMatchExpression minItems;
- ASSERT_OK(minItems.init("a", 2));
+ InternalSchemaMinItemsMatchExpression minItems("a", 2);
ASSERT(!minItems.matchesBSON(BSON("a" << BSON_ARRAY(BSON_ARRAY(1 << 2)))));
}
TEST(InternalSchemaMinItemsMatchExpression, NestedArraysWorkWithDottedPaths) {
- InternalSchemaMinItemsMatchExpression minItems;
- ASSERT_OK(minItems.init("a.b", 2));
+ InternalSchemaMinItemsMatchExpression minItems("a.b", 2);
ASSERT(minItems.matchesBSON(BSON("a" << BSON("b" << BSON_ARRAY(1 << 2)))));
ASSERT(!minItems.matchesBSON(BSON("a" << BSON("b" << BSON_ARRAY(1)))));
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_min_length.h b/src/mongo/db/matcher/schema/expression_internal_schema_min_length.h
index 1d4d18da4e2..aad59831247 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_min_length.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_min_length.h
@@ -36,9 +36,10 @@ namespace mongo {
class InternalSchemaMinLengthMatchExpression final : public InternalSchemaStrLengthMatchExpression {
public:
- InternalSchemaMinLengthMatchExpression()
- : InternalSchemaStrLengthMatchExpression(MatchType::INTERNAL_SCHEMA_MIN_LENGTH,
- "$_internalSchemaMinLength"_sd) {}
+ InternalSchemaMinLengthMatchExpression(StringData path, long long strLen)
+ : InternalSchemaStrLengthMatchExpression(
+ MatchType::INTERNAL_SCHEMA_MIN_LENGTH, path, strLen, "$_internalSchemaMinLength"_sd) {
+ }
Validator getComparator() const final {
return [strLen = strLen()](int lenWithoutNullTerm) {
@@ -48,8 +49,7 @@ public:
std::unique_ptr<MatchExpression> shallowClone() const final {
std::unique_ptr<InternalSchemaMinLengthMatchExpression> minLen =
- stdx::make_unique<InternalSchemaMinLengthMatchExpression>();
- invariantOK(minLen->init(path(), strLen()));
+ stdx::make_unique<InternalSchemaMinLengthMatchExpression>(path(), strLen());
if (getTag()) {
minLen->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_min_length_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_min_length_test.cpp
index 2e72f8ea2ac..8fbdd695d0b 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_min_length_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_min_length_test.cpp
@@ -37,8 +37,7 @@ namespace mongo {
namespace {
TEST(InternalSchemaMinLengthMatchExpression, RejectsNonStringElements) {
- InternalSchemaMinLengthMatchExpression minLength;
- ASSERT_OK(minLength.init("a", 1));
+ InternalSchemaMinLengthMatchExpression minLength("a", 1);
ASSERT_FALSE(minLength.matchesBSON(BSON("a" << BSONObj())));
ASSERT_FALSE(minLength.matchesBSON(BSON("a" << 1)));
@@ -46,8 +45,7 @@ TEST(InternalSchemaMinLengthMatchExpression, RejectsNonStringElements) {
}
TEST(InternalSchemaMinLengthMatchExpression, RejectsStringsWithTooFewChars) {
- InternalSchemaMinLengthMatchExpression minLength;
- ASSERT_OK(minLength.init("a", 2));
+ InternalSchemaMinLengthMatchExpression minLength("a", 2);
ASSERT_FALSE(minLength.matchesBSON(BSON("a"
<< "")));
@@ -56,8 +54,7 @@ TEST(InternalSchemaMinLengthMatchExpression, RejectsStringsWithTooFewChars) {
}
TEST(InternalSchemaMinLengthMatchExpression, AcceptsStringWithAtLeastMinChars) {
- InternalSchemaMinLengthMatchExpression minLength;
- ASSERT_OK(minLength.init("a", 2));
+ InternalSchemaMinLengthMatchExpression minLength("a", 2);
ASSERT_TRUE(minLength.matchesBSON(BSON("a"
<< "ab")));
@@ -68,26 +65,21 @@ TEST(InternalSchemaMinLengthMatchExpression, AcceptsStringWithAtLeastMinChars) {
}
TEST(InternalSchemaMinLengthMatchExpression, MinLengthZeroAllowsEmptyString) {
- InternalSchemaMinLengthMatchExpression minLength;
- ASSERT_OK(minLength.init("a", 0));
+ InternalSchemaMinLengthMatchExpression minLength("a", 0);
ASSERT_TRUE(minLength.matchesBSON(BSON("a"
<< "")));
}
TEST(InternalSchemaMinLengthMatchExpression, RejectsNull) {
- InternalSchemaMinLengthMatchExpression minLength;
- ASSERT_OK(minLength.init("a", 1));
+ InternalSchemaMinLengthMatchExpression minLength("a", 1);
ASSERT_FALSE(minLength.matchesBSON(BSON("a" << BSONNULL)));
}
TEST(InternalSchemaMinLengthMatchExpression, TreatsMultiByteCodepointAsOneCharacter) {
- InternalSchemaMinLengthMatchExpression matchingMinLength;
- InternalSchemaMinLengthMatchExpression nonMatchingMinLength;
-
- ASSERT_OK(matchingMinLength.init("a", 1));
- ASSERT_OK(nonMatchingMinLength.init("a", 2));
+ InternalSchemaMinLengthMatchExpression matchingMinLength("a", 1);
+ InternalSchemaMinLengthMatchExpression nonMatchingMinLength("a", 2);
// This string has one code point, so it should meet minimum length 1 but not minimum length 2.
constexpr auto testString = u8"\U0001f4a9";
@@ -96,11 +88,8 @@ TEST(InternalSchemaMinLengthMatchExpression, TreatsMultiByteCodepointAsOneCharac
}
TEST(InternalSchemaMinLengthMatchExpression, CorectlyCountsUnicodeCodepoints) {
- InternalSchemaMinLengthMatchExpression matchingMinLength;
- InternalSchemaMinLengthMatchExpression nonMatchingMinLength;
-
- ASSERT_OK(matchingMinLength.init("a", 5));
- ASSERT_OK(nonMatchingMinLength.init("a", 6));
+ InternalSchemaMinLengthMatchExpression matchingMinLength("a", 5);
+ InternalSchemaMinLengthMatchExpression nonMatchingMinLength("a", 6);
// A test string that contains single-byte, 2-byte, 3-byte, and 4-byte code points.
constexpr auto testString =
@@ -117,9 +106,7 @@ TEST(InternalSchemaMinLengthMatchExpression, CorectlyCountsUnicodeCodepoints) {
}
TEST(InternalSchemaMinLengthMatchExpression, DealsWithInvalidUTF8) {
- InternalSchemaMinLengthMatchExpression minLength;
-
- ASSERT_OK(minLength.init("a", 1));
+ InternalSchemaMinLengthMatchExpression minLength("a", 1);
// Several kinds of invalid byte sequences listed in the Wikipedia article about UTF-8:
// https://en.wikipedia.org/wiki/UTF-8
@@ -137,8 +124,7 @@ TEST(InternalSchemaMinLengthMatchExpression, DealsWithInvalidUTF8) {
}
TEST(InternalSchemaMinLengthMatchExpression, NestedFieldsWorkWithDottedPaths) {
- InternalSchemaMinLengthMatchExpression minLength;
- ASSERT_OK(minLength.init("a.b", 2));
+ InternalSchemaMinLengthMatchExpression minLength("a.b", 2);
ASSERT_TRUE(minLength.matchesBSON(BSON("a" << BSON("b"
<< "ab"))));
@@ -149,12 +135,9 @@ TEST(InternalSchemaMinLengthMatchExpression, NestedFieldsWorkWithDottedPaths) {
}
TEST(InternalSchemaMinLengthMatchExpression, SameMinLengthTreatedEquivalent) {
- InternalSchemaMinLengthMatchExpression minLength1;
- InternalSchemaMinLengthMatchExpression minLength2;
- InternalSchemaMinLengthMatchExpression minLength3;
- ASSERT_OK(minLength1.init("a", 2));
- ASSERT_OK(minLength2.init("a", 2));
- ASSERT_OK(minLength3.init("a", 3));
+ InternalSchemaMinLengthMatchExpression minLength1("a", 2);
+ InternalSchemaMinLengthMatchExpression minLength2("a", 2);
+ InternalSchemaMinLengthMatchExpression minLength3("a", 3);
ASSERT_TRUE(minLength1.equivalent(&minLength2));
ASSERT_FALSE(minLength1.equivalent(&minLength3));
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_min_properties.h b/src/mongo/db/matcher/schema/expression_internal_schema_min_properties.h
index b97506fd882..9ac68da48a3 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_min_properties.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_min_properties.h
@@ -39,8 +39,9 @@ namespace mongo {
class InternalSchemaMinPropertiesMatchExpression final
: public InternalSchemaNumPropertiesMatchExpression {
public:
- InternalSchemaMinPropertiesMatchExpression()
+ explicit InternalSchemaMinPropertiesMatchExpression(long long numProperties)
: InternalSchemaNumPropertiesMatchExpression(MatchType::INTERNAL_SCHEMA_MIN_PROPERTIES,
+ numProperties,
"$_internalSchemaMinProperties") {}
bool matches(const MatchableDocument* doc, MatchDetails* details) const final {
@@ -57,8 +58,8 @@ public:
}
virtual std::unique_ptr<MatchExpression> shallowClone() const final {
- auto minProperties = stdx::make_unique<InternalSchemaMinPropertiesMatchExpression>();
- invariantOK(minProperties->init(numProperties()));
+ auto minProperties =
+ stdx::make_unique<InternalSchemaMinPropertiesMatchExpression>(numProperties());
if (getTag()) {
minProperties->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_min_properties_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_min_properties_test.cpp
index e364180a7f9..1699c2a6fd4 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_min_properties_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_min_properties_test.cpp
@@ -38,16 +38,14 @@ namespace mongo {
namespace {
TEST(InternalSchemaMinPropertiesMatchExpression, RejectsObjectsWithTooFewElements) {
- InternalSchemaMinPropertiesMatchExpression minProperties;
- ASSERT_OK(minProperties.init(2));
+ InternalSchemaMinPropertiesMatchExpression minProperties(2);
ASSERT_FALSE(minProperties.matchesBSON(BSONObj()));
ASSERT_FALSE(minProperties.matchesBSON(BSON("b" << 21)));
}
TEST(InternalSchemaMinPropertiesMatchExpression, AcceptsObjectWithAtLeastMinElements) {
- InternalSchemaMinPropertiesMatchExpression minProperties;
- ASSERT_OK(minProperties.init(2));
+ InternalSchemaMinPropertiesMatchExpression minProperties(2);
ASSERT_TRUE(minProperties.matchesBSON(BSON("b" << 21 << "c" << BSONNULL)));
ASSERT_TRUE(minProperties.matchesBSON(BSON("b" << 21 << "c" << 3)));
@@ -55,33 +53,27 @@ TEST(InternalSchemaMinPropertiesMatchExpression, AcceptsObjectWithAtLeastMinElem
}
TEST(InternalSchemaMinPropertiesMatchExpression, MinPropertiesZeroAllowsEmptyObjects) {
- InternalSchemaMinPropertiesMatchExpression minProperties;
- ASSERT_OK(minProperties.init(0));
+ InternalSchemaMinPropertiesMatchExpression minProperties(0);
ASSERT_TRUE(minProperties.matchesBSON(BSONObj()));
}
TEST(InternalSchemaMinPropertiesMatchExpression, NestedObjectsAreNotUnwound) {
- InternalSchemaMinPropertiesMatchExpression minProperties;
- ASSERT_OK(minProperties.init(2));
+ InternalSchemaMinPropertiesMatchExpression minProperties(2);
ASSERT_FALSE(minProperties.matchesBSON(BSON("b" << BSON("c" << 2 << "d" << 3))));
}
TEST(InternalSchemaMinPropertiesMatchExpression, NestedArraysAreNotUnwound) {
- InternalSchemaMinPropertiesMatchExpression minProperties;
- ASSERT_OK(minProperties.init(2));
+ InternalSchemaMinPropertiesMatchExpression minProperties(2);
ASSERT_FALSE(minProperties.matchesBSON(BSON("a" << (BSON("b" << 2 << "c" << 3 << "d" << 4)))));
}
TEST(InternalSchemaMinPropertiesMatchExpression, EquivalentFunctionIsAccurate) {
- InternalSchemaMinPropertiesMatchExpression minProperties1;
- InternalSchemaMinPropertiesMatchExpression minProperties2;
- InternalSchemaMinPropertiesMatchExpression minProperties3;
- ASSERT_OK(minProperties1.init(1));
- ASSERT_OK(minProperties2.init(1));
- ASSERT_OK(minProperties3.init(2));
+ InternalSchemaMinPropertiesMatchExpression minProperties1(1);
+ InternalSchemaMinPropertiesMatchExpression minProperties2(1);
+ InternalSchemaMinPropertiesMatchExpression minProperties3(2);
ASSERT_TRUE(minProperties1.equivalent(&minProperties1));
ASSERT_TRUE(minProperties1.equivalent(&minProperties2));
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.cpp
index f6a31657847..d5bc5069a35 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.cpp
@@ -32,6 +32,10 @@
namespace mongo {
+InternalSchemaNumArrayItemsMatchExpression::InternalSchemaNumArrayItemsMatchExpression(
+ MatchType type, StringData path, long long numItems, StringData name)
+ : ArrayMatchingMatchExpression(type, path), _name(name), _numItems(numItems) {}
+
void InternalSchemaNumArrayItemsMatchExpression::debugString(StringBuilder& debug,
int level) const {
_debugAddSpace(debug, level);
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.h b/src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.h
index 05dd873d772..b8db5a34258 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_num_array_items.h
@@ -38,16 +38,13 @@ namespace mongo {
*/
class InternalSchemaNumArrayItemsMatchExpression : public ArrayMatchingMatchExpression {
public:
- InternalSchemaNumArrayItemsMatchExpression(MatchType type, StringData name)
- : ArrayMatchingMatchExpression(type), _name(name) {}
+ InternalSchemaNumArrayItemsMatchExpression(MatchType type,
+ StringData path,
+ long long numItems,
+ StringData name);
virtual ~InternalSchemaNumArrayItemsMatchExpression() {}
- Status init(StringData path, long long numItems) {
- _numItems = numItems;
- return setPath(path);
- }
-
void debugString(StringBuilder& debug, int level) const final;
void serialize(BSONObjBuilder* out) const final;
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_num_properties.h b/src/mongo/db/matcher/schema/expression_internal_schema_num_properties.h
index ced6529a668..541b30ebfe4 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_num_properties.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_num_properties.h
@@ -39,16 +39,13 @@ namespace mongo {
*/
class InternalSchemaNumPropertiesMatchExpression : public MatchExpression {
public:
- InternalSchemaNumPropertiesMatchExpression(MatchType type, std::string name)
- : MatchExpression(type), _name(name) {}
+ InternalSchemaNumPropertiesMatchExpression(MatchType type,
+ long long numProperties,
+ std::string name)
+ : MatchExpression(type), _numProperties(numProperties), _name(name) {}
virtual ~InternalSchemaNumPropertiesMatchExpression() {}
- Status init(long long numProperties) {
- _numProperties = numProperties;
- return Status::OK();
- }
-
size_t numChildren() const final {
return 0;
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_object_match.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_object_match.cpp
index 9e8d5ac702a..d6a8c05342b 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_object_match.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_object_match.cpp
@@ -34,6 +34,12 @@ namespace mongo {
constexpr StringData InternalSchemaObjectMatchExpression::kName;
+InternalSchemaObjectMatchExpression::InternalSchemaObjectMatchExpression(
+ StringData path, std::unique_ptr<MatchExpression> expr)
+ : PathMatchExpression(INTERNAL_SCHEMA_OBJECT_MATCH, path), _sub(std::move(expr)) {
+ setTraverseLeafArray();
+}
+
bool InternalSchemaObjectMatchExpression::matchesSingleElement(const BSONElement& elem,
MatchDetails* details) const {
if (elem.type() != BSONType::Object) {
@@ -65,8 +71,8 @@ bool InternalSchemaObjectMatchExpression::equivalent(const MatchExpression* othe
}
std::unique_ptr<MatchExpression> InternalSchemaObjectMatchExpression::shallowClone() const {
- auto clone = stdx::make_unique<InternalSchemaObjectMatchExpression>();
- invariantOK(clone->init(_sub->shallowClone(), path()));
+ auto clone =
+ stdx::make_unique<InternalSchemaObjectMatchExpression>(path(), _sub->shallowClone());
if (getTag()) {
clone->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_object_match.h b/src/mongo/db/matcher/schema/expression_internal_schema_object_match.h
index ef328388c0b..776d35af6de 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_object_match.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_object_match.h
@@ -36,12 +36,7 @@ class InternalSchemaObjectMatchExpression final : public PathMatchExpression {
public:
static constexpr StringData kName = "$_internalSchemaObjectMatch"_sd;
- InternalSchemaObjectMatchExpression() : PathMatchExpression(INTERNAL_SCHEMA_OBJECT_MATCH) {}
-
- Status init(std::unique_ptr<MatchExpression> expr, StringData path) {
- _sub = std::move(expr);
- return setPath(path);
- }
+ InternalSchemaObjectMatchExpression(StringData path, std::unique_ptr<MatchExpression> expr);
bool matchesSingleElement(const BSONElement& elem, MatchDetails* details = nullptr) const final;
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp
index a6d0ff5b5f9..f6ad77e4e06 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp
@@ -45,8 +45,7 @@ TEST(InternalSchemaObjectMatchExpression, RejectsNonObjectElements) {
auto subExpr = MatchExpressionParser::parse(BSON("b" << 1), expCtx);
ASSERT_OK(subExpr.getStatus());
- InternalSchemaObjectMatchExpression objMatch;
- ASSERT_OK(objMatch.init(std::move(subExpr.getValue()), "a"_sd));
+ InternalSchemaObjectMatchExpression objMatch("a"_sd, std::move(subExpr.getValue()));
ASSERT_FALSE(objMatch.matchesBSON(BSON("a" << 1)));
ASSERT_FALSE(objMatch.matchesBSON(BSON("a"
@@ -61,8 +60,7 @@ TEST(InternalSchemaObjectMatchExpression, RejectsObjectsThatDontMatch) {
expCtx);
ASSERT_OK(subExpr.getStatus());
- InternalSchemaObjectMatchExpression objMatch;
- ASSERT_OK(objMatch.init(std::move(subExpr.getValue()), "a"_sd));
+ InternalSchemaObjectMatchExpression objMatch("a"_sd, std::move(subExpr.getValue()));
ASSERT_FALSE(objMatch.matchesBSON(BSON("a" << BSON("b" << 1))));
ASSERT_FALSE(objMatch.matchesBSON(BSON("a" << BSON("b" << BSONObj()))));
@@ -75,8 +73,7 @@ TEST(InternalSchemaObjectMatchExpression, AcceptsObjectsThatMatch) {
expCtx);
ASSERT_OK(subExpr.getStatus());
- InternalSchemaObjectMatchExpression objMatch;
- ASSERT_OK(objMatch.init(std::move(subExpr.getValue()), "a"_sd));
+ InternalSchemaObjectMatchExpression objMatch("a"_sd, std::move(subExpr.getValue()));
ASSERT_TRUE(objMatch.matchesBSON(BSON("a" << BSON("b"
<< "string"))));
@@ -97,8 +94,7 @@ TEST(InternalSchemaObjectMatchExpression, DottedPathAcceptsObjectsThatMatch) {
expCtx);
ASSERT_OK(subExpr.getStatus());
- InternalSchemaObjectMatchExpression objMatch;
- ASSERT_OK(objMatch.init(std::move(subExpr.getValue()), "a"_sd));
+ InternalSchemaObjectMatchExpression objMatch("a"_sd, std::move(subExpr.getValue()));
ASSERT_FALSE(objMatch.matchesBSON(BSON("a" << BSON("d"
<< "string"))));
@@ -112,8 +108,7 @@ TEST(InternalSchemaObjectMatchExpression, EmptyMatchAcceptsAllObjects) {
auto subExpr = MatchExpressionParser::parse(BSONObj(), expCtx);
ASSERT_OK(subExpr.getStatus());
- InternalSchemaObjectMatchExpression objMatch;
- ASSERT_OK(objMatch.init(std::move(subExpr.getValue()), "a"_sd));
+ InternalSchemaObjectMatchExpression objMatch("a"_sd, std::move(subExpr.getValue()));
ASSERT_FALSE(objMatch.matchesBSON(BSON("a" << 1)));
ASSERT_FALSE(objMatch.matchesBSON(BSON("a"
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.cpp
index c0a5bbf8922..2684533c465 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.cpp
@@ -68,8 +68,7 @@ bool InternalSchemaRootDocEqMatchExpression::equivalent(const MatchExpression* o
}
std::unique_ptr<MatchExpression> InternalSchemaRootDocEqMatchExpression::shallowClone() const {
- auto clone = stdx::make_unique<InternalSchemaRootDocEqMatchExpression>();
- clone->init(_rhsObj);
+ auto clone = stdx::make_unique<InternalSchemaRootDocEqMatchExpression>(_rhsObj.copy());
if (getTag()) {
clone->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.h b/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.h
index e6f53658eda..7ca66e89ca2 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq.h
@@ -45,12 +45,11 @@ class InternalSchemaRootDocEqMatchExpression final : public MatchExpression {
public:
static constexpr StringData kName = "$_internalSchemaRootDocEq"_sd;
- InternalSchemaRootDocEqMatchExpression()
- : MatchExpression(MatchExpression::INTERNAL_SCHEMA_ROOT_DOC_EQ) {}
-
- void init(BSONObj obj) {
- _rhsObj = std::move(obj);
- }
+ /**
+ * Constructs a new match expression, taking ownership of 'rhs'.
+ */
+ explicit InternalSchemaRootDocEqMatchExpression(BSONObj rhs)
+ : MatchExpression(MatchExpression::INTERNAL_SCHEMA_ROOT_DOC_EQ), _rhsObj(std::move(rhs)) {}
bool matches(const MatchableDocument* doc, MatchDetails* details = nullptr) const final;
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq_test.cpp
index ade721236d3..0a1e36d69c2 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_root_doc_eq_test.cpp
@@ -38,9 +38,8 @@ namespace mongo {
namespace {
TEST(InternalSchemaRootDocEqMatchExpression, MatchesObject) {
- InternalSchemaRootDocEqMatchExpression rootDocEq;
- rootDocEq.init(BSON("a" << 1 << "b"
- << "string"));
+ InternalSchemaRootDocEqMatchExpression rootDocEq(BSON("a" << 1 << "b"
+ << "string"));
ASSERT_TRUE(rootDocEq.matchesBSON(BSON("a" << 1 << "b"
<< "string")));
ASSERT_FALSE(rootDocEq.matchesBSON(BSON("a" << 2 << "b"
@@ -48,40 +47,34 @@ TEST(InternalSchemaRootDocEqMatchExpression, MatchesObject) {
}
TEST(InternalSchemaRootDocEqMatchExpression, MatchesNestedObject) {
- InternalSchemaRootDocEqMatchExpression rootDocEq;
- rootDocEq.init(BSON("a" << 1 << "b" << BSON("c" << 1)));
+ InternalSchemaRootDocEqMatchExpression rootDocEq(BSON("a" << 1 << "b" << BSON("c" << 1)));
ASSERT_TRUE(rootDocEq.matchesBSON(BSON("a" << 1 << "b" << BSON("c" << 1))));
ASSERT_FALSE(rootDocEq.matchesBSON(BSON("a" << 1 << "b" << BSON("c" << 2))));
}
TEST(InternalSchemaRootDocEqMatchExpression, MatchesObjectIgnoresElementOrder) {
- InternalSchemaRootDocEqMatchExpression rootDocEq;
- rootDocEq.init(BSON("a" << 1 << "b" << BSON("c" << 1)));
+ InternalSchemaRootDocEqMatchExpression rootDocEq(BSON("a" << 1 << "b" << BSON("c" << 1)));
ASSERT_TRUE(rootDocEq.matchesBSON(BSON("b" << BSON("c" << 1) << "a" << 1)));
}
TEST(InternalSchemaRootDocEqMatchExpression, MatchesNestedObjectIgnoresElementOrder) {
- InternalSchemaRootDocEqMatchExpression rootDocEq;
- rootDocEq.init(BSON("a" << BSON("b" << 1 << "c" << 1)));
+ InternalSchemaRootDocEqMatchExpression rootDocEq(BSON("a" << BSON("b" << 1 << "c" << 1)));
ASSERT_TRUE(rootDocEq.matchesBSON(BSON("a" << BSON("c" << 1 << "b" << 1))));
}
TEST(InternalSchemaRootDocEqMatchExpression, MatchesEmptyObject) {
- InternalSchemaRootDocEqMatchExpression rootDocEq;
- rootDocEq.init(BSONObj());
+ InternalSchemaRootDocEqMatchExpression rootDocEq{BSONObj()};
ASSERT_TRUE(rootDocEq.matchesBSON(BSONObj()));
}
TEST(InternalSchemaRootDocEqMatchExpression, MatchesNestedArray) {
- InternalSchemaRootDocEqMatchExpression rootDocEq;
- rootDocEq.init(BSON("a" << BSON_ARRAY(1 << 2 << 3)));
+ InternalSchemaRootDocEqMatchExpression rootDocEq(BSON("a" << BSON_ARRAY(1 << 2 << 3)));
ASSERT_TRUE(rootDocEq.matchesBSON(BSON("a" << BSON_ARRAY(1 << 2 << 3))));
ASSERT_FALSE(rootDocEq.matchesBSON(BSON("a" << BSON_ARRAY(1 << 3 << 2))));
}
TEST(InternalSchemaRootDocEqMatchExpression, MatchesObjectWithNullElement) {
- InternalSchemaRootDocEqMatchExpression rootDocEq;
- rootDocEq.init(fromjson("{a: null}"));
+ InternalSchemaRootDocEqMatchExpression rootDocEq(fromjson("{a: null}"));
ASSERT_TRUE(rootDocEq.matchesBSON(fromjson("{a: null}")));
ASSERT_FALSE(rootDocEq.matchesBSON(fromjson("{a: 1}")));
ASSERT_FALSE(rootDocEq.matchesBSON(fromjson("{}")));
@@ -94,27 +87,28 @@ TEST(InternalSchemaRootDocEqMatchExpression, EquivalentReturnsCorrectResults) {
b: 1, c: 1
}})");
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- Matcher rootDocEq(query, expCtx);
+ Matcher rootDocEq(std::move(query), expCtx);
query = fromjson(R"(
{$_internalSchemaRootDocEq: {
c: 1, b: 1
}})");
- Matcher exprEq(query, expCtx);
+ Matcher exprEq(std::move(query), expCtx);
ASSERT_TRUE(rootDocEq.getMatchExpression()->equivalent(exprEq.getMatchExpression()));
query = fromjson(R"(
{$_internalSchemaRootDocEq: {
c: 1
}})");
- Matcher exprNotEq(query, expCtx);
+ Matcher exprNotEq(std::move(query), expCtx);
ASSERT_FALSE(rootDocEq.getMatchExpression()->equivalent(exprNotEq.getMatchExpression()));
}
TEST(InternalSchemaRootDocEqMatchExpression, EquivalentToClone) {
auto query = fromjson("{$_internalSchemaRootDocEq: {a:1, b: {c: 1, d: [1]}}}");
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- Matcher rootDocEq(query, expCtx);
+ Matcher rootDocEq(std::move(query), expCtx);
+
auto clone = rootDocEq.getMatchExpression()->shallowClone();
ASSERT_TRUE(rootDocEq.getMatchExpression()->equivalent(clone.get()));
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_str_length.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_str_length.cpp
index 02a7b8895e8..f01f3e80ba5 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_str_length.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_str_length.cpp
@@ -34,6 +34,12 @@
namespace mongo {
+InternalSchemaStrLengthMatchExpression::InternalSchemaStrLengthMatchExpression(MatchType type,
+ StringData path,
+ long long strLen,
+ StringData name)
+ : LeafMatchExpression(type, path), _name(name), _strLen(strLen) {}
+
void InternalSchemaStrLengthMatchExpression::debugString(StringBuilder& debug, int level) const {
_debugAddSpace(debug, level);
debug << path() << " " << _name << " " << _strLen << "\n";
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_str_length.h b/src/mongo/db/matcher/schema/expression_internal_schema_str_length.h
index 90830577432..2a00de506b9 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_str_length.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_str_length.h
@@ -38,16 +38,13 @@ class InternalSchemaStrLengthMatchExpression : public LeafMatchExpression {
public:
using Validator = stdx::function<bool(int)>;
- InternalSchemaStrLengthMatchExpression(MatchType type, StringData name)
- : LeafMatchExpression(type), _name(name) {}
+ InternalSchemaStrLengthMatchExpression(MatchType type,
+ StringData path,
+ long long strLen,
+ StringData name);
virtual ~InternalSchemaStrLengthMatchExpression() {}
- Status init(StringData path, long long strLen) {
- _strLen = strLen;
- return setPath(path);
- }
-
virtual Validator getComparator() const = 0;
bool matchesSingleElement(const BSONElement& elem,
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_unique_items.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_unique_items.cpp
index f35d14eb69b..bce1089077c 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_unique_items.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_unique_items.cpp
@@ -64,8 +64,7 @@ void InternalSchemaUniqueItemsMatchExpression::serialize(BSONObjBuilder* builder
}
std::unique_ptr<MatchExpression> InternalSchemaUniqueItemsMatchExpression::shallowClone() const {
- auto clone = stdx::make_unique<InternalSchemaUniqueItemsMatchExpression>();
- invariantOK(clone->init(path()));
+ auto clone = stdx::make_unique<InternalSchemaUniqueItemsMatchExpression>(path());
if (getTag()) {
clone->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_unique_items.h b/src/mongo/db/matcher/schema/expression_internal_schema_unique_items.h
index f41b9e0ef34..5338d3fbcc6 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_unique_items.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_unique_items.h
@@ -45,12 +45,8 @@ class InternalSchemaUniqueItemsMatchExpression final : public ArrayMatchingMatch
public:
static constexpr StringData kName = "$_internalSchemaUniqueItems"_sd;
- InternalSchemaUniqueItemsMatchExpression()
- : ArrayMatchingMatchExpression(MatchExpression::INTERNAL_SCHEMA_UNIQUE_ITEMS) {}
-
- Status init(StringData path) {
- return setPath(path);
- }
+ explicit InternalSchemaUniqueItemsMatchExpression(StringData path)
+ : ArrayMatchingMatchExpression(MatchExpression::INTERNAL_SCHEMA_UNIQUE_ITEMS, path) {}
size_t numChildren() const final {
return 0;
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_unique_items_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_unique_items_test.cpp
index 5e9d1a119b4..46e3be31d41 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_unique_items_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_unique_items_test.cpp
@@ -36,8 +36,7 @@
namespace mongo {
namespace {
TEST(InternalSchemaUniqueItemsMatchExpression, RejectsNonArrays) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo");
ASSERT_FALSE(uniqueItems.matchesBSON(BSON("foo" << 1)));
ASSERT_FALSE(uniqueItems.matchesBSON(BSON("foo" << BSONObj())));
ASSERT_FALSE(uniqueItems.matchesBSON(BSON("foo"
@@ -45,22 +44,19 @@ TEST(InternalSchemaUniqueItemsMatchExpression, RejectsNonArrays) {
}
TEST(InternalSchemaUniqueItemsMatchExpression, MatchesEmptyArray) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo");
ASSERT_TRUE(uniqueItems.matchesBSON(BSON("foo" << BSONArray())));
}
TEST(InternalSchemaUniqueItemsMatchExpression, MatchesOneElementArray) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo");
ASSERT_TRUE(uniqueItems.matchesBSON(BSON("foo" << BSON_ARRAY(1))));
ASSERT_TRUE(uniqueItems.matchesBSON(BSON("foo" << BSON_ARRAY(BSONObj()))));
ASSERT_TRUE(uniqueItems.matchesBSON(BSON("foo" << BSON_ARRAY(BSON_ARRAY(9 << "bar")))));
}
TEST(InternalSchemaUniqueItemsMatchExpression, MatchesArrayOfUniqueItems) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo");
ASSERT_TRUE(uniqueItems.matchesBSON(fromjson("{foo: [1, 'bar', {}, [], null]}")));
ASSERT_TRUE(uniqueItems.matchesBSON(fromjson("{foo: [{x: 1}, {x: 2}, {x: 2, y: 3}]}")));
ASSERT_TRUE(uniqueItems.matchesBSON(fromjson("{foo: [[1], [1, 2], 1]}")));
@@ -68,8 +64,7 @@ TEST(InternalSchemaUniqueItemsMatchExpression, MatchesArrayOfUniqueItems) {
}
TEST(InternalSchemaUniqueItemsMatchExpression, MatchesNestedArrayOfUniqueItems) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo.bar"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo.bar");
ASSERT_TRUE(uniqueItems.matchesBSON(fromjson("{foo: {bar: [1, 'bar', {}, [], null]}}")));
ASSERT_TRUE(uniqueItems.matchesBSON(fromjson("{foo: {bar: [{x: 1}, {x: 2}, {x: 2, y: 3}]}}")));
ASSERT_TRUE(uniqueItems.matchesBSON(fromjson("{foo: {bar: [[1], [1, 2], 1]}}")));
@@ -77,8 +72,7 @@ TEST(InternalSchemaUniqueItemsMatchExpression, MatchesNestedArrayOfUniqueItems)
}
TEST(InternalSchemaUniqueItemsMatchExpression, RejectsArrayWithDuplicates) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo");
ASSERT_FALSE(uniqueItems.matchesBSON(fromjson("{foo: [1, 1, 1]}")));
ASSERT_FALSE(uniqueItems.matchesBSON(fromjson("{foo: [['bar'], ['bar']]}")));
ASSERT_FALSE(
@@ -86,8 +80,7 @@ TEST(InternalSchemaUniqueItemsMatchExpression, RejectsArrayWithDuplicates) {
}
TEST(InternalSchemaUniqueItemsMatchExpression, RejectsNestedArrayWithDuplicates) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo");
ASSERT_FALSE(uniqueItems.matchesBSON(fromjson("{foo: {bar: [1, 1, 1]}}")));
ASSERT_FALSE(uniqueItems.matchesBSON(fromjson("{foo: {bar: [['baz'], ['baz']]}}")));
ASSERT_FALSE(uniqueItems.matchesBSON(
@@ -95,8 +88,7 @@ TEST(InternalSchemaUniqueItemsMatchExpression, RejectsNestedArrayWithDuplicates)
}
TEST(InternalSchemaUniqueItemsMatchExpression, FieldNameSignificantWhenComparingNestedObjects) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo");
ASSERT_TRUE(uniqueItems.matchesBSON(fromjson("{foo: [{x: 7}, {y: 7}]}")));
ASSERT_TRUE(uniqueItems.matchesBSON(fromjson("{foo: [{a: 'bar'}, {b: 'bar'}]}")));
ASSERT_FALSE(uniqueItems.matchesBSON(fromjson("{foo: [{a: 'bar'}, {a: 'bar'}]}")));
@@ -104,8 +96,7 @@ TEST(InternalSchemaUniqueItemsMatchExpression, FieldNameSignificantWhenComparing
}
TEST(InternalSchemaUniqueItemsMatchExpression, AlwaysUsesBinaryComparisonRegardlessOfCollator) {
- InternalSchemaUniqueItemsMatchExpression uniqueItems;
- ASSERT_OK(uniqueItems.init("foo"));
+ InternalSchemaUniqueItemsMatchExpression uniqueItems("foo");
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
uniqueItems.setCollator(&collator);
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_xor_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_xor_test.cpp
index 60d7e4d90e8..0a982bfdba1 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_xor_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_xor_test.cpp
@@ -99,10 +99,8 @@ TEST(InternalSchemaXorOp, DoesNotUseElemMatchKey) {
TEST(InternalSchemaXorOp, Equivalent) {
BSONObj baseOperand1 = BSON("a" << 1);
BSONObj baseOperand2 = BSON("b" << 2);
- EqualityMatchExpression sub1;
- ASSERT(sub1.init("a", baseOperand1["a"]).isOK());
- EqualityMatchExpression sub2;
- ASSERT(sub2.init("b", baseOperand2["b"]).isOK());
+ EqualityMatchExpression sub1("a", baseOperand1["a"]);
+ EqualityMatchExpression sub2("b", baseOperand2["b"]);
InternalSchemaXorMatchExpression e1;
e1.add(sub1.shallowClone().release());
diff --git a/src/mongo/db/matcher/schema/json_schema_parser.cpp b/src/mongo/db/matcher/schema/json_schema_parser.cpp
index 8c107f0b759..fc1eedcc612 100644
--- a/src/mongo/db/matcher/schema/json_schema_parser.cpp
+++ b/src/mongo/db/matcher/schema/json_schema_parser.cpp
@@ -160,11 +160,9 @@ std::unique_ptr<MatchExpression> makeRestriction(const MatcherTypeSet& restricti
//
// We need to do this because restriction keywords do not apply when a field is either not
// present or of a different type.
- auto typeExpr = stdx::make_unique<InternalSchemaTypeExpression>();
- invariantOK(typeExpr->init(path, restrictionType));
+ auto typeExpr = stdx::make_unique<InternalSchemaTypeExpression>(path, restrictionType);
- auto notExpr = stdx::make_unique<NotMatchExpression>();
- invariantOK(notExpr->init(typeExpr.release()));
+ auto notExpr = stdx::make_unique<NotMatchExpression>(typeExpr.release());
auto orExpr = stdx::make_unique<OrMatchExpression>();
orExpr->add(notExpr.release());
@@ -228,11 +226,8 @@ StatusWith<std::unique_ptr<InternalSchemaTypeExpression>> parseType(
<< "' must name at least one type")};
}
- auto typeExpr = stdx::make_unique<InternalSchemaTypeExpression>();
- auto initStatus = typeExpr->init(path, std::move(typeSet.getValue()));
- if (!initStatus.isOK()) {
- return initStatus;
- }
+ auto typeExpr =
+ stdx::make_unique<InternalSchemaTypeExpression>(path, std::move(typeSet.getValue()));
return {std::move(typeExpr)};
}
@@ -254,13 +249,9 @@ StatusWithMatchExpression parseMaximum(StringData path,
std::unique_ptr<ComparisonMatchExpression> expr;
if (isExclusiveMaximum) {
- expr = stdx::make_unique<LTMatchExpression>();
+ expr = stdx::make_unique<LTMatchExpression>(path, maximum);
} else {
- expr = stdx::make_unique<LTEMatchExpression>();
- }
- auto status = expr->init(path, maximum);
- if (!status.isOK()) {
- return status;
+ expr = stdx::make_unique<LTEMatchExpression>(path, maximum);
}
MatcherTypeSet restrictionType;
@@ -285,13 +276,9 @@ StatusWithMatchExpression parseMinimum(StringData path,
std::unique_ptr<ComparisonMatchExpression> expr;
if (isExclusiveMinimum) {
- expr = stdx::make_unique<GTMatchExpression>();
+ expr = stdx::make_unique<GTMatchExpression>(path, minimum);
} else {
- expr = stdx::make_unique<GTEMatchExpression>();
- }
- auto status = expr->init(path, minimum);
- if (!status.isOK()) {
- return status;
+ expr = stdx::make_unique<GTEMatchExpression>(path, minimum);
}
MatcherTypeSet restrictionType;
@@ -316,11 +303,7 @@ StatusWithMatchExpression parseLength(StringData path,
return {stdx::make_unique<AlwaysTrueMatchExpression>()};
}
- auto expr = stdx::make_unique<T>();
- auto status = expr->init(path, parsedLength.getValue());
- if (!status.isOK()) {
- return status;
- }
+ auto expr = stdx::make_unique<T>(path, parsedLength.getValue());
return makeRestriction(restrictionType, path, std::move(expr), typeExpr);
}
@@ -337,14 +320,11 @@ StatusWithMatchExpression parsePattern(StringData path,
return {stdx::make_unique<AlwaysTrueMatchExpression>()};
}
- auto expr = stdx::make_unique<RegexMatchExpression>();
-
// JSON Schema does not allow regex flags to be specified.
constexpr auto emptyFlags = "";
- auto status = expr->init(path, pattern.valueStringData(), emptyFlags);
- if (!status.isOK()) {
- return status;
- }
+ auto expr =
+ stdx::make_unique<RegexMatchExpression>(path, pattern.valueStringData(), emptyFlags);
+
return makeRestriction(BSONType::String, path, std::move(expr), typeExpr);
}
@@ -366,11 +346,8 @@ StatusWithMatchExpression parseMultipleOf(StringData path,
return {stdx::make_unique<AlwaysTrueMatchExpression>()};
}
- auto expr = stdx::make_unique<InternalSchemaFmodMatchExpression>();
- auto status = expr->init(path, multipleOf.numberDecimal(), Decimal128(0));
- if (!status.isOK()) {
- return status;
- }
+ auto expr = stdx::make_unique<InternalSchemaFmodMatchExpression>(
+ path, multipleOf.numberDecimal(), Decimal128(0));
MatcherTypeSet restrictionType;
restrictionType.allNumbers = true;
@@ -445,16 +422,12 @@ StatusWithMatchExpression parseEnum(StringData path, BSONElement enumElement) {
// Top-level non-object enum values can be safely ignored, since MongoDB only stores
// objects, not scalars or arrays.
if (arrayElem.type() == BSONType::Object) {
- auto rootDocEq = stdx::make_unique<InternalSchemaRootDocEqMatchExpression>();
- rootDocEq->init(arrayElem.embeddedObject());
+ auto rootDocEq = stdx::make_unique<InternalSchemaRootDocEqMatchExpression>(
+ arrayElem.embeddedObject());
orExpr->add(rootDocEq.release());
}
} else {
- auto eqExpr = stdx::make_unique<InternalSchemaEqMatchExpression>();
- auto initStatus = eqExpr->init(path, arrayElem);
- if (!initStatus.isOK()) {
- return initStatus;
- }
+ auto eqExpr = stdx::make_unique<InternalSchemaEqMatchExpression>(path, arrayElem);
orExpr->add(eqExpr.release());
}
@@ -520,17 +493,13 @@ StatusWithMatchExpression translateRequired(
auto andExpr = stdx::make_unique<AndMatchExpression>();
for (auto&& propertyName : requiredProperties) {
- auto existsExpr = stdx::make_unique<ExistsMatchExpression>();
- invariantOK(existsExpr->init(propertyName));
+ auto existsExpr = stdx::make_unique<ExistsMatchExpression>(propertyName);
if (path.empty()) {
andExpr->add(existsExpr.release());
} else {
- auto objectMatch = stdx::make_unique<InternalSchemaObjectMatchExpression>();
- auto objectMatchStatus = objectMatch->init(std::move(existsExpr), path);
- if (!objectMatchStatus.isOK()) {
- return objectMatchStatus;
- }
+ auto objectMatch =
+ stdx::make_unique<InternalSchemaObjectMatchExpression>(path, std::move(existsExpr));
andExpr->add(objectMatch.release());
}
@@ -580,11 +549,10 @@ StatusWithMatchExpression parseProperties(
} else {
// This property either must not exist or must match the nested schema. Therefore, we
// generate the match expression (OR (NOT (EXISTS)) <nestedSchemaMatch>).
- auto existsExpr = stdx::make_unique<ExistsMatchExpression>();
- invariantOK(existsExpr->init(property.fieldNameStringData()));
+ auto existsExpr =
+ stdx::make_unique<ExistsMatchExpression>(property.fieldNameStringData());
- auto notExpr = stdx::make_unique<NotMatchExpression>();
- invariantOK(notExpr->init(existsExpr.release()));
+ auto notExpr = stdx::make_unique<NotMatchExpression>(existsExpr.release());
auto orExpr = stdx::make_unique<OrMatchExpression>();
orExpr->add(notExpr.release());
@@ -600,11 +568,8 @@ StatusWithMatchExpression parseProperties(
return {std::move(andExpr)};
}
- auto objectMatch = stdx::make_unique<InternalSchemaObjectMatchExpression>();
- auto objectMatchStatus = objectMatch->init(std::move(andExpr), path);
- if (!objectMatchStatus.isOK()) {
- return objectMatchStatus;
- }
+ auto objectMatch =
+ stdx::make_unique<InternalSchemaObjectMatchExpression>(path, std::move(andExpr));
return makeRestriction(BSONType::Object, path, std::move(objectMatch), typeExpr);
}
@@ -717,15 +682,11 @@ StatusWithMatchExpression parseAllowedProperties(StringData path,
auto otherwiseWithPlaceholder = stdx::make_unique<ExpressionWithPlaceholder>(
kNamePlaceholder.toString(), std::move(otherwiseExpr.getValue()));
- auto allowedPropertiesExpr =
- stdx::make_unique<InternalSchemaAllowedPropertiesMatchExpression>();
- auto status = allowedPropertiesExpr->init(std::move(propertyNames),
- kNamePlaceholder,
- std::move(patternProperties.getValue()),
- std::move(otherwiseWithPlaceholder));
- if (!status.isOK()) {
- return status;
- }
+ auto allowedPropertiesExpr = stdx::make_unique<InternalSchemaAllowedPropertiesMatchExpression>(
+ std::move(propertyNames),
+ kNamePlaceholder,
+ std::move(patternProperties.getValue()),
+ std::move(otherwiseWithPlaceholder));
// If this is a top-level schema, then we have no path and there is no need for an explicit
// object match node.
@@ -733,11 +694,8 @@ StatusWithMatchExpression parseAllowedProperties(StringData path,
return {std::move(allowedPropertiesExpr)};
}
- auto objectMatch = stdx::make_unique<InternalSchemaObjectMatchExpression>();
- auto objectMatchStatus = objectMatch->init(std::move(allowedPropertiesExpr), path);
- if (!objectMatchStatus.isOK()) {
- return objectMatchStatus;
- }
+ auto objectMatch = stdx::make_unique<InternalSchemaObjectMatchExpression>(
+ path, std::move(allowedPropertiesExpr));
return makeRestriction(BSONType::Object, path, std::move(objectMatch), typeExpr);
}
@@ -755,39 +713,28 @@ StatusWithMatchExpression parseNumProperties(StringData path,
return parsedNumProps.getStatus();
}
- auto expr = stdx::make_unique<T>();
- auto status = expr->init(parsedNumProps.getValue());
- if (!status.isOK()) {
- return status;
- }
+ auto expr = stdx::make_unique<T>(parsedNumProps.getValue());
if (path.empty()) {
// This is a top-level schema.
return {std::move(expr)};
}
- auto objectMatch = stdx::make_unique<InternalSchemaObjectMatchExpression>();
- auto objectMatchStatus = objectMatch->init(std::move(expr), path);
- if (!objectMatchStatus.isOK()) {
- return objectMatchStatus;
- }
+ auto objectMatch =
+ stdx::make_unique<InternalSchemaObjectMatchExpression>(path, std::move(expr));
return makeRestriction(BSONType::Object, path, std::move(objectMatch), typeExpr);
}
StatusWithMatchExpression makeDependencyExistsClause(StringData path, StringData dependencyName) {
- auto existsExpr = stdx::make_unique<ExistsMatchExpression>();
- invariantOK(existsExpr->init(dependencyName));
+ auto existsExpr = stdx::make_unique<ExistsMatchExpression>(dependencyName);
if (path.empty()) {
return {std::move(existsExpr)};
}
- auto objectMatch = stdx::make_unique<InternalSchemaObjectMatchExpression>();
- auto status = objectMatch->init(std::move(existsExpr), path);
- if (!status.isOK()) {
- return status;
- }
+ auto objectMatch =
+ stdx::make_unique<InternalSchemaObjectMatchExpression>(path, std::move(existsExpr));
return {std::move(objectMatch)};
}
@@ -807,10 +754,12 @@ StatusWithMatchExpression translateSchemaDependency(StringData path,
return ifClause.getStatus();
}
- auto condExpr = stdx::make_unique<InternalSchemaCondMatchExpression>();
- condExpr->init({std::move(ifClause.getValue()),
- std::move(nestedSchemaMatch.getValue()),
- stdx::make_unique<AlwaysTrueMatchExpression>()});
+ std::array<std::unique_ptr<MatchExpression>, 3> expressions = {
+ std::move(ifClause.getValue()),
+ std::move(nestedSchemaMatch.getValue()),
+ stdx::make_unique<AlwaysTrueMatchExpression>()};
+
+ auto condExpr = stdx::make_unique<InternalSchemaCondMatchExpression>(std::move(expressions));
return {std::move(condExpr)};
}
@@ -861,10 +810,12 @@ StatusWithMatchExpression translatePropertyDependency(StringData path, BSONEleme
return ifClause.getStatus();
}
- auto condExpr = stdx::make_unique<InternalSchemaCondMatchExpression>();
- condExpr->init({std::move(ifClause.getValue()),
- std::move(propertyDependencyExpr),
- stdx::make_unique<AlwaysTrueMatchExpression>()});
+ std::array<std::unique_ptr<MatchExpression>, 3> expressions = {
+ {std::move(ifClause.getValue()),
+ std::move(propertyDependencyExpr),
+ stdx::make_unique<AlwaysTrueMatchExpression>()}};
+
+ auto condExpr = stdx::make_unique<InternalSchemaCondMatchExpression>(std::move(expressions));
return {std::move(condExpr)};
}
@@ -910,11 +861,7 @@ StatusWithMatchExpression parseUniqueItems(BSONElement uniqueItemsElt,
} else if (path.empty()) {
return {stdx::make_unique<AlwaysTrueMatchExpression>()};
} else if (uniqueItemsElt.boolean()) {
- auto uniqueItemsExpr = stdx::make_unique<InternalSchemaUniqueItemsMatchExpression>();
- auto status = uniqueItemsExpr->init(path);
- if (!status.isOK()) {
- return status;
- }
+ auto uniqueItemsExpr = stdx::make_unique<InternalSchemaUniqueItemsMatchExpression>(path);
return makeRestriction(BSONType::Array, path, std::move(uniqueItemsExpr), typeExpr);
}
@@ -954,9 +901,8 @@ StatusWith<boost::optional<long long>> parseItems(StringData path,
}
auto exprWithPlaceholder = stdx::make_unique<ExpressionWithPlaceholder>(
kNamePlaceholder.toString(), std::move(parsedSubschema.getValue()));
- auto matchArrayIndex =
- stdx::make_unique<InternalSchemaMatchArrayIndexMatchExpression>();
- invariantOK(matchArrayIndex->init(path, index, std::move(exprWithPlaceholder)));
+ auto matchArrayIndex = stdx::make_unique<InternalSchemaMatchArrayIndexMatchExpression>(
+ path, index, std::move(exprWithPlaceholder));
andExprForSubschemas->add(matchArrayIndex.release());
++index;
}
@@ -984,11 +930,10 @@ StatusWith<boost::optional<long long>> parseItems(StringData path,
if (path.empty()) {
andExpr->add(stdx::make_unique<AlwaysTrueMatchExpression>().release());
} else {
- auto allElemMatch =
- stdx::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>();
constexpr auto startIndexForItems = 0LL;
- invariantOK(
- allElemMatch->init(path, startIndexForItems, std::move(exprWithPlaceholder)));
+ auto allElemMatch =
+ stdx::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>(
+ path, startIndexForItems, std::move(exprWithPlaceholder));
andExpr->add(makeRestriction(BSONType::Array, path, std::move(allElemMatch), typeExpr)
.release());
}
@@ -1039,9 +984,8 @@ Status parseAdditionalItems(StringData path,
andExpr->add(stdx::make_unique<AlwaysTrueMatchExpression>().release());
} else {
auto allElemMatch =
- stdx::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>();
- invariantOK(
- allElemMatch->init(path, *startIndexForAdditionalItems, std::move(otherwiseExpr)));
+ stdx::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>(
+ path, *startIndexForAdditionalItems, std::move(otherwiseExpr));
andExpr->add(makeRestriction(BSONType::Array, path, std::move(allElemMatch), typeExpr)
.release());
}
@@ -1129,11 +1073,7 @@ Status translateLogicalKeywords(StringMap<BSONElement>* keywordMap,
return parsedExpr.getStatus();
}
- auto notMatchExpr = stdx::make_unique<NotMatchExpression>();
- auto initStatus = notMatchExpr->init(parsedExpr.getValue().release());
- if (!initStatus.isOK()) {
- return initStatus;
- }
+ auto notMatchExpr = stdx::make_unique<NotMatchExpression>(parsedExpr.getValue().release());
andExpr->add(notMatchExpr.release());
}
@@ -1556,11 +1496,14 @@ constexpr StringData JSONSchemaParser::kSchemaTypeString;
StatusWithMatchExpression JSONSchemaParser::parse(BSONObj schema, bool ignoreUnknownKeywords) {
LOG(5) << "Parsing JSON Schema: " << schema.jsonString();
-
- auto translation = _parse(""_sd, schema, ignoreUnknownKeywords);
- if (shouldLog(logger::LogSeverity::Debug(5)) && translation.isOK()) {
- LOG(5) << "Translated schema match expression: " << translation.getValue()->toString();
+ try {
+ auto translation = _parse(""_sd, schema, ignoreUnknownKeywords);
+ if (shouldLog(logger::LogSeverity::Debug(5)) && translation.isOK()) {
+ LOG(5) << "Translated schema match expression: " << translation.getValue()->toString();
+ }
+ return translation;
+ } catch (const DBException& ex) {
+ return {ex.toStatus()};
}
- return translation;
}
} // namespace mongo
diff --git a/src/mongo/db/pipeline/document_source_match.cpp b/src/mongo/db/pipeline/document_source_match.cpp
index 358775136cd..9d3b6365266 100644
--- a/src/mongo/db/pipeline/document_source_match.cpp
+++ b/src/mongo/db/pipeline/document_source_match.cpp
@@ -447,10 +447,10 @@ boost::intrusive_ptr<DocumentSourceMatch> DocumentSourceMatch::descendMatchOnPat
if (node->getCategory() == MatchExpression::MatchCategory::kLeaf &&
node->matchType() != MatchExpression::TYPE_OPERATOR) {
auto leafNode = static_cast<LeafMatchExpression*>(node);
- leafNode->setPath(newPath).transitional_ignore();
+ leafNode->setPath(newPath);
} else if (node->getCategory() == MatchExpression::MatchCategory::kArrayMatching) {
auto arrayNode = static_cast<ArrayMatchingMatchExpression*>(node);
- arrayNode->setPath(newPath).transitional_ignore();
+ arrayNode->setPath(newPath);
}
});
diff --git a/src/mongo/db/query/planner_analysis_test.cpp b/src/mongo/db/query/planner_analysis_test.cpp
index 783438a482c..23d794fd41c 100644
--- a/src/mongo/db/query/planner_analysis_test.cpp
+++ b/src/mongo/db/query/planner_analysis_test.cpp
@@ -177,10 +177,10 @@ TEST(QueryPlannerAnalysis, GeoSkipValidation) {
QueryPlannerParams params;
std::unique_ptr<FetchNode> fetchNodePtr = stdx::make_unique<FetchNode>();
- std::unique_ptr<GeoMatchExpression> exprPtr = stdx::make_unique<GeoMatchExpression>();
+ std::unique_ptr<GeoMatchExpression> exprPtr =
+ stdx::make_unique<GeoMatchExpression>("geometry.field", nullptr, BSONObj());
GeoMatchExpression* expr = exprPtr.get();
- expr->init("geometry.field", nullptr, BSONObj()).transitional_ignore();
FetchNode* fetchNode = fetchNodePtr.get();
// Takes ownership.
diff --git a/src/mongo/dbtests/extensions_callback_real_test.cpp b/src/mongo/dbtests/extensions_callback_real_test.cpp
index 7ea4e6a4af0..2e342f06645 100644
--- a/src/mongo/dbtests/extensions_callback_real_test.cpp
+++ b/src/mongo/dbtests/extensions_callback_real_test.cpp
@@ -79,11 +79,10 @@ protected:
TEST_F(ExtensionsCallbackRealTest, TextNoIndex) {
BSONObj query = fromjson("{$text: {$search:\"awesome\"}}");
- StatusWithMatchExpression result =
- ExtensionsCallbackReal(&_opCtx, &_nss).parseText(query.firstElement());
-
- ASSERT_NOT_OK(result.getStatus());
- ASSERT_EQ(ErrorCodes::IndexNotFound, result.getStatus());
+ ASSERT_THROWS_CODE(StatusWithMatchExpression result(
+ ExtensionsCallbackReal(&_opCtx, &_nss).parseText(query.firstElement())),
+ AssertionException,
+ ErrorCodes::IndexNotFound);
}
TEST_F(ExtensionsCallbackRealTest, TextBasic) {
@@ -116,10 +115,10 @@ TEST_F(ExtensionsCallbackRealTest, TextLanguageError) {
false)); // isUnique
BSONObj query = fromjson("{$text: {$search:\"awesome\", $language:\"spanglish\"}}");
- StatusWithMatchExpression result =
- ExtensionsCallbackReal(&_opCtx, &_nss).parseText(query.firstElement());
-
- ASSERT_NOT_OK(result.getStatus());
+ ASSERT_THROWS_CODE(StatusWithMatchExpression result(
+ ExtensionsCallbackReal(&_opCtx, &_nss).parseText(query.firstElement())),
+ AssertionException,
+ ErrorCodes::BadValue);
}
TEST_F(ExtensionsCallbackRealTest, TextCaseSensitiveTrue) {
diff --git a/src/mongo/s/shard_key_pattern.cpp b/src/mongo/s/shard_key_pattern.cpp
index 549e753ea65..409bc54ec83 100644
--- a/src/mongo/s/shard_key_pattern.cpp
+++ b/src/mongo/s/shard_key_pattern.cpp
@@ -209,7 +209,7 @@ BSONObj ShardKeyPattern::normalizeShardKey(const BSONObj& shardKey) const {
static BSONElement extractKeyElementFromMatchable(const MatchableDocument& matchable,
StringData pathStr) {
ElementPath path;
- path.init(pathStr).transitional_ignore();
+ path.init(pathStr);
path.setTraverseNonleafArrays(false);
path.setTraverseLeafArray(false);