diff options
author | James Wahlin <james.wahlin@10gen.com> | 2017-05-08 16:36:32 -0400 |
---|---|---|
committer | James Wahlin <james.wahlin@10gen.com> | 2017-05-09 06:50:30 -0400 |
commit | 79c2c2d340982da8b669cd7c3aa6b958dbf56263 (patch) | |
tree | 638966f593b22a6e3a1de2851a4e1df2959480bb /src/mongo/db/pipeline/document_source_group.cpp | |
parent | 7d90084649608b3acc35ea290cce879783df12dc (diff) | |
download | mongo-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.cpp | 9 |
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); |