summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTess Avitabile <tess.avitabile@mongodb.com>2017-09-05 17:34:32 -0400
committerTess Avitabile <tess.avitabile@mongodb.com>2017-09-06 14:26:51 -0400
commit7dbfca42c49e27bc2d2b40e92d128fd0239041f7 (patch)
tree8eb0c4cfe1bceafcd48b38e3cb98b4586553e74d /src
parented601dd01169b8c1fad9fb8d388da0523a1b48f5 (diff)
downloadmongo-7dbfca42c49e27bc2d2b40e92d128fd0239041f7.tar.gz
SERVER-30954 Remove support for expr constant expressions from ComparisonMatchExpression
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/matcher/expression_leaf.cpp59
-rw-r--r--src/mongo/db/matcher/expression_leaf.h32
-rw-r--r--src/mongo/db/matcher/expression_leaf_test.cpp127
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp108
-rw-r--r--src/mongo/db/matcher/expression_parser.h34
-rw-r--r--src/mongo/db/matcher/expression_parser_geo_test.cpp17
-rw-r--r--src/mongo/db/matcher/expression_parser_leaf_test.cpp459
-rw-r--r--src/mongo/db/matcher/expression_parser_test.cpp3
-rw-r--r--src/mongo/db/matcher/expression_parser_tree.cpp2
-rw-r--r--src/mongo/db/matcher/expression_with_placeholder_test.cpp3
-rw-r--r--src/mongo/db/ops/modifier_pull_test.cpp3
-rw-r--r--src/mongo/db/query/parsed_projection_test.cpp3
-rw-r--r--src/mongo/db/update/pull_node_test.cpp3
-rw-r--r--src/mongo/dbtests/extensions_callback_real_test.cpp9
14 files changed, 86 insertions, 776 deletions
diff --git a/src/mongo/db/matcher/expression_leaf.cpp b/src/mongo/db/matcher/expression_leaf.cpp
index 7ba272ea224..f3d00d40e01 100644
--- a/src/mongo/db/matcher/expression_leaf.cpp
+++ b/src/mongo/db/matcher/expression_leaf.cpp
@@ -59,15 +59,15 @@ bool ComparisonMatchExpression::equivalent(const MatchExpression* other) const {
const StringData::ComparatorInterface* stringComparator = nullptr;
BSONElementComparator eltCmp(BSONElementComparator::FieldNamesMode::kIgnore, stringComparator);
- return path() == realOther->path() && eltCmp.evaluate(_rhsElem == realOther->_rhsElem);
+ return path() == realOther->path() && eltCmp.evaluate(_rhs == realOther->_rhs);
}
-Status ComparisonMatchExpression::_validate() {
- if (!_rhsElem) {
- return Status(ErrorCodes::BadValue, "need a real operand");
- }
+Status ComparisonMatchExpression::init(StringData path, const BSONElement& rhs) {
+ _rhs = rhs;
+
+ invariant(_rhs);
- if (_rhsElem.type() == BSONType::Undefined) {
+ if (_rhs.type() == BSONType::Undefined) {
return Status(ErrorCodes::BadValue, "cannot compare to undefined");
}
@@ -82,50 +82,19 @@ Status ComparisonMatchExpression::_validate() {
return Status(ErrorCodes::BadValue, "bad match type for ComparisonMatchExpression");
}
- return Status::OK();
-}
-
-Status ComparisonMatchExpression::init(StringData path,
- const boost::intrusive_ptr<Expression>& rhsExpr) {
- auto exprConstant = dynamic_cast<ExpressionConstant*>(rhsExpr.get());
- if (exprConstant) {
- BSONObjBuilder bob;
- bob << path << exprConstant->getValue();
- _resolvedRhsExpr = bob.obj();
- _rhsElem = _resolvedRhsExpr.firstElement();
- } else {
- return Status(ErrorCodes::BadValue, "$expr does not yet handle non-constant expressions");
- }
-
- auto status = _validate();
- if (!status.isOK()) {
- return status;
- }
-
- return setPath(path);
-}
-
-Status ComparisonMatchExpression::init(StringData path, const BSONElement& rhs) {
- _rhsElem = rhs;
-
- auto status = _validate();
- if (!status.isOK()) {
- return status;
- }
-
return setPath(path);
}
bool ComparisonMatchExpression::matchesSingleElement(const BSONElement& e,
MatchDetails* details) const {
- if (e.canonicalType() != _rhsElem.canonicalType()) {
+ if (e.canonicalType() != _rhs.canonicalType()) {
// some special cases
// jstNULL and undefined are treated the same
- if (e.canonicalType() + _rhsElem.canonicalType() == 5) {
+ if (e.canonicalType() + _rhs.canonicalType() == 5) {
return matchType() == EQ || matchType() == LTE || matchType() == GTE;
}
- if (_rhsElem.type() == MaxKey || _rhsElem.type() == MinKey) {
+ if (_rhs.type() == MaxKey || _rhs.type() == MinKey) {
return matchType() != EQ;
}
return false;
@@ -133,8 +102,8 @@ bool ComparisonMatchExpression::matchesSingleElement(const BSONElement& e,
// Special case handling for NaN. NaN is equal to NaN but
// otherwise always compares to false.
- if (std::isnan(e.numberDouble()) || std::isnan(_rhsElem.numberDouble())) {
- bool bothNaN = std::isnan(e.numberDouble()) && std::isnan(_rhsElem.numberDouble());
+ if (std::isnan(e.numberDouble()) || std::isnan(_rhs.numberDouble())) {
+ bool bothNaN = std::isnan(e.numberDouble()) && std::isnan(_rhs.numberDouble());
switch (matchType()) {
case LT:
return false;
@@ -153,7 +122,7 @@ bool ComparisonMatchExpression::matchesSingleElement(const BSONElement& e,
}
}
- int x = compareElementValues(e, _rhsElem, _collator);
+ int x = compareElementValues(e, _rhs, _collator);
switch (matchType()) {
case LT:
@@ -195,7 +164,7 @@ void ComparisonMatchExpression::debugString(StringBuilder& debug, int level) con
default:
invariant(false);
}
- debug << " " << _rhsElem.toString(false);
+ debug << " " << _rhs.toString(false);
MatchExpression::TagData* td = getTag();
if (NULL != td) {
@@ -228,7 +197,7 @@ void ComparisonMatchExpression::serialize(BSONObjBuilder* out) const {
invariant(false);
}
- out->append(path(), BSON(opString << _rhsElem));
+ out->append(path(), BSON(opString << _rhs));
}
// ---------------
diff --git a/src/mongo/db/matcher/expression_leaf.h b/src/mongo/db/matcher/expression_leaf.h
index 75c6421ddd6..eb573debe5c 100644
--- a/src/mongo/db/matcher/expression_leaf.h
+++ b/src/mongo/db/matcher/expression_leaf.h
@@ -33,7 +33,6 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_path.h"
-#include "mongo/db/pipeline/expression.h"
#include "mongo/db/query/collation/collator_interface.h"
#include "mongo/stdx/memory.h"
#include "mongo/stdx/unordered_map.h"
@@ -69,7 +68,6 @@ public:
explicit ComparisonMatchExpression(MatchType type) : LeafMatchExpression(type) {}
Status init(StringData path, const BSONElement& rhs);
- Status init(StringData path, const boost::intrusive_ptr<Expression>& rhsExpr);
virtual ~ComparisonMatchExpression() {}
@@ -77,19 +75,12 @@ public:
virtual void debugString(StringBuilder& debug, int level = 0) const;
- /**
- * 'collator' must outlive the ComparisonMatchExpression and any clones made of it.
- */
- virtual void _doSetCollator(const CollatorInterface* collator) {
- _collator = collator;
- }
-
virtual void serialize(BSONObjBuilder* out) const;
virtual bool equivalent(const MatchExpression* other) const;
const BSONElement& getData() const {
- return _rhsElem;
+ return _rhs;
}
const CollatorInterface* getCollator() const {
@@ -113,11 +104,14 @@ public:
}
protected:
- Status _validate();
-
- BSONElement _rhsElem;
+ /**
+ * 'collator' must outlive the ComparisonMatchExpression and any clones made of it.
+ */
+ virtual void _doSetCollator(const CollatorInterface* collator) {
+ _collator = collator;
+ }
- BSONObj _resolvedRhsExpr;
+ BSONElement _rhs;
// Collator used to compare elements. By default, simple binary comparison will be used.
const CollatorInterface* _collator = nullptr;
@@ -128,7 +122,7 @@ public:
EqualityMatchExpression() : ComparisonMatchExpression(EQ) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<EqualityMatchExpression>();
- invariantOK(e->init(path(), _rhsElem));
+ invariantOK(e->init(path(), _rhs));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -142,7 +136,7 @@ public:
LTEMatchExpression() : ComparisonMatchExpression(LTE) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<LTEMatchExpression>();
- invariantOK(e->init(path(), _rhsElem));
+ invariantOK(e->init(path(), _rhs));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -156,7 +150,7 @@ public:
LTMatchExpression() : ComparisonMatchExpression(LT) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<LTMatchExpression>();
- invariantOK(e->init(path(), _rhsElem));
+ invariantOK(e->init(path(), _rhs));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -170,7 +164,7 @@ public:
GTMatchExpression() : ComparisonMatchExpression(GT) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<GTMatchExpression>();
- invariantOK(e->init(path(), _rhsElem));
+ invariantOK(e->init(path(), _rhs));
if (getTag()) {
e->setTag(getTag()->clone());
}
@@ -184,7 +178,7 @@ public:
GTEMatchExpression() : ComparisonMatchExpression(GTE) {}
virtual std::unique_ptr<MatchExpression> shallowClone() const {
std::unique_ptr<ComparisonMatchExpression> e = stdx::make_unique<GTEMatchExpression>();
- invariantOK(e->init(path(), _rhsElem));
+ invariantOK(e->init(path(), _rhs));
if (getTag()) {
e->setTag(getTag()->clone());
}
diff --git a/src/mongo/db/matcher/expression_leaf_test.cpp b/src/mongo/db/matcher/expression_leaf_test.cpp
index eddc44b9e0b..f49c586641a 100644
--- a/src/mongo/db/matcher/expression_leaf_test.cpp
+++ b/src/mongo/db/matcher/expression_leaf_test.cpp
@@ -35,8 +35,8 @@
#include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/expression_parser.h"
-#include "mongo/db/pipeline/aggregation_context_fixture.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
+#include "mongo/unittest/death_test.h"
namespace mongo {
@@ -97,31 +97,10 @@ TEST(EqOp, MatchesElement) {
ASSERT(eq.equivalent(&eq));
}
-TEST(EqOp, ConstantAggExprMatchesElement) {
- BSONObj operand = BSON("a" << BSON("$expr"
- << "$$userVar"));
- BSONObj match = BSON("a" << 5);
- BSONObj notMatch = BSON("a" << 6);
-
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(5));
- auto expr = Expression::parseOperand(
- expCtx, operand.firstElement()["$expr"], expCtx->variablesParseState);
- expr = expr->optimize();
-
- EqualityMatchExpression eq;
- ASSERT_OK(eq.init("a", expr));
- ASSERT(eq.matchesSingleElement(match.firstElement()));
- ASSERT_FALSE(eq.matchesSingleElement(notMatch.firstElement()));
-
- ASSERT(eq.equivalent(&eq));
-}
-
-TEST(EqOp, InvalidEooOperand) {
+DEATH_TEST(EqOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
EqualityMatchExpression eq;
- ASSERT_FALSE(eq.init("", operand.firstElement()).isOK());
+ eq.init("", operand.firstElement()).ignore();
}
TEST(EqOp, MatchesScalar) {
@@ -339,10 +318,10 @@ TEST(LtOp, MatchesElement) {
ASSERT(!lt.matchesSingleElement(notMatchWrongType.firstElement()));
}
-TEST(LtOp, InvalidEooOperand) {
+DEATH_TEST(LtOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
LTMatchExpression lt;
- ASSERT(!lt.init("", operand.firstElement()).isOK());
+ lt.init("", operand.firstElement()).ignore();
}
TEST(LtOp, MatchesScalar) {
@@ -440,27 +419,6 @@ TEST(LtOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
-TEST(LtOp, ConstantAggExprMatchesElement) {
- BSONObj operand = BSON("a" << BSON("$lt" << BSON("$expr"
- << "$$userVar")));
- BSONObj match = BSON("a" << 5);
- BSONObj notMatch = BSON("a" << 10);
-
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(6));
- auto expr = Expression::parseOperand(
- expCtx, operand.firstElement()["$lt"]["$expr"], expCtx->variablesParseState);
- expr = expr->optimize();
-
- LTMatchExpression lt;
- ASSERT_OK(lt.init("a", expr));
- ASSERT(lt.matchesSingleElement(match.firstElement()));
- ASSERT_FALSE(lt.matchesSingleElement(notMatch.firstElement()));
-
- ASSERT(lt.equivalent(&lt));
-}
-
/**
TEST( LtOp, MatchesIndexKeyScalar ) {
BSONObj operand = BSON( "$lt" << 6 );
@@ -526,31 +484,10 @@ TEST(LteOp, MatchesElement) {
ASSERT(!lte.matchesSingleElement(notMatchWrongType.firstElement()));
}
-TEST(LteOp, ConstantAggExprMatchesElement) {
- BSONObj operand = BSON("a" << BSON("$lte" << BSON("$expr"
- << "$$userVar")));
- BSONObj match = BSON("a" << 5);
- BSONObj notMatch = BSON("a" << 10);
-
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(6));
- auto expr = Expression::parseOperand(
- expCtx, operand.firstElement()["$lte"]["$expr"], expCtx->variablesParseState);
- expr = expr->optimize();
-
- LTEMatchExpression lte;
- ASSERT_OK(lte.init("a", expr));
- ASSERT(lte.matchesSingleElement(match.firstElement()));
- ASSERT_FALSE(lte.matchesSingleElement(notMatch.firstElement()));
-
- ASSERT(lte.equivalent(&lte));
-}
-
-TEST(LteOp, InvalidEooOperand) {
+DEATH_TEST(LteOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
LTEMatchExpression lte;
- ASSERT(!lte.init("", operand.firstElement()).isOK());
+ lte.init("", operand.firstElement()).ignore();
}
TEST(LteOp, MatchesScalar) {
@@ -706,10 +643,10 @@ TEST(LteOp, ElemMatchKey) {
}
*/
-TEST(GtOp, InvalidEooOperand) {
+DEATH_TEST(GtOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
GTMatchExpression gt;
- ASSERT(!gt.init("", operand.firstElement()).isOK());
+ gt.init("", operand.firstElement()).ignore();
}
TEST(GtOp, MatchesScalar) {
@@ -801,27 +738,6 @@ TEST(GtOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
-TEST(GtOp, ConstantAggExprMatchesElement) {
- BSONObj operand = BSON("a" << BSON("$gt" << BSON("$expr"
- << "$$userVar")));
- BSONObj match = BSON("a" << 10);
- BSONObj notMatch = BSON("a" << 0);
-
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(5));
- auto expr = Expression::parseOperand(
- expCtx, operand.firstElement()["$gt"]["$expr"], expCtx->variablesParseState);
- expr = expr->optimize();
-
- GTMatchExpression gt;
- ASSERT_OK(gt.init("a", expr));
- ASSERT(gt.matchesSingleElement(match.firstElement()));
- ASSERT_FALSE(gt.matchesSingleElement(notMatch.firstElement()));
-
- ASSERT(gt.equivalent(&gt));
-}
-
/**
TEST( GtOp, MatchesIndexKeyScalar ) {
BSONObj operand = BSON( "$gt" << 6 );
@@ -888,10 +804,10 @@ TEST(GteOp, MatchesElement) {
ASSERT(!gte.matchesSingleElement(notMatchWrongType.firstElement()));
}
-TEST(GteOp, InvalidEooOperand) {
+DEATH_TEST(GteOp, InvalidEooOperand, "Invariant failure _rhs") {
BSONObj operand;
GTEMatchExpression gte;
- ASSERT(!gte.init("", operand.firstElement()).isOK());
+ gte.init("", operand.firstElement()).ignore();
}
TEST(GteOp, MatchesScalar) {
@@ -982,27 +898,6 @@ TEST(GteOp, ElemMatchKey) {
ASSERT_EQUALS("1", details.elemMatchKey());
}
-TEST(GteOp, ConstantAggExprMatchesElement) {
- BSONObj operand = BSON("a" << BSON("$gte" << BSON("$expr"
- << "$$userVar")));
- BSONObj match = BSON("a" << 10);
- BSONObj notMatch = BSON("a" << 0);
-
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(5));
- auto expr = Expression::parseOperand(
- expCtx, operand.firstElement()["$gte"]["$expr"], expCtx->variablesParseState);
- expr = expr->optimize();
-
- GTEMatchExpression gte;
- ASSERT_OK(gte.init("a", expr));
- ASSERT(gte.matchesSingleElement(match.firstElement()));
- ASSERT_FALSE(gte.matchesSingleElement(notMatch.firstElement()));
-
- ASSERT(gte.equivalent(&gte));
-}
-
TEST(RegexMatchExpression, MatchesElementExact) {
BSONObj match = BSON("a"
<< "b");
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp
index 4f995fbfa4e..2f2263e841e 100644
--- a/src/mongo/db/matcher/expression_parser.cpp
+++ b/src/mongo/db/matcher/expression_parser.cpp
@@ -115,20 +115,9 @@ StatusWithMatchExpression MatchExpressionParser::_parseComparison(
return {Status(ErrorCodes::BadValue, ss)};
}
- if (_isAggExpression(e, expCtx)) {
- auto expr = _parseAggExpression(e, expCtx, allowedFeatures);
- if (!expr.isOK()) {
- return expr.getStatus();
- }
- auto s = temp->init(name, expr.getValue());
- if (!s.isOK()) {
- return s;
- }
- } else {
- auto s = temp->init(name, e);
- if (!s.isOK()) {
- return s;
- }
+ auto s = temp->init(name, e);
+ if (!s.isOK()) {
+ return s;
}
temp->setCollator(collator);
@@ -278,10 +267,10 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(
}
case PathAcceptingKeyword::TYPE:
- return _parseType<TypeMatchExpression>(name, e, expCtx);
+ return _parseType<TypeMatchExpression>(name, e);
case PathAcceptingKeyword::MOD:
- return _parseMOD(name, e, expCtx);
+ return _parseMOD(name, e);
case PathAcceptingKeyword::OPTIONS: {
// TODO: try to optimize this
@@ -299,7 +288,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(
}
case PathAcceptingKeyword::REGEX: {
- return _parseRegexDocument(name, context, expCtx);
+ return _parseRegexDocument(name, context);
}
case PathAcceptingKeyword::ELEM_MATCH:
@@ -319,19 +308,19 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(
// Handles bitwise query operators.
case PathAcceptingKeyword::BITS_ALL_SET: {
- return _parseBitTest<BitsAllSetMatchExpression>(name, e, expCtx);
+ return _parseBitTest<BitsAllSetMatchExpression>(name, e);
}
case PathAcceptingKeyword::BITS_ALL_CLEAR: {
- return _parseBitTest<BitsAllClearMatchExpression>(name, e, expCtx);
+ return _parseBitTest<BitsAllClearMatchExpression>(name, e);
}
case PathAcceptingKeyword::BITS_ANY_SET: {
- return _parseBitTest<BitsAnySetMatchExpression>(name, e, expCtx);
+ return _parseBitTest<BitsAnySetMatchExpression>(name, e);
}
case PathAcceptingKeyword::BITS_ANY_CLEAR: {
- return _parseBitTest<BitsAnyClearMatchExpression>(name, e, expCtx);
+ return _parseBitTest<BitsAnyClearMatchExpression>(name, e);
}
case PathAcceptingKeyword::INTERNAL_SCHEMA_FMOD:
@@ -452,7 +441,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(
}
case PathAcceptingKeyword::INTERNAL_SCHEMA_TYPE: {
- return _parseType<InternalSchemaTypeExpression>(name, e, expCtx);
+ return _parseType<InternalSchemaTypeExpression>(name, e);
}
}
@@ -623,7 +612,7 @@ StatusWithMatchExpression MatchExpressionParser::_parse(
continue;
}
- if (_isExpressionDocument(e, false, expCtx)) {
+ if (_isExpressionDocument(e, false)) {
Status s = _parseSub(e.fieldName(),
e.Obj(),
root.get(),
@@ -637,7 +626,7 @@ StatusWithMatchExpression MatchExpressionParser::_parse(
}
if (e.type() == RegEx) {
- StatusWithMatchExpression result = _parseRegexElement(e.fieldName(), e, expCtx);
+ StatusWithMatchExpression result = _parseRegexElement(e.fieldName(), e);
if (!result.isOK())
return result;
root->add(result.getValue().release());
@@ -712,10 +701,7 @@ Status MatchExpressionParser::_parseSub(const char* name,
return Status::OK();
}
-bool MatchExpressionParser::_isExpressionDocument(
- const BSONElement& e,
- bool allowIncompleteDBRef,
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+bool MatchExpressionParser::_isExpressionDocument(const BSONElement& e, bool allowIncompleteDBRef) {
if (e.type() != Object)
return false;
@@ -731,10 +717,6 @@ bool MatchExpressionParser::_isExpressionDocument(
return false;
}
- if (_isAggExpression(e, expCtx)) {
- return false;
- }
-
return true;
}
@@ -779,8 +761,7 @@ bool MatchExpressionParser::_isDBRefDocument(const BSONObj& obj, bool allowIncom
return hasRef && hasID;
}
-StatusWithMatchExpression MatchExpressionParser::_parseMOD(
- const char* name, const BSONElement& e, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+StatusWithMatchExpression MatchExpressionParser::_parseMOD(const char* name, const BSONElement& e) {
if (e.type() != Array)
return {Status(ErrorCodes::BadValue, "malformed mod, needs to be an array")};
@@ -808,8 +789,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseMOD(
return {std::move(temp)};
}
-StatusWithMatchExpression MatchExpressionParser::_parseRegexElement(
- const char* name, const BSONElement& e, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+StatusWithMatchExpression MatchExpressionParser::_parseRegexElement(const char* name,
+ const BSONElement& e) {
if (e.type() != RegEx)
return {Status(ErrorCodes::BadValue, "not a regex")};
@@ -820,8 +801,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseRegexElement(
return {std::move(temp)};
}
-StatusWithMatchExpression MatchExpressionParser::_parseRegexDocument(
- const char* name, const BSONObj& doc, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+StatusWithMatchExpression MatchExpressionParser::_parseRegexDocument(const char* name,
+ const BSONObj& doc) {
string regex;
string regexOptions;
@@ -874,7 +855,7 @@ Status MatchExpressionParser::_parseInExpression(
BSONElement e = i.next();
// Allow DBRefs, but reject all fields with names starting with $.
- if (_isExpressionDocument(e, false, expCtx)) {
+ if (_isExpressionDocument(e, false)) {
return Status(ErrorCodes::BadValue, "cannot nest $ under $in");
}
@@ -887,10 +868,6 @@ Status MatchExpressionParser::_parseInExpression(
if (!s.isOK())
return s;
} else {
- if (_isAggExpression(e, expCtx)) {
- return Status(ErrorCodes::BadValue, "$expr not supported for $in");
- }
-
equalities.push_back(e);
}
}
@@ -898,10 +875,8 @@ Status MatchExpressionParser::_parseInExpression(
}
template <class T>
-StatusWithMatchExpression MatchExpressionParser::_parseType(
- const char* name,
- const BSONElement& elt,
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+StatusWithMatchExpression MatchExpressionParser::_parseType(const char* name,
+ const BSONElement& elt) {
auto typeSet = MatcherTypeSet::parse(elt, MatcherTypeSet::kTypeAliasMap);
if (!typeSet.isOK()) {
return typeSet.getStatus();
@@ -943,7 +918,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseElemMatch(
// 3) expression is not a WHERE operator. WHERE works on objects instead
// of specific field.
bool isElemMatchValue = false;
- if (_isExpressionDocument(e, true, expCtx)) {
+ if (_isExpressionDocument(e, true)) {
BSONObj o = e.Obj();
BSONElement elt = o.firstElement();
invariant(!elt.eoo());
@@ -1086,8 +1061,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseAll(
}
template <class T>
-StatusWithMatchExpression MatchExpressionParser::_parseBitTest(
- const char* name, const BSONElement& e, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+StatusWithMatchExpression MatchExpressionParser::_parseBitTest(const char* name,
+ const BSONElement& e) {
std::unique_ptr<BitTestMatchExpression> bitTestMatchExpression = stdx::make_unique<T>();
if (e.type() == BSONType::Array) {
@@ -1672,39 +1647,6 @@ StatusWithMatchExpression MatchExpressionParser::_parseGeo(const char* name,
}
}
-bool MatchExpressionParser::_isAggExpression(
- BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx) {
- if (!expCtx) {
- return false;
- }
-
- if (BSONType::Object != elem.type()) {
- return false;
- }
-
- auto obj = elem.embeddedObject();
- if (obj.nFields() != 1) {
- return false;
- }
-
- return obj.firstElementFieldName() == kAggExpression;
-}
-
-StatusWith<boost::intrusive_ptr<Expression>> MatchExpressionParser::_parseAggExpression(
- BSONElement elem,
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- AllowedFeatureSet allowedFeatures) {
- invariant(expCtx);
-
- if ((allowedFeatures & AllowedFeatures::kExpr) == 0u) {
- return {Status(ErrorCodes::BadValue, "$expr is not allowed in this context")};
- }
-
- auto expr = Expression::parseOperand(
- expCtx, elem.embeddedObject().firstElement(), expCtx->variablesParseState);
- return expr->optimize();
-}
-
namespace {
// Maps from query operator string name to operator PathAcceptingKeyword.
std::unique_ptr<StringMap<PathAcceptingKeyword>> queryOperatorMap;
diff --git a/src/mongo/db/matcher/expression_parser.h b/src/mongo/db/matcher/expression_parser.h
index 55ef95ddf4a..dc7b5041517 100644
--- a/src/mongo/db/matcher/expression_parser.h
+++ b/src/mongo/db/matcher/expression_parser.h
@@ -38,6 +38,7 @@
#include "mongo/db/matcher/expression_type.h"
#include "mongo/db/matcher/extensions_callback.h"
#include "mongo/db/matcher/extensions_callback_noop.h"
+#include "mongo/db/pipeline/expression.h"
#include "mongo/db/pipeline/expression_context.h"
#include "mongo/stdx/functional.h"
@@ -170,9 +171,7 @@ private:
* { $id : "x" } = false (if incomplete DBRef is allowed)
* { $db : "mydb" } = false (if incomplete DBRef is allowed)
*/
- bool _isExpressionDocument(const BSONElement& e,
- bool allowIncompleteDBRef,
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ bool _isExpressionDocument(const BSONElement& e, bool allowIncompleteDBRef);
/**
* { $ref: "s", $id: "x" } = true
@@ -232,19 +231,11 @@ private:
const boost::intrusive_ptr<ExpressionContext>& expCtx,
AllowedFeatureSet allowedFeatures);
- StatusWithMatchExpression _parseMOD(const char* name,
- const BSONElement& e,
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ StatusWithMatchExpression _parseMOD(const char* name, const BSONElement& e);
- StatusWithMatchExpression _parseRegexElement(
- const char* name,
- const BSONElement& e,
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ StatusWithMatchExpression _parseRegexElement(const char* name, const BSONElement& e);
- StatusWithMatchExpression _parseRegexDocument(
- const char* name,
- const BSONObj& doc,
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ StatusWithMatchExpression _parseRegexDocument(const char* name, const BSONObj& doc);
Status _parseInExpression(InMatchExpression* entries,
const BSONObj& theArray,
@@ -252,9 +243,7 @@ private:
const boost::intrusive_ptr<ExpressionContext>& expCtx);
template <class T>
- StatusWithMatchExpression _parseType(const char* name,
- const BSONElement& elt,
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ StatusWithMatchExpression _parseType(const char* name, const BSONElement& elt);
StatusWithMatchExpression _parseGeo(const char* name,
PathAcceptingKeyword type,
@@ -297,9 +286,7 @@ private:
* Parses 'e' into a BitTestMatchExpression.
*/
template <class T>
- StatusWithMatchExpression _parseBitTest(const char* name,
- const BSONElement& e,
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ StatusWithMatchExpression _parseBitTest(const char* name, const BSONElement& e);
/**
* Converts 'theArray', a BSONArray of integers, into a std::vector of integers.
@@ -341,13 +328,6 @@ private:
StatusWithMatchExpression _parseInternalSchemaMatchArrayIndex(
const char* path, const BSONElement& elem, const CollatorInterface* collator);
- bool _isAggExpression(BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx);
-
- StatusWith<boost::intrusive_ptr<Expression>> _parseAggExpression(
- BSONElement elem,
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- AllowedFeatureSet allowedFeatures);
-
StatusWithMatchExpression _parseInternalSchemaAllowedProperties(
const BSONElement& elem, const CollatorInterface* collator);
diff --git a/src/mongo/db/matcher/expression_parser_geo_test.cpp b/src/mongo/db/matcher/expression_parser_geo_test.cpp
index b8a17a3ae2f..38ffdafe4da 100644
--- a/src/mongo/db/matcher/expression_parser_geo_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_geo_test.cpp
@@ -59,23 +59,6 @@ TEST(MatchExpressionParserGeo, WithinBox) {
ASSERT(result.getValue()->matchesBSON(fromjson("{a: {x: 5, y:5.1}}")));
}
-TEST(MatchExpressionParserGeo, RejectsExprAsGeometry) {
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(fromjson("{type: 'Point', coordinates:[0,0]}}")));
-
- BSONObj query = fromjson("{a:{$geoIntersects:{$geometry: {$expr: '$$userVar'} }}}");
-
- const CollatorInterface* collator = nullptr;
- StatusWithMatchExpression result =
- MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::kAllowAllSpecialFeatures);
- ASSERT_NOT_OK(result.getStatus());
-}
-
TEST(MatchExpressionParserGeoNear, ParseNear) {
BSONObj query = fromjson(
"{loc:{$near:{$maxDistance:100, "
diff --git a/src/mongo/db/matcher/expression_parser_leaf_test.cpp b/src/mongo/db/matcher/expression_parser_leaf_test.cpp
index 6bf8a68857f..074825045b1 100644
--- a/src/mongo/db/matcher/expression_parser_leaf_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_leaf_test.cpp
@@ -34,7 +34,6 @@
#include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/expression_parser.h"
#include "mongo/db/matcher/extensions_callback_noop.h"
-#include "mongo/db/pipeline/expression_context_for_test.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/platform/decimal128.h"
#include "mongo/unittest/death_test.h"
@@ -68,69 +67,6 @@ TEST(MatchExpressionParserLeafTest, Collation) {
ASSERT_TRUE(match->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, ConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$expr"
- << "$$userVar"));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
-
- ASSERT_OK(result.getStatus());
- ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
-
- auto expr = result.getValue().get();
-
- BSONObj match = BSON("x" << 123);
- BSONObj notMatch = BSON("x" << 321);
-
- ASSERT_TRUE(expr->matchesBSON(match));
- ASSERT_FALSE(expr->matchesBSON(notMatch));
-}
-
-TEST(MatchExpressionParserLeafTest, ConstantExprFailsWithMissingVariable) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$expr"
- << "$$userVar"));
-
- ASSERT_THROWS_CODE(
- auto sw = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr),
- AssertionException,
- 17276);
-}
-
-DEATH_TEST(MatchExpressionParserLeafTest,
- ConstantExprFailsWithMissingExpressionContext,
- "Invariant failure (allowedFeatures & AllowedFeatures::kExpr) == 0u") {
- boost::intrusive_ptr<ExpressionContextForTest> nullExpCtx;
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$expr"
- << "$$userVar"));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- nullExpCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
-
- ASSERT_NOT_OK(result.getStatus());
-}
-
TEST(MatchExpressionParserLeafTest, SimpleEQ2) {
BSONObj query = BSON("x" << BSON("$eq" << 2));
const CollatorInterface* collator = nullptr;
@@ -172,34 +108,6 @@ TEST(MatchExpressionParserLeafTest, EQCollation) {
ASSERT_TRUE(match->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, EQConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$eq" << BSON("$expr"
- << "$$userVar")));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
-
- ASSERT_OK(result.getStatus());
- ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
-
- auto expr = result.getValue().get();
-
- BSONObj match = BSON("x" << 123);
- BSONObj notMatch = BSON("x" << 321);
-
- ASSERT_TRUE(expr->matchesBSON(match));
- ASSERT_FALSE(expr->matchesBSON(notMatch));
-}
-
TEST(MatchExpressionParserLeafTest, SimpleGT1) {
BSONObj query = BSON("x" << BSON("$gt" << 2));
const CollatorInterface* collator = nullptr;
@@ -233,34 +141,6 @@ TEST(MatchExpressionParserLeafTest, GTCollation) {
ASSERT_TRUE(match->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, GTConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$gt" << BSON("$expr"
- << "$$userVar")));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
-
- ASSERT_OK(result.getStatus());
- ASSERT_EQUALS(MatchExpression::GT, result.getValue()->matchType());
-
- auto expr = result.getValue().get();
-
- BSONObj match = BSON("x" << 500);
- BSONObj notMatch = BSON("x" << 0);
-
- ASSERT_TRUE(expr->matchesBSON(match));
- ASSERT_FALSE(expr->matchesBSON(notMatch));
-}
-
TEST(MatchExpressionParserLeafTest, SimpleLT1) {
BSONObj query = BSON("x" << BSON("$lt" << 2));
const CollatorInterface* collator = nullptr;
@@ -295,34 +175,6 @@ TEST(MatchExpressionParserLeafTest, LTCollation) {
ASSERT_TRUE(match->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, LTConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$lt" << BSON("$expr"
- << "$$userVar")));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
-
- ASSERT_OK(result.getStatus());
- ASSERT_EQUALS(MatchExpression::LT, result.getValue()->matchType());
-
- auto expr = result.getValue().get();
-
- BSONObj match = BSON("x" << 0);
- BSONObj notMatch = BSON("x" << 500);
-
- ASSERT_TRUE(expr->matchesBSON(match));
- ASSERT_FALSE(expr->matchesBSON(notMatch));
-}
-
TEST(MatchExpressionParserLeafTest, SimpleGTE1) {
BSONObj query = BSON("x" << BSON("$gte" << 2));
const CollatorInterface* collator = nullptr;
@@ -357,36 +209,6 @@ TEST(MatchExpressionParserLeafTest, GTECollation) {
ASSERT_TRUE(match->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, GTEConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$gte" << BSON("$expr"
- << "$$userVar")));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
-
- ASSERT_OK(result.getStatus());
- ASSERT_EQUALS(MatchExpression::GTE, result.getValue()->matchType());
-
- auto expr = result.getValue().get();
-
- BSONObj matchEq = BSON("x" << 123);
- BSONObj matchGt = BSON("x" << 500);
- BSONObj notMatch = BSON("x" << 0);
-
- ASSERT_TRUE(expr->matchesBSON(matchEq));
- ASSERT_TRUE(expr->matchesBSON(matchGt));
- ASSERT_FALSE(expr->matchesBSON(notMatch));
-}
-
TEST(MatchExpressionParserLeafTest, SimpleLTE1) {
BSONObj query = BSON("x" << BSON("$lte" << 2));
const CollatorInterface* collator = nullptr;
@@ -421,36 +243,6 @@ TEST(MatchExpressionParserLeafTest, LTECollation) {
ASSERT_TRUE(match->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, LTEConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$lte" << BSON("$expr"
- << "$$userVar")));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
-
- ASSERT_OK(result.getStatus());
- ASSERT_EQUALS(MatchExpression::LTE, result.getValue()->matchType());
-
- auto expr = result.getValue().get();
-
- BSONObj matchEq = BSON("x" << 123);
- BSONObj matchLt = BSON("x" << 0);
- BSONObj notMatch = BSON("x" << 500);
-
- ASSERT_TRUE(expr->matchesBSON(matchEq));
- ASSERT_TRUE(expr->matchesBSON(matchLt));
- ASSERT_FALSE(expr->matchesBSON(notMatch));
-}
-
TEST(MatchExpressionParserLeafTest, SimpleNE1) {
BSONObj query = BSON("x" << BSON("$ne" << 2));
const CollatorInterface* collator = nullptr;
@@ -489,34 +281,6 @@ TEST(MatchExpressionParserLeafTest, NECollation) {
ASSERT_TRUE(eqMatch->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, NEConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$ne" << BSON("$expr"
- << "$$userVar")));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
-
- ASSERT_OK(result.getStatus());
- ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
-
- auto expr = result.getValue().get();
-
- BSONObj match = BSON("x" << 0);
- BSONObj notMatch = BSON("x" << 123);
-
- ASSERT_TRUE(expr->matchesBSON(match));
- ASSERT_FALSE(expr->matchesBSON(notMatch));
-}
-
TEST(MatchExpressionParserLeafTest, SimpleModBad1) {
BSONObj query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2)));
const CollatorInterface* collator = nullptr;
@@ -568,25 +332,6 @@ TEST(MatchExpressionParserLeafTest, SimpleModNotNumber) {
<< "a")));
}
-TEST(MatchExpressionParserLeafTest, ModConstantExprFails) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$mod" << BSON("$expr"
- << "$$userVar")));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(BSON_ARRAY(10 << 2)));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
- ASSERT_NOT_OK(result.getStatus());
- ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
-}
-
TEST(MatchExpressionParserLeafTest, IdCollation) {
BSONObj query = BSON("$id"
<< "string");
@@ -609,26 +354,6 @@ TEST(MatchExpressionParserLeafTest, IdNullCollation) {
ASSERT_TRUE(match->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, IdConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("$id" << BSON("$expr"
- << "$$userVar"));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
- ASSERT_OK(result.getStatus());
-
- ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
-}
-
TEST(MatchExpressionParserLeafTest, RefCollation) {
BSONObj query = BSON("$ref"
<< "coll");
@@ -640,26 +365,6 @@ TEST(MatchExpressionParserLeafTest, RefCollation) {
ASSERT_TRUE(match->getCollator() == nullptr);
}
-TEST(MatchExpressionParserLeafTest, RefConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("$ref" << BSON("$expr"
- << "$$userVar"));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(std::string("colName")));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
- ASSERT_OK(result.getStatus());
-
- ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
-}
-
TEST(MatchExpressionParserLeafTest, DbCollation) {
BSONObj query = BSON("$db"
<< "db");
@@ -671,26 +376,6 @@ TEST(MatchExpressionParserLeafTest, DbCollation) {
ASSERT_TRUE(match->getCollator() == nullptr);
}
-TEST(MatchExpressionParserLeafTest, DbConstantExpr) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("$db" << BSON("$expr"
- << "$$userVar"));
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(std::string("dbName")));
-
- auto result = MatchExpressionParser::parse(query,
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
- ASSERT_OK(result.getStatus());
-
- ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
-}
-
TEST(MatchExpressionParserLeafTest, SimpleIN1) {
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(2 << 3)));
const CollatorInterface* collator = nullptr;
@@ -722,40 +407,6 @@ TEST(MatchExpressionParserLeafTest, INCollation) {
ASSERT_TRUE(match->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, INConstantExprFails) {
- CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
-
- // $expr represents entire $in array.
- BSONObj query = BSON("x" << BSON("$in" << BSON("$expr"
- << "userVar")));
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(BSON_ARRAY(1 << 2)));
-
- StatusWithMatchExpression result =
- MatchExpressionParser::parse(query,
- &collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
- ASSERT_NOT_OK(result.getStatus());
- ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
-
- // $expr represents a single element of the $in array.
- query = BSON("x" << BSON("$in" << BSON_ARRAY(1 << BSON("$expr"
- << "userVar"))));
- varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- result = MatchExpressionParser::parse(query,
- &collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
- ASSERT_NOT_OK(result.getStatus());
- ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
-}
-
TEST(MatchExpressionParserLeafTest, INSingleDBRef) {
OID oid = OID::gen();
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref"
@@ -1173,40 +824,6 @@ TEST(MatchExpressionParserLeafTest, NINCollation) {
ASSERT_TRUE(inMatch->getCollator() == &collator);
}
-TEST(MatchExpressionParserLeafTest, NINConstantExprFails) {
- CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
-
- // $expr represents entire $in array.
- BSONObj query = BSON("x" << BSON("$nin" << BSON("$expr"
- << "userVar")));
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(BSON_ARRAY(1 << 2)));
-
- StatusWithMatchExpression result =
- MatchExpressionParser::parse(query,
- &collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
- ASSERT_NOT_OK(result.getStatus());
- ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
-
- // $expr represents a single element of the $in array.
- query = BSON("x" << BSON("$nin" << BSON_ARRAY(1 << BSON("$expr"
- << "userVar"))));
- varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(123));
-
- result = MatchExpressionParser::parse(query,
- &collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr);
- ASSERT_NOT_OK(result.getStatus());
- ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue);
-}
-
TEST(MatchExpressionParserLeafTest, Regex1) {
BSONObjBuilder b;
b.appendRegex("x", "abc", "i");
@@ -1300,33 +917,6 @@ TEST(MatchExpressionParserLeafTest, RegexEmbeddedNULByte) {
<< "a")));
}
-TEST(MatchExpressionParserLeafTest, RegexWithConstantExprFails) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$options" << BSON("$expr"
- << "userVar")
- << "$regex"
- << "abc"));
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(std::string("i")));
-
- StatusWithMatchExpression result = MatchExpressionParser::parse(query, collator);
- ASSERT_NOT_OK(result.getStatus());
-
-
- query = BSON("x" << BSON("$options"
- << "i"
- << "$regex"
- << BSON("$expr"
- << "userVar")));
- varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(std::string("abc")));
-
- result = MatchExpressionParser::parse(query, collator);
- ASSERT_NOT_OK(result.getStatus());
-}
-
TEST(MatchExpressionParserLeafTest, ExistsYes1) {
BSONObjBuilder b;
b.appendBool("$exists", true);
@@ -1647,19 +1237,6 @@ TEST(MatchExpressionParserLeafTest, ValidTypeCodesParseSuccessfully) {
}
}
-TEST(MatchExpressionParserLeafTest, TypeWithConstantExprFails) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- BSONObj query = BSON("x" << BSON("$type" << BSON("$expr"
- << "userVar")));
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(static_cast<int>(BSONType::NumberDouble)));
-
- StatusWithMatchExpression result = MatchExpressionParser::parse(query, collator);
- ASSERT_NOT_OK(result.getStatus());
-}
-
TEST(MatchExpressionParserTest, BitTestMatchExpressionValidMask) {
const double k2Power53 = scalbn(1, 32);
@@ -2110,40 +1687,4 @@ TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidArrayValue) {
collator)
.getStatus());
}
-
-TEST(MatchExpressionParserLeafTest, BitTestWithConstantExprFails) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- const CollatorInterface* collator = nullptr;
-
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value(BSON_ARRAY(1 << 5)));
-
- ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [{$expr: 'userVar'}]}}"),
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr)
- .getStatus());
-
- ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: {$expr: 'userVar'}}}"),
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr)
- .getStatus());
-
- ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: {$expr: 'userVar'}}}"),
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr)
- .getStatus());
-
- ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: {$expr: 'userVar'}}}"),
- collator,
- expCtx,
- ExtensionsCallbackNoop(),
- MatchExpressionParser::AllowedFeatures::kExpr)
- .getStatus());
-}
} // namespace mongo
diff --git a/src/mongo/db/matcher/expression_parser_test.cpp b/src/mongo/db/matcher/expression_parser_test.cpp
index 9f0276b7028..e4d0e67b388 100644
--- a/src/mongo/db/matcher/expression_parser_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_test.cpp
@@ -372,6 +372,8 @@ TEST(MatchExpressionParserTest, NearParsesSuccessfullyWhenAllowed) {
.getStatus());
}
+// TODO SERVER-30951: Convert these tests to use top-level $expr and enable them.
+/*
TEST(MatchExpressionParserTest, ExprFailsToParseWhenDisallowed) {
auto query = fromjson("{a: {$expr: 5}}");
const CollatorInterface* collator = nullptr;
@@ -389,4 +391,5 @@ TEST(MatchExpressionParserTest, ExprParsesSuccessfullyWhenAllowed) {
MatchExpressionParser::AllowedFeatures::kExpr)
.getStatus());
}
+*/
}
diff --git a/src/mongo/db/matcher/expression_parser_tree.cpp b/src/mongo/db/matcher/expression_parser_tree.cpp
index 1e4290fcdc9..58365df9ff6 100644
--- a/src/mongo/db/matcher/expression_parser_tree.cpp
+++ b/src/mongo/db/matcher/expression_parser_tree.cpp
@@ -73,7 +73,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseNot(
AllowedFeatureSet allowedFeatures,
bool topLevel) {
if (e.type() == RegEx) {
- StatusWithMatchExpression s = _parseRegexElement(name, e, expCtx);
+ StatusWithMatchExpression s = _parseRegexElement(name, e);
if (!s.isOK())
return s;
std::unique_ptr<NotMatchExpression> n = stdx::make_unique<NotMatchExpression>();
diff --git a/src/mongo/db/matcher/expression_with_placeholder_test.cpp b/src/mongo/db/matcher/expression_with_placeholder_test.cpp
index 06460455dc7..5609755d89b 100644
--- a/src/mongo/db/matcher/expression_with_placeholder_test.cpp
+++ b/src/mongo/db/matcher/expression_with_placeholder_test.cpp
@@ -236,12 +236,15 @@ TEST(ExpressionWithPlaceholderTest, GeoNearExpressionFailsToParse) {
ASSERT_NOT_OK(status.getStatus());
}
+// TODO SERVER-30951: Convert this test to use top-level $expr and enable it.
+/*
TEST(ExpressionWithPlaceholderTest, ExprExpressionFailsToParse) {
const CollatorInterface* collator = nullptr;
auto rawFilter = fromjson("{i: {$expr: 5}}");
auto status = ExpressionWithPlaceholder::parse(rawFilter, collator);
ASSERT_NOT_OK(status.getStatus());
}
+*/
TEST(ExpressionWithPlaceholderTest, EquivalentIfPlaceholderAndExpressionMatch) {
constexpr auto collator = nullptr;
diff --git a/src/mongo/db/ops/modifier_pull_test.cpp b/src/mongo/db/ops/modifier_pull_test.cpp
index afefb4349ed..2870bf0ade1 100644
--- a/src/mongo/db/ops/modifier_pull_test.cpp
+++ b/src/mongo/db/ops/modifier_pull_test.cpp
@@ -121,6 +121,8 @@ TEST(SimpleMod, InitWithGeoNearObjectFails) {
ASSERT_EQUALS(ErrorCodes::BadValue, status);
}
+// TODO SERVER-30951: Convert these tests to use top-level $expr and enable them.
+/*
TEST(SimpleMod, InitWithExprElemFails) {
auto update = fromjson("{$pull: {a: {$expr: 5}}}");
const CollatorInterface* collator = nullptr;
@@ -138,6 +140,7 @@ TEST(SimpleMod, InitWithExprObjectFails) {
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::BadValue, status);
}
+*/
TEST(SimpleMod, PrepareOKTargetNotFound) {
Document doc(fromjson("{}"));
diff --git a/src/mongo/db/query/parsed_projection_test.cpp b/src/mongo/db/query/parsed_projection_test.cpp
index 22046f8b531..5d433bb4416 100644
--- a/src/mongo/db/query/parsed_projection_test.cpp
+++ b/src/mongo/db/query/parsed_projection_test.cpp
@@ -172,9 +172,12 @@ TEST(ParsedProjectionTest, InvalidElemMatchGeoNearProjection) {
"{a: {$elemMatch: {$nearSphere: {$geometry: {type: 'Point', coordinates: [0, 0]}}}}}");
}
+// TODO SERVER-30951: Convert this test to use top-level $expr and enable it.
+/*
TEST(ParsedProjectionTest, InvalidElemMatchExprProjection) {
assertInvalidProjection("{}", "{a: {$elemMatch: {$expr: 5}}}");
}
+*/
TEST(ParsedProjectionTest, ValidPositionalOperatorProjections) {
createParsedProjection("{a: 1}", "{'a.$': 1}");
diff --git a/src/mongo/db/update/pull_node_test.cpp b/src/mongo/db/update/pull_node_test.cpp
index 0fa4c83dcc0..a00a80e394e 100644
--- a/src/mongo/db/update/pull_node_test.cpp
+++ b/src/mongo/db/update/pull_node_test.cpp
@@ -101,6 +101,8 @@ TEST(PullNodeTest, InitWithGeoNearObjectFails) {
ASSERT_EQUALS(ErrorCodes::BadValue, status);
}
+// TODO SERVER-30951: Convert these tests to use top-level $expr and enable them.
+/*
TEST(PullNodeTest, InitWithExprElemFails) {
auto update = fromjson("{$pull: {a: {$expr: 5}}}");
const CollatorInterface* collator = nullptr;
@@ -118,6 +120,7 @@ TEST(PullNodeTest, InitWithExprObjectFails) {
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::BadValue, status);
}
+*/
TEST_F(PullNodeTest, TargetNotFound) {
auto update = fromjson("{$pull : {a: {$lt: 1}}}");
diff --git a/src/mongo/dbtests/extensions_callback_real_test.cpp b/src/mongo/dbtests/extensions_callback_real_test.cpp
index 9c0105299d9..7ea4e6a4af0 100644
--- a/src/mongo/dbtests/extensions_callback_real_test.cpp
+++ b/src/mongo/dbtests/extensions_callback_real_test.cpp
@@ -86,15 +86,6 @@ TEST_F(ExtensionsCallbackRealTest, TextNoIndex) {
ASSERT_EQ(ErrorCodes::IndexNotFound, result.getStatus());
}
-TEST_F(ExtensionsCallbackRealTest, TextRejectsExpr) {
- BSONObj query = fromjson("{$text: {$expr: '$$userVar'}}");
- StatusWithMatchExpression result =
- ExtensionsCallbackReal(&_opCtx, &_nss).parseText(query.firstElement());
-
- ASSERT_NOT_OK(result.getStatus());
- ASSERT_EQ(ErrorCodes::NoSuchKey, result.getStatus());
-}
-
TEST_F(ExtensionsCallbackRealTest, TextBasic) {
ASSERT_OK(dbtests::createIndex(&_opCtx,
_nss.ns(),