summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/group_processor_base.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/group_processor_base.cpp')
-rw-r--r--src/mongo/db/pipeline/group_processor_base.cpp34
1 files changed, 21 insertions, 13 deletions
diff --git a/src/mongo/db/pipeline/group_processor_base.cpp b/src/mongo/db/pipeline/group_processor_base.cpp
index 1f09cd0fcf8..5c5ae8c153b 100644
--- a/src/mongo/db/pipeline/group_processor_base.cpp
+++ b/src/mongo/db/pipeline/group_processor_base.cpp
@@ -76,20 +76,28 @@ void GroupProcessorBase::freeMemory() {
void GroupProcessorBase::setIdExpression(const boost::intrusive_ptr<Expression> idExpression) {
tassert(7801001, "Can't mutate _id fields after initialization", !_executionStarted);
- if (auto object = dynamic_cast<ExpressionObject*>(idExpression.get())) {
- auto& childExpressions = object->getChildExpressions();
- invariant(!childExpressions.empty()); // We expect to have converted an empty object into a
- // constant expression.
-
- // grouping on an "artificial" object. Rather than create the object for each input
- // in initialize(), instead group on the output of the raw expressions. The artificial
- // object will be created at the end in makeDocument() while outputting results.
- for (auto&& childExpPair : childExpressions) {
- _idFieldNames.push_back(childExpPair.first);
- _idExpressions.push_back(childExpPair.second);
- }
- } else {
+
+
+ auto object = dynamic_cast<ExpressionObject*>(idExpression.get());
+ if (!object || object->getChildExpressions().empty()) {
+ // Any single expression (including an empty object) can be directly computed and output
+ // without any custom handling or transformations. Note that we don't expect the parser to
+ // produce an empty object ExpressionObject (it should produce an ExpressionConstant
+ // instead), but we have been mistaken about that before in SERVER-89611, so we will handle
+ // this special case as well.
_idExpressions.push_back(idExpression);
+ return;
+ }
+
+ // For objects (e.g. from parsing {$group: {_id: {a: "$a", b: "$b"}}}), we do the following
+ // optimization to perform grouping on an "artificial" object. Rather than create the object for
+ // each input in initialize(), instead group on the output of the raw expressions. The
+ // artificial object will be created at the end in makeDocument() while outputting results.
+ auto& childExpressions = object->getChildExpressions();
+
+ for (auto&& childExpPair : childExpressions) {
+ _idFieldNames.push_back(childExpPair.first);
+ _idExpressions.push_back(childExpPair.second);
}
}