diff options
author | Charlie Swanson <charlie.swanson@mongodb.com> | 2022-11-23 15:03:08 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-23 15:33:18 +0000 |
commit | b2fa75ac0b97688390df6ac7e2e8b0325e21e454 (patch) | |
tree | 2bdc8b7adcdef9dda02e277abda6b584f6033027 | |
parent | b5e8544cb77adf0c459d0e630c87e280e348ea56 (diff) | |
download | mongo-b2fa75ac0b97688390df6ac7e2e8b0325e21e454.tar.gz |
SERVER-64764 Fix '$$ROOT' handling in $expr rewrite
-rw-r--r-- | jstests/core/expr.js | 3 | ||||
-rw-r--r-- | src/mongo/db/matcher/rewrite_expr.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/matcher/rewrite_expr_test.cpp | 12 |
3 files changed, 18 insertions, 3 deletions
diff --git a/jstests/core/expr.js b/jstests/core/expr.js index 362e06c9a55..c599bcd757e 100644 --- a/jstests/core/expr.js +++ b/jstests/core/expr.js @@ -24,8 +24,9 @@ const isMongos = (hello.msg === "isdbgrid"); // coll.drop(); -assert.commandWorked(coll.insert({a: 0})); +assert.commandWorked(coll.insert({_id: 0, a: 0})); assert.eq(1, coll.aggregate([{$match: {$expr: {$eq: ["$a", 0]}}}]).itcount()); +assert.eq(1, coll.aggregate([{$match: {$expr: {$eq: ["$$ROOT", {_id: 0, a: 0}]}}}]).itcount()); assert.throws(function() { coll.aggregate([{$match: {$expr: {$eq: ["$a", "$$unbound"]}}}]); }); diff --git a/src/mongo/db/matcher/rewrite_expr.cpp b/src/mongo/db/matcher/rewrite_expr.cpp index a523853a639..e61ddeaab78 100644 --- a/src/mongo/db/matcher/rewrite_expr.cpp +++ b/src/mongo/db/matcher/rewrite_expr.cpp @@ -233,8 +233,10 @@ bool RewriteExpr::_canRewriteComparison( for (auto operand : operandList) { if (auto exprFieldPath = dynamic_cast<ExpressionFieldPath*>(operand.get())) { - if (exprFieldPath->isVariableReference()) { - // This field path refers to a variable rather than a local document field path. + if (exprFieldPath->isVariableReference() || exprFieldPath->isROOT()) { + // Rather than a local document field path, this field path refers to either a + // variable or the full document itself. Neither of which can be expressed in the + // match language. return false; } diff --git a/src/mongo/db/matcher/rewrite_expr_test.cpp b/src/mongo/db/matcher/rewrite_expr_test.cpp index 9fa64b3c70b..948add02c26 100644 --- a/src/mongo/db/matcher/rewrite_expr_test.cpp +++ b/src/mongo/db/matcher/rewrite_expr_test.cpp @@ -163,6 +163,18 @@ TEST(RewriteExpr, EqWithComparisonToMissingDoesNotRewriteToMatch) { testExprRewrite(expr, expectedMatch); } +TEST(RewriteExpr, EqWithComparisonToRootDoesNotRewriteToMatch) { + BSONObj expr = fromjson("{$expr: {$eq: ['$$ROOT', {a: 1}]}}"); + const BSONObj expectedMatch; + testExprRewrite(expr, expectedMatch); +} + +TEST(RewriteExpr, EqWithComparisonToCurrentDoesNotRewriteToMatch) { + BSONObj expr = fromjson("{$expr: {$eq: ['$$CURRENT', 2]}}"); + const BSONObj expectedMatch; + testExprRewrite(expr, expectedMatch); +} + TEST(RewriteExpr, EqWithComparisonToArrayDoesNotRewriteToMatch) { BSONObj expr = fromjson("{$expr: {$eq: ['$x', [1, 2, 3]]}}"); const BSONObj expectedMatch; |