summaryrefslogtreecommitdiff
path: root/src/mongo/db/matcher/expression_serialization_test.cpp
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/db/matcher/expression_serialization_test.cpp
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (diff)
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0' with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'src/mongo/db/matcher/expression_serialization_test.cpp')
-rw-r--r--src/mongo/db/matcher/expression_serialization_test.cpp352
1 files changed, 7 insertions, 345 deletions
diff --git a/src/mongo/db/matcher/expression_serialization_test.cpp b/src/mongo/db/matcher/expression_serialization_test.cpp
index 3b25631cd0f..78517a52634 100644
--- a/src/mongo/db/matcher/expression_serialization_test.cpp
+++ b/src/mongo/db/matcher/expression_serialization_test.cpp
@@ -37,16 +37,7 @@
#include "mongo/db/matcher/expression_parser.h"
#include "mongo/db/matcher/extensions_callback_noop.h"
#include "mongo/db/matcher/matcher.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_all_elem_match_from_index.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_cond.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_eq.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_fmod.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_max_items.h"
#include "mongo/db/matcher/schema/expression_internal_schema_max_length.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_max_properties.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_min_items.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_min_length.h"
-#include "mongo/db/matcher/schema/expression_internal_schema_min_properties.h"
#include "mongo/db/pipeline/expression_context_for_test.h"
#include "mongo/unittest/unittest.h"
@@ -58,7 +49,9 @@ using std::string;
using std::unique_ptr;
BSONObj serialize(MatchExpression* match) {
- return match->serialize();
+ BSONObjBuilder bob;
+ match->serialize(&bob, true);
+ return bob.obj();
}
TEST(SerializeBasic, AndExpressionWithOneChildSerializesCorrectly) {
@@ -362,6 +355,7 @@ TEST(SerializeBasic, ExpressionElemMatchValueWithTripleNotSerializesCorrectly) {
ASSERT_EQ(original.matches(obj), reserialized.matches(obj));
}
+
TEST(SerializeBasic, ExpressionSizeSerializesCorrectly) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
Matcher original(fromjson("{x: {$size: 2}}"),
@@ -636,32 +630,6 @@ TEST(SerializeBasic, ExpressionRegexWithValueAndOptionsSerializesCorrectly) {
ASSERT_EQ(original.matches(obj), reserialized.matches(obj));
}
-TEST(SerializeBasic, ExpressionRegexWithoutOptionsSerializesShapeCorrectly) {
- auto query = fromjson(R"({x: {$regex: ".*"}})");
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto objMatch = MatchExpressionParser::parse(query, expCtx);
- ASSERT_OK(objMatch.getStatus());
- SerializationOptions opts;
- opts.literalPolicy = LiteralSerializationPolicy::kToRepresentativeParseableValue;
- ASSERT_BSONOBJ_EQ(BSON("x" << BSON("$regex"
- << "\\?")),
- objMatch.getValue()->serialize(opts));
-}
-
-TEST(SerializeBasic, ExpressionRegexWithOptionsSerializesShapeCorrectly) {
- auto query = fromjson(R"({x: {$regex: ".*", $options: "m"}})");
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto objMatch = MatchExpressionParser::parse(query, expCtx);
- ASSERT_OK(objMatch.getStatus());
- SerializationOptions opts;
- opts.literalPolicy = LiteralSerializationPolicy::kToRepresentativeParseableValue;
- ASSERT_BSONOBJ_EQ(BSON("x" << BSON("$regex"
- << "\\?"
- << "$options"
- << "i")),
- objMatch.getValue()->serialize(opts));
-}
-
TEST(SerializeBasic, ExpressionRegexWithValueSerializesCorrectly) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
Matcher original(fromjson("{x: /a.b/}"),
@@ -1125,7 +1093,7 @@ TEST(SerializeBasic, ExpressionNotWithDirectPathExpSerializesCorrectly) {
// direct path expression child, instead creating a NOT -> AND -> path expression. This test
// manually constructs such an expression in case it ever turns up, since that should still be
// able to serialize.
- auto originalBSON = fromjson("{a: {$not: {$eq: 2}}}");
+ auto originalBSON = fromjson("{a: {$not: {$eq: 2}}}}");
auto equalityRHSElem = originalBSON["a"]["$not"]["$eq"];
auto equalityExpression = std::make_unique<EqualityMatchExpression>("a"_sd, equalityRHSElem);
@@ -1711,7 +1679,7 @@ TEST(SerializeInternalSchema, ExpressionInternalSchemaMaxLengthSerializesCorrect
TEST(SerializeInternalSchema, ExpressionInternalSchemaCondSerializesCorrectly) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- Matcher original(fromjson("{$_internalSchemaCond: [{a: 1}, {b: 2}, {c: 3}]}"),
+ Matcher original(fromjson("{$_internalSchemaCond: [{a: 1}, {b: 2}, {c: 3}]}}"),
expCtx,
ExtensionsCallbackNoop(),
MatchExpressionParser::kAllowAllSpecialFeatures);
@@ -1722,7 +1690,7 @@ TEST(SerializeInternalSchema, ExpressionInternalSchemaCondSerializesCorrectly) {
BSONObjBuilder builder;
ASSERT_BSONOBJ_EQ(
*reserialized.getQuery(),
- fromjson("{$_internalSchemaCond: [{a: {$eq: 1}}, {b: {$eq: 2}}, {c: {$eq: 3}}]}"));
+ fromjson("{$_internalSchemaCond: [{a: {$eq: 1}}, {b: {$eq: 2}}, {c: {$eq: 3}}]}}"));
ASSERT_BSONOBJ_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
}
@@ -1880,311 +1848,5 @@ TEST(SerializeInternalBinDataSubType, ExpressionBinDataSubTypeSerializesCorrectl
ASSERT_TRUE(original.matches(obj));
}
-TEST(SerializeInternalSchema, AllowedPropertiesRedactsCorrectly) {
-
- auto query = fromjson(
- "{$_internalSchemaAllowedProperties: {properties: ['a', 'b'],"
- "namePlaceholder: 'i', patternProperties: [], otherwise: {i: 0}}}");
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto objMatch = MatchExpressionParser::parse(query, expCtx);
- ASSERT_OK(objMatch.getStatus());
-
- SerializationOptions opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
-
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({
- "$_internalSchemaAllowedProperties": {
- "properties": "?array<?string>",
- "namePlaceholder": "i",
- "patternProperties": [],
- "otherwise": {
- "HASH<i>": {
- "$eq": "?number"
- }
- }
- }
- })",
- objMatch.getValue()->serialize(opts));
-}
-
-/**
- * Helper function for parsing and creating MatchExpressions.
- */
-std::unique_ptr<InternalSchemaCondMatchExpression> createCondMatchExpression(BSONObj condition,
- BSONObj thenBranch,
- BSONObj elseBranch) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto conditionExpr = MatchExpressionParser::parse(condition, expCtx);
- ASSERT_OK(conditionExpr.getStatus());
- auto thenBranchExpr = MatchExpressionParser::parse(thenBranch, expCtx);
- ASSERT_OK(thenBranchExpr.getStatus());
- auto elseBranchExpr = MatchExpressionParser::parse(elseBranch, expCtx);
-
- std::array<std::unique_ptr<MatchExpression>, 3> expressions = {
- {std::move(conditionExpr.getValue()),
- std::move(thenBranchExpr.getValue()),
- std::move(elseBranchExpr.getValue())}};
-
- auto cond = std::make_unique<InternalSchemaCondMatchExpression>(std::move(expressions));
-
- return cond;
-}
-
-TEST(SerializeInternalSchema, CondMatchRedactsCorrectly) {
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
- auto conditionQuery = BSON("age" << BSON("$lt" << 18));
- auto thenQuery = BSON("job"
- << "student");
- auto elseQuery = BSON("job"
- << "engineer");
- auto cond = createCondMatchExpression(conditionQuery, thenQuery, elseQuery);
- BSONObjBuilder bob;
- cond->serialize(&bob, opts);
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({
- "$_internalSchemaCond": [
- {
- "HASH<age>": {
- "$lt": "?number"
- }
- },
- {
- "HASH<job>": {
- "$eq": "?string"
- }
- },
- {
- "HASH<job>": {
- "$eq": "?string"
- }
- }
- ]
- })",
- bob.done());
-}
-
-TEST(SerializeInternalSchema, FmodMatchRedactsCorrectly) {
- InternalSchemaFmodMatchExpression m("a"_sd, Decimal128(1.7), Decimal128(2));
- auto opts = SerializationOptions{LiteralSerializationPolicy::kToDebugTypeString};
- BSONObjBuilder bob;
- m.serialize(&bob, opts);
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"a":{"$_internalSchemaFmod":["?number","?number"]}})",
- bob.done());
-}
-
-TEST(SerializeInternalSchema, MatchArrayIndexRedactsCorrectly) {
- auto query = fromjson(
- "{foo: {$_internalSchemaMatchArrayIndex:"
- "{index: 0, namePlaceholder: 'i', expression: {i: {$type: 'number'}}}}}");
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto objMatch = MatchExpressionParser::parse(query, expCtx);
- ASSERT_OK(objMatch.getStatus());
-
- BSONObjBuilder bob;
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
- objMatch.getValue()->serialize(&bob, opts);
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({
- "HASH<foo>": {
- "$_internalSchemaMatchArrayIndex": {
- "index": "?number",
- "namePlaceholder": "HASH<i>",
- "expression": {
- "HASH<i>": {
- "$type": ['number']
- }
- }
- }
- }
- })",
- bob.done());
-}
-
-TEST(SerializeInternalSchema, MaxItemsRedactsCorrectly) {
- InternalSchemaMaxItemsMatchExpression maxItems("a.b"_sd, 2);
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"$_internalSchemaMaxItems":"?number"})",
- maxItems.getSerializedRightHandSide(opts));
-}
-
-TEST(SerializeInternalSchema, MaxLengthRedactsCorrectly) {
- InternalSchemaMaxLengthMatchExpression maxLength("a"_sd, 2);
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"$_internalSchemaMaxLength":"?number"})",
- maxLength.getSerializedRightHandSide(opts));
-}
-
-TEST(SerializeInternalSchema, MinItemsRedactsCorrectly) {
- InternalSchemaMinItemsMatchExpression minItems("a.b"_sd, 2);
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
-
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"$_internalSchemaMinItems":"?number"})",
- minItems.getSerializedRightHandSide(opts));
-}
-
-TEST(SerializeInternalSchema, MinLengthRedactsCorrectly) {
- InternalSchemaMinLengthMatchExpression minLength("a"_sd, 2);
- auto opts = SerializationOptions{LiteralSerializationPolicy::kToDebugTypeString};
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"$_internalSchemaMinLength":"?number"})",
- minLength.getSerializedRightHandSide(opts));
-}
-
-TEST(SerializeInternalSchema, MinPropertiesRedactsCorrectly) {
- InternalSchemaMinPropertiesMatchExpression minProperties(5);
- auto opts = SerializationOptions{LiteralSerializationPolicy::kToDebugTypeString};
-
- BSONObjBuilder bob;
- minProperties.serialize(&bob, opts);
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"$_internalSchemaMinProperties":"?number"})",
- bob.done());
-}
-
-TEST(SerializeInternalSchema, ObjectMatchRedactsCorrectly) {
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
- auto query = fromjson(
- " {a: {$_internalSchemaObjectMatch: {"
- " c: {$eq: 3}"
- " }}}");
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto objMatch = MatchExpressionParser::parse(query, expCtx);
- ASSERT_OK(objMatch.getStatus());
-
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"HASH<a>":{"$_internalSchemaObjectMatch":{"HASH<c>":{"$eq":"?number"}}}})",
- objMatch.getValue()->serialize(opts));
-}
-
-TEST(SerializeInternalSchema, RootDocEqRedactsCorrectly) {
- auto query = fromjson("{$_internalSchemaRootDocEq: {a:1, b: {c: 1, d: [1]}}}");
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
- auto objMatch = MatchExpressionParser::parse(query, expCtx);
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({
- "$_internalSchemaRootDocEq": {
- "HASH<a>": "?number",
- "HASH<b>": {
- "HASH<c>": "?number",
- "HASH<d>": [
- "?number"
- ]
- }
- }
- })",
- objMatch.getValue()->serialize(opts));
-}
-
-TEST(SerializeInternalSchema, BinDataEncryptedTypeRedactsCorrectly) {
- MatcherTypeSet typeSet;
- typeSet.bsonTypes.insert(BSONType::String);
- typeSet.bsonTypes.insert(BSONType::Date);
- InternalSchemaBinDataEncryptedTypeExpression e("a"_sd, std::move(typeSet));
- auto opts = SerializationOptions{LiteralSerializationPolicy::kToDebugTypeString};
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"$_internalSchemaBinDataEncryptedType":[2,9]})",
- e.getSerializedRightHandSide(opts));
-}
-
-TEST(SerializeInternalSchema, BinDataFLE2EncryptedTypeRedactsCorrectly) {
- InternalSchemaBinDataFLE2EncryptedTypeExpression e("ssn"_sd, BSONType::String);
- auto opts = SerializationOptions{LiteralSerializationPolicy::kToDebugTypeString};
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"$_internalSchemaBinDataFLE2EncryptedType":[2]})",
- e.getSerializedRightHandSide(opts));
-}
-
-TEST(SerializesInternalSchema, MaxPropertiesRedactsCorrectly) {
- InternalSchemaMaxPropertiesMatchExpression maxProperties(5);
- auto opts = SerializationOptions{LiteralSerializationPolicy::kToDebugTypeString};
-
- BSONObjBuilder bob;
- maxProperties.serialize(&bob, opts);
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({"$_internalSchemaMaxProperties":"?number"})",
- bob.done());
-}
-
-TEST(SerializesInternalSchema, EqRedactsCorrectly) {
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
- auto query = fromjson("{$_internalSchemaEq: {a:1, b: {c: 1, d: [1]}}}");
- BSONObjBuilder bob;
- InternalSchemaEqMatchExpression e("a"_sd, query.firstElement());
- e.serialize(&bob, opts);
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({
- "HASH<a>": {
- "$_internalSchemaEq": {
- "HASH<a>": "?number",
- "HASH<b>": {
- "HASH<c>": "?number",
- "HASH<d>": [
- "?number"
- ]
- }
- }
- }
- })",
- bob.done());
-}
-
-TEST(InternalSchemaAllElemMatchFromIndexMatchExpression, RedactsExpressionCorrectly) {
- auto query = fromjson("{a: {$_internalSchemaAllElemMatchFromIndex: [2, {a: {$lt: 5}}]}}");
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto expr = MatchExpressionParser::parse(query, expCtx);
- ASSERT_OK(expr.getStatus());
- auto elemMatchExpr = dynamic_cast<const InternalSchemaAllElemMatchFromIndexMatchExpression*>(
- expr.getValue().get());
-
- auto opts = SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST;
-
- ASSERT_BSONOBJ_EQ_AUTO( // NOLINT
- R"({
- "$_internalSchemaAllElemMatchFromIndex": [
- "?number",
- {
- "HASH<a>": {
- "$lt": "?number"
- }
- }
- ]
- })",
- elemMatchExpr->getSerializedRightHandSide(opts));
-}
-
-TEST(SerializeBasic, SerializesNestedElemMatchCorrectly) {
- auto query = fromjson(R"({a: {$elemMatch: {$elemMatch: {b: {$lt: 6, $gt: 4}}}}})");
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto objMatch = MatchExpressionParser::parse(query, expCtx);
- ASSERT_OK(objMatch.getStatus());
- SerializationOptions opts;
- opts.literalPolicy = LiteralSerializationPolicy::kToDebugTypeString;
- ASSERT_BSONOBJ_EQ_AUTO(
- R"({"a": {
- "$elemMatch": {
- "$elemMatch": {
- "$and": [
- {
- "b": {
- "$lt": "?number"
- }
- },
- {
- "b": {
- "$gt": "?number"
- }
- }
- ]
- }
- }
- }
- })",
- objMatch.getValue()->serialize(opts));
-}
} // namespace
} // namespace mongo