You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-02 17:22:27 +03:00
fix(memory leaks): MCOL-5791 - get rid of memory leaks in plugin code
There were numerous memory leaks in plugin's code and associated code. During typical run of MTR tests it leaked around 65 megabytes of objects. As a result they may severely affect long-lived connections. This patch fixes (almost) all leaks found in the plugin. The exceptions are two leaks associated with SHOW CREATE TABLE columnstore_table and getting information of columns of columnstore-handled table. These should be fixed on the server side and work is on the way.
This commit is contained in:
committed by
Sergey Zefirov
parent
6445f4dff3
commit
38fd96a663
@ -293,13 +293,66 @@ string escapeBackTick(const char* str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void clearStacks(gp_walk_info& gwi)
|
||||
cal_impl_if::gp_walk_info::~gp_walk_info()
|
||||
{
|
||||
while (!rcWorkStack.empty())
|
||||
{
|
||||
delete rcWorkStack.top();
|
||||
rcWorkStack.pop();
|
||||
}
|
||||
|
||||
while (!ptWorkStack.empty())
|
||||
{
|
||||
delete ptWorkStack.top();
|
||||
ptWorkStack.pop();
|
||||
}
|
||||
for (uint32_t i=0;i<viewList.size();i++) {
|
||||
delete viewList[i];
|
||||
}
|
||||
viewList.clear();
|
||||
}
|
||||
|
||||
void clearStacks(gp_walk_info& gwi, bool andViews = true, bool mayDelete = false)
|
||||
{
|
||||
while (!gwi.rcWorkStack.empty())
|
||||
{
|
||||
if (mayDelete)
|
||||
{
|
||||
delete gwi.rcWorkStack.top();
|
||||
}
|
||||
gwi.rcWorkStack.pop();
|
||||
}
|
||||
|
||||
while (!gwi.ptWorkStack.empty())
|
||||
{
|
||||
if (mayDelete)
|
||||
{
|
||||
delete gwi.ptWorkStack.top();
|
||||
}
|
||||
gwi.ptWorkStack.pop();
|
||||
}
|
||||
if (andViews)
|
||||
{
|
||||
gwi.viewList.clear();
|
||||
}
|
||||
}
|
||||
void clearDeleteStacks(gp_walk_info& gwi)
|
||||
{
|
||||
while (!gwi.rcWorkStack.empty())
|
||||
{
|
||||
delete gwi.rcWorkStack.top();
|
||||
gwi.rcWorkStack.pop();
|
||||
}
|
||||
|
||||
while (!gwi.ptWorkStack.empty())
|
||||
{
|
||||
delete gwi.ptWorkStack.top();
|
||||
gwi.ptWorkStack.pop();
|
||||
}
|
||||
for (uint32_t i=0;i<gwi.viewList.size();i++) {
|
||||
delete gwi.viewList[i];
|
||||
}
|
||||
gwi.viewList.clear();
|
||||
}
|
||||
|
||||
bool nonConstFunc(Item_func* ifp)
|
||||
@ -1512,6 +1565,7 @@ uint32_t buildJoin(gp_walk_info& gwi, List<TABLE_LIST>& join_list,
|
||||
ParseTree* pt = new ParseTree(onFilter);
|
||||
outerJoinStack.push(pt);
|
||||
}
|
||||
|
||||
}
|
||||
else // inner join
|
||||
{
|
||||
@ -1545,7 +1599,7 @@ ParseTree* buildRowPredicate(gp_walk_info* gwip, RowColumn* lhs, RowColumn* rhs,
|
||||
|
||||
ParseTree* pt = new ParseTree(lo);
|
||||
sop->setOpType(lhs->columnVec()[0]->resultType(), rhs->columnVec()[0]->resultType());
|
||||
SimpleFilter* sf = new SimpleFilter(sop, lhs->columnVec()[0].get(), rhs->columnVec()[0].get());
|
||||
SimpleFilter* sf = new SimpleFilter(sop, lhs->columnVec()[0]->clone(), rhs->columnVec()[0]->clone());
|
||||
sf->timeZone(gwip->timeZone);
|
||||
pt->left(new ParseTree(sf));
|
||||
|
||||
@ -1553,7 +1607,7 @@ ParseTree* buildRowPredicate(gp_walk_info* gwip, RowColumn* lhs, RowColumn* rhs,
|
||||
{
|
||||
sop.reset(po->clone());
|
||||
sop->setOpType(lhs->columnVec()[i]->resultType(), rhs->columnVec()[i]->resultType());
|
||||
SimpleFilter* sf = new SimpleFilter(sop, lhs->columnVec()[i].get(), rhs->columnVec()[i].get());
|
||||
SimpleFilter* sf = new SimpleFilter(sop, lhs->columnVec()[i]->clone(), rhs->columnVec()[i]->clone());
|
||||
sf->timeZone(gwip->timeZone);
|
||||
pt->right(new ParseTree(sf));
|
||||
|
||||
@ -1570,6 +1624,12 @@ ParseTree* buildRowPredicate(gp_walk_info* gwip, RowColumn* lhs, RowColumn* rhs,
|
||||
|
||||
bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, Item_func* ifp)
|
||||
{
|
||||
// rhs and lhs are being dismembered here and then get thrown away, leaking.
|
||||
// So we create two scoped pointers to get them delete'd automatically at
|
||||
// return.
|
||||
// Also look below into heldoutVals vector - it contains values produced from
|
||||
// ifp's arguments.
|
||||
const std::unique_ptr<RowColumn> rhsp(rhs), lhsp(lhs);
|
||||
if (ifp->functype() == Item_func::EQ_FUNC || ifp->functype() == Item_func::NE_FUNC)
|
||||
{
|
||||
// (c1,c2,..) = (v1,v2,...) transform to: c1=v1 and c2=v2 and ...
|
||||
@ -1601,6 +1661,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
|
||||
// two entries have been popped from the stack already: lhs and rhs
|
||||
stack<ReturnedColumn*> tmpStack;
|
||||
vector<RowColumn*> valVec;
|
||||
vector<SRCP> heldOutVals; // these vals are not rhs/lhs and need to be freed
|
||||
tmpStack.push(rhs);
|
||||
tmpStack.push(lhs);
|
||||
assert(gwip->rcWorkStack.size() >= ifp->argument_count() - 2);
|
||||
@ -1608,6 +1669,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
|
||||
for (uint32_t i = 2; i < ifp->argument_count(); i++)
|
||||
{
|
||||
tmpStack.push(gwip->rcWorkStack.top());
|
||||
heldOutVals.push_back(SRCP(gwip->rcWorkStack.top()));
|
||||
|
||||
if (!gwip->rcWorkStack.empty())
|
||||
gwip->rcWorkStack.pop();
|
||||
@ -1627,7 +1689,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
|
||||
vals = dynamic_cast<RowColumn*>(tmpStack.top());
|
||||
valVec.push_back(vals);
|
||||
tmpStack.pop();
|
||||
pt1->right(buildRowPredicate(gwip, columns->clone(), vals, predicateOp));
|
||||
pt1->right(buildRowPredicate(gwip, columns, vals, predicateOp));
|
||||
pt = pt1;
|
||||
}
|
||||
|
||||
@ -1644,7 +1706,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
|
||||
|
||||
for (uint32_t i = 0; i < columns->columnVec().size(); i++)
|
||||
{
|
||||
ConstantFilter* cf = new ConstantFilter();
|
||||
std::unique_ptr<ConstantFilter> cf(new ConstantFilter());
|
||||
|
||||
sop.reset(lo->clone());
|
||||
cf->op(sop);
|
||||
@ -1652,7 +1714,9 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
|
||||
|
||||
// no optimization for non-simple column because CP won't apply
|
||||
if (!sc)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ssc.reset(sc->clone());
|
||||
cf->col(ssc);
|
||||
@ -1674,9 +1738,11 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
|
||||
}
|
||||
|
||||
if (j < valVec.size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tmpPtStack.push(new ParseTree(cf));
|
||||
tmpPtStack.push(new ParseTree(cf.release()));
|
||||
}
|
||||
|
||||
// "and" all the filters together
|
||||
@ -2027,7 +2093,10 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
||||
}
|
||||
|
||||
if (!gwip->rcWorkStack.empty())
|
||||
{
|
||||
delete gwip->rcWorkStack.top();
|
||||
gwip->rcWorkStack.pop(); // pop gwip->scsp
|
||||
}
|
||||
|
||||
if (cf->filterList().size() < inp->argument_count() - 1)
|
||||
{
|
||||
@ -2839,7 +2908,6 @@ void setError(THD* thd, uint32_t errcode, string errmsg)
|
||||
void setError(THD* thd, uint32_t errcode, string errmsg, gp_walk_info& gwi)
|
||||
{
|
||||
setError(thd, errcode, errmsg);
|
||||
clearStacks(gwi);
|
||||
}
|
||||
|
||||
int setErrorAndReturn(gp_walk_info& gwi)
|
||||
@ -4114,6 +4182,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non
|
||||
if (!sptp)
|
||||
{
|
||||
nonSupport = true;
|
||||
delete fc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4128,6 +4197,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non
|
||||
nonSupport = true;
|
||||
gwi.fatalParseError = true;
|
||||
gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_SUB_EXPRESSION);
|
||||
delete fc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4159,6 +4229,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non
|
||||
if (!rc || nonSupport)
|
||||
{
|
||||
nonSupport = true;
|
||||
delete fc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4187,6 +4258,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non
|
||||
else
|
||||
{
|
||||
nonSupport = true;
|
||||
delete fc;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -4583,6 +4655,7 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS
|
||||
gwi.inCaseStmt = false;
|
||||
if (!gwi.ptWorkStack.empty() && *gwi.ptWorkStack.top() == *sptp.get())
|
||||
{
|
||||
delete gwi.ptWorkStack.top();
|
||||
gwi.ptWorkStack.pop();
|
||||
}
|
||||
}
|
||||
@ -4603,6 +4676,7 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS
|
||||
// We need to pop whichever stack is holding it, if any.
|
||||
if ((!gwi.rcWorkStack.empty()) && *gwi.rcWorkStack.top() == parm)
|
||||
{
|
||||
delete gwi.rcWorkStack.top();
|
||||
gwi.rcWorkStack.pop();
|
||||
}
|
||||
else if (!gwi.ptWorkStack.empty())
|
||||
@ -4610,7 +4684,10 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS
|
||||
ReturnedColumn* ptrc = dynamic_cast<ReturnedColumn*>(gwi.ptWorkStack.top()->data());
|
||||
|
||||
if (ptrc && *ptrc == *parm)
|
||||
{
|
||||
delete gwi.ptWorkStack.top();
|
||||
gwi.ptWorkStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -4620,6 +4697,7 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS
|
||||
// We need to pop whichever stack is holding it, if any.
|
||||
if ((!gwi.ptWorkStack.empty()) && *gwi.ptWorkStack.top()->data() == sptp->data())
|
||||
{
|
||||
delete gwi.ptWorkStack.top();
|
||||
gwi.ptWorkStack.pop();
|
||||
}
|
||||
else if (!gwi.rcWorkStack.empty())
|
||||
@ -4630,6 +4708,7 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS
|
||||
|
||||
if (ptrc && *ptrc == *gwi.rcWorkStack.top())
|
||||
{
|
||||
delete gwi.rcWorkStack.top();
|
||||
gwi.rcWorkStack.pop();
|
||||
}
|
||||
}
|
||||
@ -5301,6 +5380,18 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
||||
ac->constCol(SRCP(rc));
|
||||
break;
|
||||
}
|
||||
// the "rc" can be in gwi.no_parm_func_list. erase it from that list and
|
||||
// then delete it.
|
||||
// kludge, I know.
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; gwi.no_parm_func_list[i] != rc && i < gwi.no_parm_func_list.size(); i++) { }
|
||||
|
||||
if (i < gwi.no_parm_func_list.size())
|
||||
{
|
||||
gwi.no_parm_func_list.erase(gwi.no_parm_func_list.begin() + i);
|
||||
delete rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5996,7 +6087,10 @@ void gp_walk(const Item* item, void* arg)
|
||||
{
|
||||
// @bug 4215. remove the argument in rcWorkStack.
|
||||
if (!gwip->rcWorkStack.empty())
|
||||
{
|
||||
delete gwip->rcWorkStack.top();
|
||||
gwip->rcWorkStack.pop();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@ -6031,6 +6125,7 @@ void gp_walk(const Item* item, void* arg)
|
||||
|
||||
for (uint32_t i = 0; i < ifp->argument_count() && !gwip->rcWorkStack.empty(); i++)
|
||||
{
|
||||
delete gwip->rcWorkStack.top();
|
||||
gwip->rcWorkStack.pop();
|
||||
}
|
||||
|
||||
@ -6207,6 +6302,7 @@ void gp_walk(const Item* item, void* arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
delete rhs;
|
||||
gwip->ptWorkStack.push(lhs);
|
||||
continue;
|
||||
}
|
||||
@ -6740,21 +6836,21 @@ int processFrom(bool& isUnion, SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP&
|
||||
if (table_ptr->derived)
|
||||
{
|
||||
SELECT_LEX* select_cursor = table_ptr->derived->first_select();
|
||||
FromSubQuery fromSub(gwi, select_cursor);
|
||||
FromSubQuery* fromSub = new FromSubQuery(gwi, select_cursor);
|
||||
string alias(table_ptr->alias.str);
|
||||
if (lower_case_table_names)
|
||||
{
|
||||
boost::algorithm::to_lower(alias);
|
||||
}
|
||||
fromSub.alias(alias);
|
||||
fromSub->alias(alias);
|
||||
|
||||
CalpontSystemCatalog::TableAliasName tn = make_aliasview("", "", alias, viewName);
|
||||
// @bug 3852. check return execplan
|
||||
SCSEP plan = fromSub.transform();
|
||||
SCSEP plan = fromSub->transform();
|
||||
|
||||
if (!plan)
|
||||
{
|
||||
setError(gwi.thd, ER_INTERNAL_ERROR, fromSub.gwip().parseErrorText, gwi);
|
||||
setError(gwi.thd, ER_INTERNAL_ERROR, fromSub->gwip().parseErrorText, gwi);
|
||||
CalpontSystemCatalog::removeCalpontSystemCatalog(gwi.sessionid);
|
||||
return ER_INTERNAL_ERROR;
|
||||
}
|
||||
@ -6878,7 +6974,7 @@ int processFrom(bool& isUnion, SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP&
|
||||
plan->data(csep->data());
|
||||
|
||||
// gwi for the union unit
|
||||
gp_walk_info union_gwi(gwi.timeZone);
|
||||
gp_walk_info union_gwi(gwi.timeZone, gwi.subQueriesChain);
|
||||
union_gwi.thd = gwi.thd;
|
||||
uint32_t err = 0;
|
||||
|
||||
@ -7081,14 +7177,28 @@ int processWhere(SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP& csep, const s
|
||||
std::stack<execplan::ParseTree*> outerJoinStack;
|
||||
|
||||
if ((failed = buildJoin(gwi, select_lex.top_join_list, outerJoinStack)))
|
||||
{
|
||||
while (!outerJoinStack.empty())
|
||||
{
|
||||
delete outerJoinStack.top();
|
||||
outerJoinStack.pop();
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
if (gwi.subQuery)
|
||||
{
|
||||
for (uint i = 0; i < gwi.viewList.size(); i++)
|
||||
{
|
||||
if ((failed = gwi.viewList[i]->processJoin(gwi, outerJoinStack)))
|
||||
{
|
||||
while (!outerJoinStack.empty())
|
||||
{
|
||||
delete outerJoinStack.top();
|
||||
outerJoinStack.pop();
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7103,7 +7213,7 @@ int processWhere(SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP& csep, const s
|
||||
// is pushed to rcWorkStack.
|
||||
if (gwi.ptWorkStack.empty() && !gwi.rcWorkStack.empty())
|
||||
{
|
||||
filters = new ParseTree(gwi.rcWorkStack.top());
|
||||
gwi.ptWorkStack.push(new ParseTree(gwi.rcWorkStack.top()));
|
||||
gwi.rcWorkStack.pop();
|
||||
}
|
||||
|
||||
@ -7156,6 +7266,7 @@ int processWhere(SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP& csep, const s
|
||||
"columnstore_max_allowed_in_values "
|
||||
"threshold.",
|
||||
gwi);
|
||||
delete filters;
|
||||
return ER_CHECK_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -7180,6 +7291,26 @@ int processWhere(SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP& csep, const s
|
||||
csep->filters(filters);
|
||||
}
|
||||
|
||||
if (!gwi.rcWorkStack.empty())
|
||||
{
|
||||
while(!gwi.rcWorkStack.empty())
|
||||
{
|
||||
ReturnedColumn* t = gwi.rcWorkStack.top();
|
||||
delete t;
|
||||
gwi.rcWorkStack.pop();
|
||||
}
|
||||
}
|
||||
if (!gwi.ptWorkStack.empty())
|
||||
{
|
||||
while(!gwi.ptWorkStack.empty())
|
||||
{
|
||||
ParseTree* t = gwi.ptWorkStack.top();
|
||||
delete t;
|
||||
gwi.ptWorkStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7515,7 +7646,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
vector<Item_field*> funcFieldVec;
|
||||
|
||||
// empty rcWorkStack and ptWorkStack. They should all be empty by now.
|
||||
clearStacks(gwi);
|
||||
clearStacks(gwi, false, true);
|
||||
|
||||
// indicate the starting pos of scalar returned column, because some join column
|
||||
// has been inserted to the returned column list.
|
||||
@ -7852,6 +7983,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
gwi.parseErrorText = "Unsupported Item in SELECT subquery.";
|
||||
|
||||
setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi);
|
||||
|
||||
return ER_CHECK_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -7963,8 +8095,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
|
||||
// Having clause handling
|
||||
gwi.clauseType = HAVING;
|
||||
clearStacks(gwi);
|
||||
ParseTree* havingFilter = 0;
|
||||
clearStacks(gwi, false, true);
|
||||
std::unique_ptr<ParseTree> havingFilter;
|
||||
// clear fatalParseError that may be left from post process functions
|
||||
gwi.fatalParseError = false;
|
||||
gwi.parseErrorText = "";
|
||||
@ -7990,20 +8122,20 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
// @bug 4215. some function filter will be in the rcWorkStack.
|
||||
if (gwi.ptWorkStack.empty() && !gwi.rcWorkStack.empty())
|
||||
{
|
||||
havingFilter = new ParseTree(gwi.rcWorkStack.top());
|
||||
gwi.ptWorkStack.push(new ParseTree(gwi.rcWorkStack.top()));
|
||||
gwi.rcWorkStack.pop();
|
||||
}
|
||||
|
||||
while (!gwi.ptWorkStack.empty())
|
||||
{
|
||||
havingFilter = gwi.ptWorkStack.top();
|
||||
havingFilter.reset(gwi.ptWorkStack.top());
|
||||
gwi.ptWorkStack.pop();
|
||||
|
||||
if (gwi.ptWorkStack.empty())
|
||||
break;
|
||||
|
||||
ptp = new ParseTree(new LogicOperator("and"));
|
||||
ptp->left(havingFilter);
|
||||
ptp->left(havingFilter.release());
|
||||
rhs = gwi.ptWorkStack.top();
|
||||
gwi.ptWorkStack.pop();
|
||||
ptp->right(rhs);
|
||||
@ -8034,9 +8166,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
if (havingFilter)
|
||||
{
|
||||
ParseTree* ptp = new ParseTree(new LogicOperator("and"));
|
||||
ptp->left(havingFilter);
|
||||
ptp->left(havingFilter.release());
|
||||
ptp->right(inToExistsFilter);
|
||||
havingFilter = ptp;
|
||||
havingFilter.reset(ptp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8266,6 +8398,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
{
|
||||
if (strcasecmp(sc->alias().c_str(), gwi.returnedCols[j]->alias().c_str()) == 0)
|
||||
{
|
||||
delete rc;
|
||||
rc = gwi.returnedCols[j].get()->clone();
|
||||
rc->orderPos(j);
|
||||
break;
|
||||
@ -8278,6 +8411,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
{
|
||||
if (ifp->name.length && string(ifp->name.str) == gwi.returnedCols[j].get()->alias())
|
||||
{
|
||||
delete rc;
|
||||
rc = gwi.returnedCols[j].get()->clone();
|
||||
rc->orderPos(j);
|
||||
break;
|
||||
@ -8629,21 +8763,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
{
|
||||
}
|
||||
}
|
||||
else if (ord_item->type() == Item::FUNC_ITEM)
|
||||
{
|
||||
// @bug5636. check if this order by column is on the select list
|
||||
ReturnedColumn* rc = buildFunctionColumn((Item_func*)(ord_item), gwi, gwi.fatalParseError);
|
||||
|
||||
for (uint32_t i = 0; i < gwi.returnedCols.size(); i++)
|
||||
{
|
||||
if (rc && rc->operator==(gwi.returnedCols[i].get()))
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8746,20 +8865,28 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
csep->orderByCols(gwi.orderByCols);
|
||||
csep->returnedCols(gwi.returnedCols);
|
||||
csep->columnMap(gwi.columnMap);
|
||||
csep->having(havingFilter);
|
||||
csep->having(havingFilter.release());
|
||||
csep->derivedTableList(gwi.derivedTbList);
|
||||
csep->selectSubList(selectSubList);
|
||||
csep->subSelectList(gwi.subselectList);
|
||||
clearStacks(gwi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti, long timeZone)
|
||||
{
|
||||
gp_walk_info* gwi = ti.condInfo;
|
||||
|
||||
if (!gwi)
|
||||
gwi = new gp_walk_info(timeZone);
|
||||
SubQueryChainHolder chainHolder;
|
||||
bool allocated = false;
|
||||
gp_walk_info* gwi;
|
||||
if (ti.condInfo)
|
||||
{
|
||||
gwi = &ti.condInfo->gwi;
|
||||
}
|
||||
else
|
||||
{
|
||||
allocated = true;
|
||||
gwi = new gp_walk_info(timeZone, &chainHolder.chain);
|
||||
}
|
||||
|
||||
gwi->thd = thd;
|
||||
LEX* lex = thd->lex;
|
||||
@ -8810,7 +8937,7 @@ int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti, long timeZone)
|
||||
// get filter
|
||||
if (ti.condInfo)
|
||||
{
|
||||
gp_walk_info* gwi = ti.condInfo;
|
||||
gp_walk_info* gwi = &ti.condInfo->gwi;
|
||||
ParseTree* filters = 0;
|
||||
ParseTree* ptp = 0;
|
||||
ParseTree* rhs = 0;
|
||||
@ -8856,6 +8983,10 @@ int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti, long timeZone)
|
||||
// @bug 3321. Set max number of blocks in a dictionary file to be scanned for filtering
|
||||
csep->stringScanThreshold(get_string_scan_threshold(gwi->thd));
|
||||
|
||||
if (allocated)
|
||||
{
|
||||
delete gwi;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -8865,7 +8996,8 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi)
|
||||
const char* timeZone = thd->variables.time_zone->get_name()->ptr();
|
||||
long timeZoneOffset;
|
||||
dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset);
|
||||
gp_walk_info gwi(timeZoneOffset);
|
||||
SubQuery* chain = nullptr;
|
||||
gp_walk_info gwi(timeZoneOffset, &chain);
|
||||
gwi.thd = thd;
|
||||
gwi.isGroupByHandler = true;
|
||||
int status = getGroupPlan(gwi, *select_lex, csep, gi);
|
||||
@ -9003,6 +9135,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
#ifdef DEBUG_WALK_COND
|
||||
cerr << "getGroupPlan()" << endl;
|
||||
#endif
|
||||
idbassert_s(false, "getGroupPlan is utterly out of date");
|
||||
|
||||
// XXX: rollup is currently not supported (not tested) in this part.
|
||||
// but this is not triggered in any of tests.
|
||||
@ -9103,21 +9236,21 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
|
||||
SELECT_LEX* select_cursor = table_ptr->derived->first_select();
|
||||
// Use Pushdown handler for subquery processing
|
||||
FromSubQuery fromSub(gwi, select_cursor);
|
||||
FromSubQuery* fromSub = new FromSubQuery(gwi, select_cursor);
|
||||
string alias(table_ptr->alias.str);
|
||||
if (lower_case_table_names)
|
||||
{
|
||||
boost::algorithm::to_lower(alias);
|
||||
}
|
||||
fromSub.alias(alias);
|
||||
fromSub->alias(alias);
|
||||
|
||||
CalpontSystemCatalog::TableAliasName tn = make_aliasview("", "", alias, viewName);
|
||||
// @bug 3852. check return execplan
|
||||
SCSEP plan = fromSub.transform();
|
||||
SCSEP plan = fromSub->transform();
|
||||
|
||||
if (!plan)
|
||||
{
|
||||
setError(gwi.thd, ER_INTERNAL_ERROR, fromSub.gwip().parseErrorText, gwi);
|
||||
setError(gwi.thd, ER_INTERNAL_ERROR, fromSub->gwip().parseErrorText, gwi);
|
||||
CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID);
|
||||
return ER_INTERNAL_ERROR;
|
||||
}
|
||||
@ -9369,7 +9502,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
bool redo = false;
|
||||
|
||||
// empty rcWorkStack and ptWorkStack. They should all be empty by now.
|
||||
clearStacks(gwi);
|
||||
clearStacks(gwi, false);
|
||||
|
||||
// indicate the starting pos of scalar returned column, because some join column
|
||||
// has been inserted to the returned column list.
|
||||
@ -9819,7 +9952,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
|
||||
// Having clause handling
|
||||
gwi.clauseType = HAVING;
|
||||
clearStacks(gwi);
|
||||
clearStacks(gwi, false);
|
||||
ParseTree* havingFilter = 0;
|
||||
// clear fatalParseError that may be left from post process functions
|
||||
gwi.fatalParseError = false;
|
||||
|
Reference in New Issue
Block a user