diff options
author | Milena Ivanova <milena.ivanova@mongodb.com> | 2021-09-10 17:31:26 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-09-10 17:51:28 +0000 |
commit | de21bf91f015f0ac21ed691ae0049db35f071920 (patch) | |
tree | 9511b9ab8dd8973fc40d813dddb2a94a3467cd26 | |
parent | 5b6c64a1d0ee28ad04556cab8743ef9d73c8871a (diff) | |
download | mongo-de21bf91f015f0ac21ed691ae0049db35f071920.tar.gz |
SERVER-58192 Fix memory leak in analyzeSort()
-rw-r--r-- | src/mongo/db/query/planner_analysis.cpp | 29 | ||||
-rw-r--r-- | src/mongo/db/query/query_solution.cpp | 6 |
2 files changed, 18 insertions, 17 deletions
diff --git a/src/mongo/db/query/planner_analysis.cpp b/src/mongo/db/query/planner_analysis.cpp index ab8698c4e43..ebd1d3de83a 100644 --- a/src/mongo/db/query/planner_analysis.cpp +++ b/src/mongo/db/query/planner_analysis.cpp @@ -664,21 +664,22 @@ QuerySolutionNode* QueryPlannerAnalysis::analyzeSort(const CanonicalQuery& query // And build the full sort stage. The sort stage has to have a sort key generating stage // as its child, supplying it with the appropriate sort keys. - SortKeyGeneratorNode* keyGenNode = new SortKeyGeneratorNode(); + auto keyGenNode = std::make_unique<SortKeyGeneratorNode>(); keyGenNode->sortSpec = sortObj; keyGenNode->children.push_back(solnRoot); - solnRoot = keyGenNode; + solnRoot = keyGenNode.release(); - SortNode* sort = new SortNode(); + auto sort = std::make_unique<SortNode>(); sort->pattern = sortObj; sort->children.push_back(solnRoot); - solnRoot = sort; + solnRoot = sort.release(); + auto sortNodeRaw = static_cast<SortNode*>(solnRoot); // When setting the limit on the sort, we need to consider both // the limit N and skip count M. The sort should return an ordered list // N + M items so that the skip stage can discard the first M results. if (qr.getLimit()) { // We have a true limit. The limit can be combined with the SORT stage. - sort->limit = + sortNodeRaw->limit = static_cast<size_t>(*qr.getLimit()) + static_cast<size_t>(qr.getSkip().value_or(0)); } else if (qr.getNToReturn()) { // We have an ntoreturn specified by an OP_QUERY style find. This is used @@ -687,7 +688,7 @@ QuerySolutionNode* QueryPlannerAnalysis::analyzeSort(const CanonicalQuery& query // Overflow here would be bad and could cause a nonsense limit. Cast // skip and limit values to unsigned ints to make sure that the // sum is never stored as signed. (See SERVER-13537). - sort->limit = + sortNodeRaw->limit = static_cast<size_t>(*qr.getNToReturn()) + static_cast<size_t>(qr.getSkip().value_or(0)); // This is a SORT with a limit. The wire protocol has a single quantity @@ -722,20 +723,20 @@ QuerySolutionNode* QueryPlannerAnalysis::analyzeSort(const CanonicalQuery& query // // Not allowed for geo or text, because we assume elsewhere that those // stages appear just once. - OrNode* orn = new OrNode(); - orn->children.push_back(sort); - SortNode* sortClone = static_cast<SortNode*>(sort->clone()); + auto orn = std::make_unique<OrNode>(); + orn->children.push_back(solnRoot); + SortNode* sortClone = static_cast<SortNode*>(sortNodeRaw->clone()); sortClone->limit = 0; orn->children.push_back(sortClone); // Add ENSURE_SORTED above the OR. - EnsureSortedNode* esn = new EnsureSortedNode(); - esn->pattern = sort->pattern; - esn->children.push_back(orn); - solnRoot = esn; + auto esn = std::make_unique<EnsureSortedNode>(); + esn->pattern = sortNodeRaw->pattern; + esn->children.push_back(orn.release()); + solnRoot = esn.release(); } } else { - sort->limit = 0; + sortNodeRaw->limit = 0; } *blockingSortOut = true; diff --git a/src/mongo/db/query/query_solution.cpp b/src/mongo/db/query/query_solution.cpp index f29ba473d40..4107621b672 100644 --- a/src/mongo/db/query/query_solution.cpp +++ b/src/mongo/db/query/query_solution.cpp @@ -970,14 +970,14 @@ void SortNode::appendToString(str::stream* ss, int indent) const { } QuerySolutionNode* SortNode::clone() const { - SortNode* copy = new SortNode(); - cloneBaseData(copy); + auto copy = std::make_unique<SortNode>(); + cloneBaseData(copy.get()); copy->_sorts = this->_sorts; copy->pattern = this->pattern; copy->limit = this->limit; - return copy; + return copy.release(); } // |