summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Wahlin <james@mongodb.com>2020-12-02 12:47:59 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-12-03 01:07:31 +0000
commit46ed0d855de5174ba5bddbc17acc8c4eab32e881 (patch)
treea2eed73b855b8163d16538fb65cb768fe4fcb497
parentc602b82432c4a4413b5cfad2ca88f7d0294c92eb (diff)
downloadmongo-46ed0d855de5174ba5bddbc17acc8c4eab32e881.tar.gz
SERVER-53007 Add $eq support to queryOperatorMap
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp15
-rw-r--r--src/mongo/db/matcher/expression_parser.h3
-rw-r--r--src/mongo/db/matcher/path_accepting_keyword_test.cpp14
-rw-r--r--src/mongo/db/pipeline/document_source_match.cpp11
-rw-r--r--src/mongo/db/update/pull_node_test.cpp19
5 files changed, 30 insertions, 32 deletions
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp
index 3412ef3cca6..e8d2acfd489 100644
--- a/src/mongo/db/matcher/expression_parser.cpp
+++ b/src/mongo/db/matcher/expression_parser.cpp
@@ -1469,19 +1469,6 @@ StatusWithMatchExpression parseSubField(const BSONObj& context,
DocumentParseLevel currentLevel) {
invariant(e);
- if ("$eq"_sd == e.fieldNameStringData()) {
- return parseComparison(
- name,
- std::make_unique<EqualityMatchExpression>(
- name,
- e,
- doc_validation_error::createAnnotation(
- expCtx, e.fieldNameStringData().toString(), BSON(name << e.wrap()))),
- e,
- expCtx,
- allowedFeatures);
- }
-
if ("$not"_sd == e.fieldNameStringData()) {
return parseNot(name, e, expCtx, extensionsCallback, allowedFeatures, currentLevel);
}
@@ -2003,7 +1990,6 @@ std::unique_ptr<StringMap<PathAcceptingKeyword>> queryOperatorMap;
MONGO_INITIALIZER(MatchExpressionParser)(InitializerContext* context) {
queryOperatorMap =
std::make_unique<StringMap<PathAcceptingKeyword>>(StringMap<PathAcceptingKeyword>{
- // TODO: SERVER-19565 Add $eq after auditing callers.
{"_internalExprEq", PathAcceptingKeyword::INTERNAL_EXPR_EQ},
{"_internalSchemaAllElemMatchFromIndex",
PathAcceptingKeyword::INTERNAL_SCHEMA_ALL_ELEM_MATCH_FROM_INDEX},
@@ -2029,6 +2015,7 @@ MONGO_INITIALIZER(MatchExpressionParser)(InitializerContext* context) {
{"bitsAnyClear", PathAcceptingKeyword::BITS_ANY_CLEAR},
{"bitsAnySet", PathAcceptingKeyword::BITS_ANY_SET},
{"elemMatch", PathAcceptingKeyword::ELEM_MATCH},
+ {"eq", PathAcceptingKeyword::EQUALITY},
{"exists", PathAcceptingKeyword::EXISTS},
{"geoIntersects", PathAcceptingKeyword::GEO_INTERSECTS},
{"geoNear", PathAcceptingKeyword::GEO_NEAR},
diff --git a/src/mongo/db/matcher/expression_parser.h b/src/mongo/db/matcher/expression_parser.h
index 673fcbfc08a..98ed368d95e 100644
--- a/src/mongo/db/matcher/expression_parser.h
+++ b/src/mongo/db/matcher/expression_parser.h
@@ -110,8 +110,7 @@ public:
/**
* Parses PathAcceptingKeyword from 'typeElem'. Returns 'defaultKeyword' if 'typeElem'
- * doesn't represent a known type, or represents PathAcceptingKeyword::EQUALITY which is not
- * handled by this parser (see SERVER-19565).
+ * doesn't represent a known type.
*/
static boost::optional<PathAcceptingKeyword> parsePathAcceptingKeyword(
BSONElement typeElem, boost::optional<PathAcceptingKeyword> defaultKeyword = boost::none);
diff --git a/src/mongo/db/matcher/path_accepting_keyword_test.cpp b/src/mongo/db/matcher/path_accepting_keyword_test.cpp
index 52b42e5d959..95a260fea4a 100644
--- a/src/mongo/db/matcher/path_accepting_keyword_test.cpp
+++ b/src/mongo/db/matcher/path_accepting_keyword_test.cpp
@@ -121,16 +121,8 @@ TEST(PathAcceptingKeyword, CanParseKnownMatchTypes) {
ASSERT_TRUE(PathAcceptingKeyword::INTERNAL_EXPR_EQ ==
MatchExpressionParser::parsePathAcceptingKeyword(
BSON("$_internalExprEq" << 1).firstElement()));
-}
-
-TEST(PathAcceptingKeyword, EqualityMatchReturnsDefault) {
- // 'boost::none' is the default when none specified.
- ASSERT_TRUE(boost::none ==
+ ASSERT_TRUE(PathAcceptingKeyword::EQUALITY ==
MatchExpressionParser::parsePathAcceptingKeyword(BSON("$eq" << 1).firstElement()));
- // Should return default specified by caller.
- ASSERT_TRUE(PathAcceptingKeyword::GEO_NEAR ==
- MatchExpressionParser::parsePathAcceptingKeyword(BSON("$eq" << 1).firstElement(),
- PathAcceptingKeyword::GEO_NEAR));
}
TEST(PathAcceptingKeyword, UnknownExpressionReturnsDefault) {
@@ -142,6 +134,10 @@ TEST(PathAcceptingKeyword, UnknownExpressionReturnsDefault) {
ASSERT_TRUE(PathAcceptingKeyword::NOT_IN ==
MatchExpressionParser::parsePathAcceptingKeyword(BSON("size" << 1).firstElement(),
PathAcceptingKeyword::NOT_IN));
+ // 'boost::none' is the default when none specified.
+ ASSERT_TRUE(boost::none ==
+ MatchExpressionParser::parsePathAcceptingKeyword(
+ BSON("NonExistentKeyWord" << 1).firstElement()));
}
TEST(PathAcceptingKeyword, EmptyBSONElemReturnsDefault) {
diff --git a/src/mongo/db/pipeline/document_source_match.cpp b/src/mongo/db/pipeline/document_source_match.cpp
index ac1ca6b16c8..9ee3c4ccb67 100644
--- a/src/mongo/db/pipeline/document_source_match.cpp
+++ b/src/mongo/db/pipeline/document_source_match.cpp
@@ -187,15 +187,12 @@ Document redactSafePortionDollarOps(BSONObj expr) {
if (field.fieldName()[0] != '$')
continue;
- if (field.fieldNameStringData() == "$eq") {
- if (isTypeRedactSafeInComparison(field.type())) {
- output[field.fieldNameStringData()] = Value(field);
- }
+ auto keyword = MatchExpressionParser::parsePathAcceptingKeyword(field);
+ if (!keyword) {
continue;
}
- switch (*MatchExpressionParser::parsePathAcceptingKeyword(field,
- PathAcceptingKeyword::EQUALITY)) {
+ switch (*keyword) {
// These are always ok
case PathAcceptingKeyword::TYPE:
case PathAcceptingKeyword::REGEX:
@@ -209,6 +206,7 @@ Document redactSafePortionDollarOps(BSONObj expr) {
break;
// These are ok if the type of the rhs is allowed in comparisons
+ case PathAcceptingKeyword::EQUALITY:
case PathAcceptingKeyword::LESS_THAN_OR_EQUAL:
case PathAcceptingKeyword::GREATER_THAN_OR_EQUAL:
case PathAcceptingKeyword::LESS_THAN:
@@ -264,7 +262,6 @@ Document redactSafePortionDollarOps(BSONObj expr) {
}
// These are never allowed
- case PathAcceptingKeyword::EQUALITY: // This actually means unknown
case PathAcceptingKeyword::EXISTS:
case PathAcceptingKeyword::GEO_INTERSECTS:
case PathAcceptingKeyword::GEO_NEAR:
diff --git a/src/mongo/db/update/pull_node_test.cpp b/src/mongo/db/update/pull_node_test.cpp
index 7231445ecab..611cc21de91 100644
--- a/src/mongo/db/update/pull_node_test.cpp
+++ b/src/mongo/db/update/pull_node_test.cpp
@@ -308,6 +308,25 @@ TEST_F(PullNodeTest, ApplyToArrayMatchingAll) {
assertOplogEntry(fromjson("{$set: {a: []}}"), fromjson("{$v: 2, diff: {u: {a: []}}}"));
}
+TEST_F(PullNodeTest, ApplyToArrayWithEq) {
+ auto update = fromjson("{$pull : {a: {$eq: 1}}}");
+ boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ PullNode node;
+ ASSERT_OK(node.init(update["$pull"]["a"], expCtx));
+
+ mutablebson::Document doc(fromjson("{a: [0, 1, 2, 3]}"));
+ setPathTaken(makeRuntimeUpdatePathForTest("a"));
+ addIndexedPath("a");
+ auto result = node.apply(getApplyParams(doc.root()["a"]), getUpdateNodeApplyParams());
+ ASSERT_FALSE(result.noop);
+ ASSERT_TRUE(result.indexesAffected);
+ ASSERT_EQUALS(fromjson("{a: [0, 2, 3]}"), doc);
+ ASSERT_FALSE(doc.isInPlaceModeEnabled());
+
+ assertOplogEntry(fromjson("{$set: {a: [0, 2, 3]}}"),
+ fromjson("{$v: 2, diff: {u: {a: [0, 2, 3]}}}"));
+}
+
TEST_F(PullNodeTest, ApplyNoIndexDataNoLogBuilder) {
auto update = fromjson("{$pull : {a: {$lt: 1}}}");
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());