summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilena Ivanova <milena.ivanova@mongodb.com>2021-09-10 17:31:26 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-09-10 17:51:28 +0000
commitde21bf91f015f0ac21ed691ae0049db35f071920 (patch)
tree9511b9ab8dd8973fc40d813dddb2a94a3467cd26
parent5b6c64a1d0ee28ad04556cab8743ef9d73c8871a (diff)
downloadmongo-de21bf91f015f0ac21ed691ae0049db35f071920.tar.gz
SERVER-58192 Fix memory leak in analyzeSort()
-rw-r--r--src/mongo/db/query/planner_analysis.cpp29
-rw-r--r--src/mongo/db/query/query_solution.cpp6
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();
}
//