diff options
| author | Rui Liu <lriuui0x0@gmail.com> | 2023-07-14 15:09:02 +0000 |
|---|---|---|
| committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-08-21 16:18:58 +0000 |
| commit | 00bd991c1fb5789bab9d93f43efe82ae509085ab (patch) | |
| tree | b103efab8bc468d665ca77ab82c033d7c1951b02 | |
| parent | ce4ec8ed4a2afc48dd2ae50b6c95b786d8dfe494 (diff) | |
SERVER-77183 Only eliminate projection before group when group doesn't require full document
(cherry picked from commit 107f24c1bf0c8f7041978b2dfb718bb6694e0ba5)
| -rw-r--r-- | jstests/aggregation/optimize_away_pipeline.js | 3 | ||||
| -rw-r--r-- | src/mongo/db/query/planner_analysis.cpp | 2 |
2 files changed, 5 insertions, 0 deletions
diff --git a/jstests/aggregation/optimize_away_pipeline.js b/jstests/aggregation/optimize_away_pipeline.js index 8dfe8340182..1229b9e7070 100644 --- a/jstests/aggregation/optimize_away_pipeline.js +++ b/jstests/aggregation/optimize_away_pipeline.js @@ -647,6 +647,9 @@ assertProjectionIsNotRemoved([{$project: {a: 1}}, {$group: {_id: "$a", s: {$sum: assertProjectionIsNotRemoved( [{$project: {a: 1, b: 1}}, {$group: {_id: "$a.b", s: {$sum: "$b.c"}}}]); +// Test that an inclusion projection is NOT optimized away if group depends on the entire document. +assertProjectionIsNotRemoved([{$project: {a: 1}}, {$group: {_id: "$$ROOT"}}]); + // If the $group depends on both "path" and "path.subpath" then it will generate a $project on only // "path" to express its dependency set. We then fail to optimize that out. As a future improvement, // we could improve the optimizer to ensure that a projection stage is not present in the resulting diff --git a/src/mongo/db/query/planner_analysis.cpp b/src/mongo/db/query/planner_analysis.cpp index 4e714e1a8a5..6f699824e1a 100644 --- a/src/mongo/db/query/planner_analysis.cpp +++ b/src/mongo/db/query/planner_analysis.cpp @@ -716,6 +716,8 @@ void removeInclusionProjectionBelowGroupRecursive(QuerySolutionNode* solnRoot) { if (auto projection = attemptToGetProjectionFromQuerySolution(*projectNodeCandidate); // only eliminate inclusion projections projection && projection.value()->isInclusionOnly() && + // only eliminate when group depends on a subset of fields + !groupNode->needWholeDocument && // only eliminate projections which preserve all fields used by the group isSubset(groupNode->requiredFields, projection.value()->getRequiredFields())) { // Attach the projectNode's child directly as the groupNode's child, eliminating the |
