summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Buerger <will.buerger@mongodb.com>2023-02-14 19:30:59 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-02-15 00:32:25 +0000
commit2f08571855761cfa81b442d63a15736fc5c4707c (patch)
tree2f0f2085ce877e2445e0aab93ff001d5bb024523
parentff7fcd42e84317e2a34e0b413ee4cc1d9be66884 (diff)
downloadmongo-2f08571855761cfa81b442d63a15736fc5c4707c.tar.gz
SERVER-73673: Query shape (literal redaction) for leftover non-leaf MatchExpressions, pt. 1
-rw-r--r--src/mongo/db/matcher/expression_always_boolean.h7
-rw-r--r--src/mongo/db/matcher/expression_array.cpp7
-rw-r--r--src/mongo/db/matcher/expression_tree.cpp1
-rw-r--r--src/mongo/db/query/query_shape_test.cpp24
4 files changed, 33 insertions, 6 deletions
diff --git a/src/mongo/db/matcher/expression_always_boolean.h b/src/mongo/db/matcher/expression_always_boolean.h
index 901203f9eff..054b9b417ca 100644
--- a/src/mongo/db/matcher/expression_always_boolean.h
+++ b/src/mongo/db/matcher/expression_always_boolean.h
@@ -63,8 +63,11 @@ public:
}
void serialize(BSONObjBuilder* out, SerializationOptions opts) const final {
- // TODO support 'opts.redactFieldNames.'
- out->append(name(), 1);
+ if (opts.replacementForLiteralArgs) {
+ out->append(name(), *opts.replacementForLiteralArgs);
+ } else {
+ out->append(name(), 1);
+ }
}
bool equivalent(const MatchExpression* other) const final {
diff --git a/src/mongo/db/matcher/expression_array.cpp b/src/mongo/db/matcher/expression_array.cpp
index 6ed79d1de5e..5f69a1211de 100644
--- a/src/mongo/db/matcher/expression_array.cpp
+++ b/src/mongo/db/matcher/expression_array.cpp
@@ -105,8 +105,9 @@ void ElemMatchObjectMatchExpression::debugString(StringBuilder& debug, int inden
BSONObj ElemMatchObjectMatchExpression::getSerializedRightHandSide(
boost::optional<StringData> replacementForLiteralArgs) const {
- // TODO SERVER-73673 respect and test 'replacementForLiteralArgs'.
- return BSON("$elemMatch" << _sub->serialize());
+ SerializationOptions opts;
+ opts.replacementForLiteralArgs = replacementForLiteralArgs;
+ return BSON("$elemMatch" << _sub->serialize(opts));
}
MatchExpression::ExpressionOptimizerFunc ElemMatchObjectMatchExpression::getOptimizer() const {
@@ -178,10 +179,10 @@ BSONObj ElemMatchValueMatchExpression::getSerializedRightHandSide(
boost::optional<StringData> replacementForLiteralArgs) const {
BSONObjBuilder emBob;
- // TODO SERVER-73673 respect and test 'replacementForLiteralArgs'.
for (auto&& child : _subs) {
SerializationOptions opts;
opts.includePath = false;
+ opts.replacementForLiteralArgs = replacementForLiteralArgs;
child->serialize(&emBob, opts);
}
diff --git a/src/mongo/db/matcher/expression_tree.cpp b/src/mongo/db/matcher/expression_tree.cpp
index c2778acb271..2f3f376931b 100644
--- a/src/mongo/db/matcher/expression_tree.cpp
+++ b/src/mongo/db/matcher/expression_tree.cpp
@@ -350,7 +350,6 @@ void AndMatchExpression::serialize(BSONObjBuilder* out, SerializationOptions opt
return;
}
- // TODO SERVER-73673 this looks correct - just need to test.
BSONArrayBuilder arrBob(out->subarrayStart("$and"));
_listToBSON(&arrBob, opts);
arrBob.doneFast();
diff --git a/src/mongo/db/query/query_shape_test.cpp b/src/mongo/db/query/query_shape_test.cpp
index 5ee00a416dd..47c5e2bdea6 100644
--- a/src/mongo/db/query/query_shape_test.cpp
+++ b/src/mongo/db/query/query_shape_test.cpp
@@ -98,6 +98,30 @@ TEST(QueryPredicateShape, BitTestOperators) {
assertShapeIs("{a: {$bitsAnyClear: 50}}", "{a: {$bitsAnyClear: '?'}}");
}
+TEST(QueryPredicateShape, AlwaysBoolean) {
+ assertShapeIs("{$alwaysTrue: 1}", "{$alwaysTrue: '?'}");
+ assertShapeIs("{$alwaysFalse: 1}", "{$alwaysFalse: '?'}");
+}
+
+TEST(QueryPredicateShape, And) {
+ assertShapeIs("{$and: [{a: {$lt: 5}}, {b: {$gte: 3}}, {c: {$lte: 10}}]}",
+ "{$and: [{a: {$lt: '?'}}, {b: {$gte: '?'}}, {c: {$lte: '?'}}]}");
+}
+
+TEST(QueryPredicateShape, Or) {
+ assertShapeIs("{$or: [{a: 5}, {b: {$in: [1,2,3]}}, {c: {$gt: 10}}]}",
+ "{$or: [{a: {$eq: '?'}}, {b: {$in: ['?']}}, {c: {$gt: '?'}}]}");
+}
+
+TEST(QueryPredicateShape, ElemMatch) {
+ // ElemMatchObjectMatchExpression
+ assertShapeIs("{a: {$elemMatch: {b: 5, c: {$exists: true}}}}",
+ "{a: {$elemMatch: {$and: [{b: {$eq: '?'}}, {c: {$exists: '?'}}]}}}");
+
+ // ElemMatchValueMatchExpression
+ assertShapeIs("{a: {$elemMatch: {$gt: 5, $lt: 10}}}", "{a: {$elemMatch: {$gt: '?', $lt:'?'}}}");
+}
+
BSONObj queryShapeForOptimizedExprExpression(std::string exprPredicateJson) {
ParsedMatchExpressionForTest expr(exprPredicateJson);
// We need to optimize an $expr expression in order to generate an $_internalExprEq. It's not