diff options
author | Reilly McBride <reilly.mcbride@mongodb.com> | 2022-08-05 20:25:47 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-05 21:35:30 +0000 |
commit | 94e93f4e95f7fa8ee169d493e50672b2c90bfc56 (patch) | |
tree | c7cdc28d3ca461800a96b8025b99c6afd3a4c8e7 /src/mongo/db | |
parent | 27ab971f2ab621d9b1d9804644b1b88befbc15bd (diff) | |
download | mongo-94e93f4e95f7fa8ee169d493e50672b2c90bfc56.tar.gz |
SERVER-67803 Parse $encryptedBetween MatchExpression
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/matcher/expression_parser.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_parser.h | 1 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_parser_test.cpp | 78 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_match.cpp | 1 |
4 files changed, 88 insertions, 0 deletions
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp index f3faa022c89..963ac06c634 100644 --- a/src/mongo/db/matcher/expression_parser.cpp +++ b/src/mongo/db/matcher/expression_parser.cpp @@ -1748,6 +1748,13 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, return {Status(ErrorCodes::BadValue, str::stream() << "near must be first in: " << context)}; + case PathAcceptingKeyword::ENCRYPTED_BETWEEN: + return std::make_unique<EncryptedBetweenMatchExpression>( + name, + e, + doc_validation_error::createAnnotation( + expCtx, e.fieldNameStringData().toString(), BSON(name << e.wrap()))); + case PathAcceptingKeyword::INTERNAL_EXPR_EQ: { if (e.type() == BSONType::Undefined || e.type() == BSONType::Array) { return {Status(ErrorCodes::BadValue, @@ -2144,6 +2151,7 @@ MONGO_INITIALIZER(MatchExpressionParser)(InitializerContext* context) { {"bitsAnyClear", PathAcceptingKeyword::BITS_ANY_CLEAR}, {"bitsAnySet", PathAcceptingKeyword::BITS_ANY_SET}, {"elemMatch", PathAcceptingKeyword::ELEM_MATCH}, + {"encryptedBetween", PathAcceptingKeyword::ENCRYPTED_BETWEEN}, {"eq", PathAcceptingKeyword::EQUALITY}, {"exists", PathAcceptingKeyword::EXISTS}, {"geoIntersects", PathAcceptingKeyword::GEO_INTERSECTS}, diff --git a/src/mongo/db/matcher/expression_parser.h b/src/mongo/db/matcher/expression_parser.h index 101a7e10332..62e13814142 100644 --- a/src/mongo/db/matcher/expression_parser.h +++ b/src/mongo/db/matcher/expression_parser.h @@ -55,6 +55,7 @@ enum class PathAcceptingKeyword { BITS_ANY_CLEAR, BITS_ANY_SET, ELEM_MATCH, + ENCRYPTED_BETWEEN, EQUALITY, EXISTS, GEO_INTERSECTS, diff --git a/src/mongo/db/matcher/expression_parser_test.cpp b/src/mongo/db/matcher/expression_parser_test.cpp index 00044cd8b23..34e5f594425 100644 --- a/src/mongo/db/matcher/expression_parser_test.cpp +++ b/src/mongo/db/matcher/expression_parser_test.cpp @@ -42,6 +42,7 @@ namespace mongo { + TEST(MatchExpressionParserTest, SimpleEQ1) { BSONObj query = BSON("x" << 2); boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); @@ -809,4 +810,81 @@ TEST(InternalSchemaBinDataEncryptedTypeExpressionTest, NonBinDataValueDoesNotMat BSONObj notMatch = BSON("a" << BSONArray()); ASSERT_FALSE(expr->matchesBSON(notMatch)); } + +TEST(EncryptedBetweenMatchExpressionTest, EncryptedBetweenExpectedBehaviorRHSNumeric) { + BSONObj query = BSON("a" << BSON("$encryptedBetween" << 5)); + BSONObj inner = BSON("$encryptedBetween" << 5); + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + StatusWithMatchExpression result = MatchExpressionParser::parse(query, expCtx); + ASSERT_TRUE(result.isOK()); + + ASSERT_EQ(result.getValue()->matchType(), MatchExpression::ENCRYPTED_BETWEEN); + auto ptr = result.getValue().get(); + auto expr = static_cast<EncryptedBetweenMatchExpression*>(ptr); + ASSERT_BSONOBJ_EQ(expr->getSerializedRightHandSide(), inner); +} + +TEST(EncryptedBetweenMatchExpressionTest, EncryptedBetweenExpectedBehaviorRHSDate) { + auto date = Date_t::now(); + BSONObj query = BSON("a" << BSON("$encryptedBetween" << date)); + BSONObj inner = BSON("$encryptedBetween" << date); + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + StatusWithMatchExpression result = MatchExpressionParser::parse(query, expCtx); + ASSERT_TRUE(result.isOK()); + + ASSERT_EQ(result.getValue()->matchType(), MatchExpression::ENCRYPTED_BETWEEN); + auto ptr = result.getValue().get(); + auto expr = static_cast<EncryptedBetweenMatchExpression*>(ptr); + ASSERT_BSONOBJ_EQ(expr->getSerializedRightHandSide(), inner); +} + +TEST(EncryptedBetweenMatchExpressionTest, EncryptedBetweenExpectedBehaviorInsideAnd) { + BSONObj query = fromjson("{$and: [{x: 1}, {a: {$encryptedBetween: 5}}]}"); + BSONObj inner = BSON("$encryptedBetween" << 5); + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + StatusWithMatchExpression result = MatchExpressionParser::parse(query, expCtx); + ASSERT_TRUE(result.isOK()); + + ASSERT_EQ(result.getValue()->matchType(), MatchExpression::AND); + ASSERT_EQ(result.getValue()->getChild(0)->matchType(), MatchExpression::EQ); + + auto ptr = result.getValue().get(); + auto encryptedBetweenChild = ptr->getChild(1); + ASSERT_EQ(encryptedBetweenChild->matchType(), MatchExpression::ENCRYPTED_BETWEEN); + + auto expr = static_cast<EncryptedBetweenMatchExpression*>(encryptedBetweenChild); + ASSERT_BSONOBJ_EQ(expr->getSerializedRightHandSide(), inner); +} + +TEST(EncryptedBetweenMatchExpressionTest, EncryptedBetweenExpectedBehaviorInsideNot) { + BSONObj query = fromjson("{a: {$not: {$encryptedBetween: 5}}}"); + BSONObj inner = BSON("$encryptedBetween" << 5); + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + StatusWithMatchExpression result = MatchExpressionParser::parse(query, expCtx); + ASSERT_TRUE(result.isOK()); + + ASSERT_EQ(result.getValue()->matchType(), MatchExpression::NOT); + ASSERT_EQ(result.getValue()->getChild(0)->matchType(), MatchExpression::AND); + + auto ptr = result.getValue().get(); + auto encryptedBetweenChild = ptr->getChild(0)->getChild(0); + ASSERT_EQ(encryptedBetweenChild->matchType(), MatchExpression::ENCRYPTED_BETWEEN); + auto expr = static_cast<EncryptedBetweenMatchExpression*>(encryptedBetweenChild); + ASSERT_BSONOBJ_EQ(expr->getSerializedRightHandSide(), inner); +} + +TEST(EncryptedBetweenMatchExpressionTest, EncryptedBetweenExpectedBehaviorDottedPath) { + BSONObj query = fromjson("{'a.b': {$encryptedBetween: 5}}"); + BSONObj inner = BSON("$encryptedBetween" << 5); + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + StatusWithMatchExpression result = MatchExpressionParser::parse(query, expCtx); + ASSERT_TRUE(result.isOK()); + ASSERT_EQ(result.getValue()->path(), "a.b"); + + ASSERT_EQ(result.getValue()->matchType(), MatchExpression::ENCRYPTED_BETWEEN); + auto ptr = result.getValue().get(); + auto expr = static_cast<EncryptedBetweenMatchExpression*>(ptr); + ASSERT_BSONOBJ_EQ(expr->getSerializedRightHandSide(), inner); +} + } // namespace mongo diff --git a/src/mongo/db/pipeline/document_source_match.cpp b/src/mongo/db/pipeline/document_source_match.cpp index 038b38100c4..9a7ba486b30 100644 --- a/src/mongo/db/pipeline/document_source_match.cpp +++ b/src/mongo/db/pipeline/document_source_match.cpp @@ -266,6 +266,7 @@ Document redactSafePortionDollarOps(BSONObj expr) { } // These are never allowed + case PathAcceptingKeyword::ENCRYPTED_BETWEEN: case PathAcceptingKeyword::EXISTS: case PathAcceptingKeyword::GEO_INTERSECTS: case PathAcceptingKeyword::GEO_NEAR: |