1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-01 06:46:55 +03:00

MCOL-4043 Fix memory leaks - 1

simpleScalarFilterToParseTree() performs a dynamic allocation
of a ParseTree object, but this memory is never freed later.
We now keep track of this allocation and perform the delete
in the JobList dtor after the query finishes.
This commit is contained in:
Gagan Goel
2020-06-11 19:01:40 -04:00
parent feee26f1ab
commit 881091c535
7 changed files with 54 additions and 2 deletions

View File

@ -150,8 +150,14 @@ SimpleFilter::SimpleFilter(const SimpleFilter& rhs) :
SimpleFilter::~SimpleFilter() SimpleFilter::~SimpleFilter()
{ {
//delete fOp; //delete fOp;
if (fLhs != NULL)
delete fLhs; delete fLhs;
if (fRhs != NULL)
delete fRhs; delete fRhs;
fLhs = NULL;
fRhs = NULL;
} }
/** /**

View File

@ -364,6 +364,11 @@ struct JobInfo
bool isDML; bool isDML;
std::string timeZone; std::string timeZone;
// This is for tracking any dynamically allocated ParseTree objects
// in simpleScalarFilterToParseTree() for later deletion in
// JobList::~JobList()
std::vector<std::pair<execplan::ParseTree*, execplan::ParseTree*>> dynamicParseTreeVec;
private: private:
//defaults okay //defaults okay
//JobInfo(const JobInfo& rhs); //JobInfo(const JobInfo& rhs);

View File

@ -3269,6 +3269,12 @@ void doOR(ParseTree* n, JobInfo& jobInfo, bool tryCombine)
ccp->left(parseTree->left()); ccp->left(parseTree->left());
ccp->right(parseTree->right()); ccp->right(parseTree->right());
ccp->data(parseTree->data()); ccp->data(parseTree->data());
jobInfo.dynamicParseTreeVec.push_back(make_pair(parseTree, ccp));
}
else if (parseTree)
{
delete parseTree;
parseTree = NULL;
} }
} }

View File

@ -192,7 +192,10 @@ void ssfInHaving(ParseTree* pt, void* obj)
pt->right(parseTree->right()); pt->right(parseTree->right());
pt->data(parseTree->data()); pt->data(parseTree->data());
jobInfo->dynamicParseTreeVec.push_back(make_pair(parseTree, pt));
// don't delete the parseTree, it has been placed in the plan. // don't delete the parseTree, it has been placed in the plan.
// Instead, we use the dynamicParseTreeVec above for deletion
// in the JobList dtor after the query executes.
// delete parseTree; // delete parseTree;
} }
else else
@ -627,7 +630,10 @@ void doSimpleScalarFilter(ParseTree* p, JobInfo& jobInfo)
// create job steps for each simple filter // create job steps for each simple filter
JLF_ExecPlanToJobList::walkTree(parseTree, jobInfo); JLF_ExecPlanToJobList::walkTree(parseTree, jobInfo);
jobInfo.dynamicParseTreeVec.push_back(make_pair(parseTree, ccp));
// don't delete the parseTree, it has been placed in the plan. // don't delete the parseTree, it has been placed in the plan.
// Instead, we use the dynamicParseTreeVec above for deletion
// in the JobList dtor after the query executes.
// delete parseTree; // delete parseTree;
} }
else else

View File

@ -142,6 +142,26 @@ JobList::~JobList()
(*iter)->join(); (*iter)->join();
} }
} }
for (auto& parseTree : fDynamicParseTreeVec)
{
if (parseTree.first)
{
delete parseTree.first;
parseTree.first = NULL;
// Note that we don't delete parseTree.second here,
// that is handled by CalpontSelectExecutionPlan::unserialize().
// parseTree.first already deleted the objects pointed to by
// parseTree.second->left()/right()/data(), so we set the
// pointers to NULL here.
if (parseTree.second)
{
parseTree.second->left((ParseTree*) (NULL));
parseTree.second->right((ParseTree*) (NULL));
parseTree.second->data((TreeNode*) (NULL));
}
}
}
} }
catch (exception& ex) catch (exception& ex)
{ {

View File

@ -34,6 +34,7 @@
#include "jobstep.h" #include "jobstep.h"
#include "bytestream.h" #include "bytestream.h"
#include "parsetree.h"
#ifndef __GNUC__ #ifndef __GNUC__
# ifndef __attribute__ # ifndef __attribute__
@ -190,6 +191,12 @@ public:
fPmsConfigured = pms; fPmsConfigured = pms;
} }
virtual void setDynamicParseTreeVec(
const std::vector<std::pair<execplan::ParseTree*, execplan::ParseTree*>>& dynamicParseTreeVec)
{
fDynamicParseTreeVec = dynamicParseTreeVec;
}
protected: protected:
//defaults okay //defaults okay
//JobList(const JobList& rhs); //JobList(const JobList& rhs);
@ -217,6 +224,7 @@ protected:
volatile uint32_t fAborted; volatile uint32_t fAborted;
uint32_t fPriority; //higher #s = higher priority uint32_t fPriority; //higher #s = higher priority
std::vector<std::pair<execplan::ParseTree*, execplan::ParseTree*>> fDynamicParseTreeVec;
}; };
class TupleJobList : public JobList class TupleJobList : public JobList

View File

@ -2003,6 +2003,7 @@ SJLP makeJobList_(
jl->addQuery(querySteps); jl->addQuery(querySteps);
jl->addProject(projectSteps); jl->addProject(projectSteps);
jl->addDelivery(deliverySteps); jl->addDelivery(deliverySteps);
jl->setDynamicParseTreeVec(jobInfo.dynamicParseTreeVec);
dynamic_cast<TupleJobList*>(jl)->setDeliveryFlag(true); dynamic_cast<TupleJobList*>(jl)->setDeliveryFlag(true);
} }