summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_group.cpp
diff options
context:
space:
mode:
authorJames Wahlin <james.wahlin@10gen.com>2017-05-08 16:36:32 -0400
committerJames Wahlin <james.wahlin@10gen.com>2017-05-09 06:50:30 -0400
commit79c2c2d340982da8b669cd7c3aa6b958dbf56263 (patch)
tree638966f593b22a6e3a1de2851a4e1df2959480bb /src/mongo/db/pipeline/document_source_group.cpp
parent7d90084649608b3acc35ea290cce879783df12dc (diff)
downloadmongo-79c2c2d340982da8b669cd7c3aa6b958dbf56263.tar.gz
SERVER-28651 Don't hold Document ref across group iterationsr3.5.7
Diffstat (limited to 'src/mongo/db/pipeline/document_source_group.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_group.cpp9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/mongo/db/pipeline/document_source_group.cpp b/src/mongo/db/pipeline/document_source_group.cpp
index 6ac4ad2bbd2..6e8d827e76c 100644
--- a/src/mongo/db/pipeline/document_source_group.cpp
+++ b/src/mongo/db/pipeline/document_source_group.cpp
@@ -490,7 +490,10 @@ DocumentSource::GetNextResult DocumentSourceGroup::initialize() {
_memoryUsageBytes = 0;
}
- Value id = computeId(input.getDocument());
+ // We release the result document here so that it does not outlive the end of this loop
+ // iteration. Not releasing could lead to an array copy when this group follows an unwind.
+ auto rootDocument = input.releaseDocument();
+ Value id = computeId(rootDocument);
// Look for the _id value in the map. If it's not there, add a new entry with a blank
// accumulator. This is done in a somewhat odd way in order to avoid hashing 'id' and
@@ -518,7 +521,7 @@ DocumentSource::GetNextResult DocumentSourceGroup::initialize() {
dassert(numAccumulators == group.size());
for (size_t i = 0; i < numAccumulators; i++) {
- group[i]->process(_accumulatedFields[i].expression->evaluate(input.getDocument()),
+ group[i]->process(_accumulatedFields[i].expression->evaluate(rootDocument),
_doingMerge);
_memoryUsageBytes += group[i]->memUsageForSorter();
@@ -767,7 +770,7 @@ BSONObjSet DocumentSourceGroup::getOutputSorts() {
}
-Value DocumentSourceGroup::computeId(Document root) {
+Value DocumentSourceGroup::computeId(const Document& root) {
// If only one expression, return result directly
if (_idExpressions.size() == 1) {
Value retValue = _idExpressions[0]->evaluate(root);