diff options
author | James Wahlin <james@mongodb.com> | 2020-12-02 12:47:59 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-12-03 01:07:31 +0000 |
commit | 46ed0d855de5174ba5bddbc17acc8c4eab32e881 (patch) | |
tree | a2eed73b855b8163d16538fb65cb768fe4fcb497 | |
parent | c602b82432c4a4413b5cfad2ca88f7d0294c92eb (diff) | |
download | mongo-46ed0d855de5174ba5bddbc17acc8c4eab32e881.tar.gz |
SERVER-53007 Add $eq support to queryOperatorMap
-rw-r--r-- | src/mongo/db/matcher/expression_parser.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_parser.h | 3 | ||||
-rw-r--r-- | src/mongo/db/matcher/path_accepting_keyword_test.cpp | 14 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_match.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/update/pull_node_test.cpp | 19 |
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()); |