1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-1510 Make changes to allow aggregations as function arguments when build in release mode. See also MDEV-16842.

This commit is contained in:
Roman Nozdrin
2018-08-30 16:59:41 +03:00
parent b46a98bb60
commit 62f296b443
5 changed files with 68 additions and 70 deletions

View File

@ -1187,18 +1187,6 @@ ha_calpont_group_by_handler::ha_calpont_group_by_handler(THD* thd_arg, Query* qu
order_by(query->order_by), order_by(query->order_by),
having(query->having) having(query->having)
{ {
List_iterator_fast<Item> item_iter(*select);
Item* item;
char* str = NULL;
while((item = item_iter++))
{
String descr;
item->print(&descr, QT_ORDINARY);
str = new char[descr.length()+1];
strncpy(str, descr.ptr(), descr.length());
str[descr.length()] = '\0';
select_list_descr.push_back(str);
}
} }
/*********************************************************** /***********************************************************
@ -1207,7 +1195,6 @@ ha_calpont_group_by_handler::ha_calpont_group_by_handler(THD* thd_arg, Query* qu
***********************************************************/ ***********************************************************/
ha_calpont_group_by_handler::~ha_calpont_group_by_handler() ha_calpont_group_by_handler::~ha_calpont_group_by_handler()
{ {
select_list_descr.delete_elements();
} }
/*********************************************************** /***********************************************************

View File

@ -286,7 +286,6 @@ public:
int end_scan(); int end_scan();
List<Item>* select; List<Item>* select;
List<char> select_list_descr;
TABLE_LIST* table_list; TABLE_LIST* table_list;
bool distinct; bool distinct;
Item* where; Item* where;

View File

@ -190,21 +190,57 @@ bool nonConstFunc(Item_func* ifp)
return false; return false;
} }
ReturnedColumn* findCorrespTempField(Item_ref* item, gp_walk_info& gwi, bool clone = true) /*@brief buildAggFrmTempField- build aggr func from extSELECT list item*/
/***********************************************************
* DESCRIPTION:
* Server adds additional aggregation items to extended SELECT list and
* references them in projection and HAVING. This f() finds
* corresponding item in extSelAggColsItems and builds
* ReturnedColumn using the item.
* PARAMETERS:
* item Item* used to build aggregation
* gwi main structure
* RETURNS
* ReturnedColumn* if corresponding Item has been found
* NULL otherwise
***********************************************************/
ReturnedColumn* buildAggFrmTempField(Item* item, gp_walk_info& gwi)
{ {
ReturnedColumn* result = NULL; ReturnedColumn* result = NULL;
uint32_t i; Item_field* ifip = NULL;
for (i = 0; i < gwi.returnedCols.size(); i++) Item_ref* irip;
Item_func_or_sum* isfp;
switch ( item->type() )
{ {
if (item->ref[0] && item->ref[0]->name.length && case Item::FIELD_ITEM:
gwi.returnedCols[i]->alias().c_str() && ifip = reinterpret_cast<Item_field*>(item);
!strcasecmp(item->ref[0]->name.str, gwi.returnedCols[i]->alias().c_str()))
{
if (clone)
result = gwi.returnedCols[i]->clone();
else
result = gwi.returnedCols[i].get();
break; break;
default:
irip = reinterpret_cast<Item_ref*>(item);
if ( irip )
ifip = reinterpret_cast<Item_field*>(irip->ref[0]);
break;
}
if (ifip && ifip->field)
{
std::vector<Item*>::iterator iter = gwi.extSelAggColsItems.begin();
for ( ; iter != gwi.extSelAggColsItems.end(); iter++ )
{
//Item* temp_isfp = *iter;
isfp = reinterpret_cast<Item_func_or_sum*>(*iter);
if ( isfp->type() == Item::SUM_FUNC_ITEM &&
isfp->result_field == ifip->field )
{
ReturnedColumn* rc = buildAggregateColumn(isfp, gwi);
if (rc)
result = rc;
break;
}
} }
} }
@ -3101,7 +3137,10 @@ ArithmeticColumn* buildArithmeticColumn(
{ {
// There must be an aggregation column in extended SELECT // There must be an aggregation column in extended SELECT
// list so find the corresponding column. // list so find the corresponding column.
ReturnedColumn* rc = findCorrespTempField(static_cast<Item_ref*>(sfitempp[0]), gwi); // Could have it set if there are aggregation funcs as this function arguments.
gwi.fatalParseError = false;
ReturnedColumn* rc = buildAggFrmTempField(sfitempp[0], gwi);
if(rc) if(rc)
lhs = new ParseTree(rc); lhs = new ParseTree(rc);
} }
@ -3117,7 +3156,10 @@ ArithmeticColumn* buildArithmeticColumn(
{ {
// There must be an aggregation column in extended SELECT // There must be an aggregation column in extended SELECT
// list so find the corresponding column. // list so find the corresponding column.
ReturnedColumn* rc = findCorrespTempField(static_cast<Item_ref*>(sfitempp[1]), gwi); // Could have it set if there are aggregation funcs as this function arguments.
gwi.fatalParseError = false;
ReturnedColumn* rc = buildAggFrmTempField(sfitempp[1], gwi);
if(rc) if(rc)
rhs = new ParseTree(rc); rhs = new ParseTree(rc);
} }
@ -3456,10 +3498,11 @@ ReturnedColumn* buildFunctionColumn(
ReturnedColumn* rc = buildReturnedColumn(ifp->arguments()[i], gwi, nonSupport, pushdownHand); ReturnedColumn* rc = buildReturnedColumn(ifp->arguments()[i], gwi, nonSupport, pushdownHand);
// MCOL-1510 It must be a temp table field, so find the corresponding column. // MCOL-1510 It must be a temp table field, so find the corresponding column.
if (pushdownHand if (!rc && pushdownHand
&& ifp->arguments()[i]->type() == Item::REF_ITEM) && ifp->arguments()[i]->type() == Item::REF_ITEM)
{ {
rc = findCorrespTempField(static_cast<Item_ref*>(ifp->arguments()[i]), gwi); gwi.fatalParseError = false;
rc = buildAggFrmTempField(ifp->arguments()[i], gwi);
} }
if (!rc || nonSupport) if (!rc || nonSupport)
@ -5344,26 +5387,9 @@ void gp_walk(const Item* item, void* arg)
} }
else if (col->type() == Item::FIELD_ITEM && gwip->clauseType == HAVING) else if (col->type() == Item::FIELD_ITEM && gwip->clauseType == HAVING)
{ {
Item_field* ifip = static_cast<Item_field*>(col); ReturnedColumn* rc = buildAggFrmTempField(const_cast<Item*>(item), *gwip);
std::vector<Item*>::iterator iter = gwip->havingAggColsItems.begin(); if (rc)
Item_func_or_sum* isfp = NULL; gwip->rcWorkStack.push(rc);
for ( ; iter != gwip->havingAggColsItems.end(); iter++ )
{
Item* temp_isfp = *iter;
isfp = reinterpret_cast<Item_func_or_sum*>(temp_isfp);
if ( isfp->type() == Item::SUM_FUNC_ITEM &&
isfp->result_field == ifip->field )
{
ReturnedColumn* rc = buildAggregateColumn(isfp, *gwip);
if (rc)
gwip->rcWorkStack.push(rc);
break;
}
}
break; break;
} }
@ -5628,7 +5654,7 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
// and set hasNonSupportItem if it is so. // and set hasNonSupportItem if it is so.
ReturnedColumn* rc = NULL; ReturnedColumn* rc = NULL;
if (gwi) if (gwi)
rc = findCorrespTempField(ref, *gwi, false); rc = buildAggFrmTempField(ref, *gwi);
if (!rc) if (!rc)
{ {
@ -8238,12 +8264,13 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi)
SELECT_LEX select_lex = lex->select_lex; SELECT_LEX select_lex = lex->select_lex;
gp_walk_info gwi; gp_walk_info gwi;
gwi.thd = thd; gwi.thd = thd;
gwi.groupByAuxDescr = gi.groupByAuxDescr;
int status = getGroupPlan(gwi, select_lex, csep, gi); int status = getGroupPlan(gwi, select_lex, csep, gi);
#ifdef DEBUG_WALK_COND
cerr << "---------------- cp_get_group_plan EXECUTION PLAN ----------------" << endl; cerr << "---------------- cp_get_group_plan EXECUTION PLAN ----------------" << endl;
cerr << *csep << endl ; cerr << *csep << endl ;
cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
#endif
if (status > 0) if (status > 0)
return ER_INTERNAL_ERROR; return ER_INTERNAL_ERROR;
@ -8620,8 +8647,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
string sel_cols_in_create; string sel_cols_in_create;
string sel_cols_in_select; string sel_cols_in_select;
bool redo = false; bool redo = false;
List_iterator_fast<char> itDescr(*gi.groupByAuxDescr);
char* fieldDescr;
// empty rcWorkStack and ptWorkStack. They should all be empty by now. // empty rcWorkStack and ptWorkStack. They should all be empty by now.
clearStacks(gwi); clearStacks(gwi);
@ -8640,14 +8665,12 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
while ((item = it++)) while ((item = it++))
{ {
// Given the size of gi.groupByAuxDescr is equal to gi.groupByFields
fieldDescr = itDescr++;
string itemAlias; string itemAlias;
if(item->name.length) if(item->name.length)
itemAlias = (item->name.str); itemAlias = (item->name.str);
else else
{ {
itemAlias = (fieldDescr ? fieldDescr: "<NULL>"); itemAlias = "<NULL>";
} }
// @bug 5916. Need to keep checking until getting concret item in case // @bug 5916. Need to keep checking until getting concret item in case
@ -8754,18 +8777,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
return ER_CHECK_NOT_IMPLEMENTED; return ER_CHECK_NOT_IMPLEMENTED;
} }
if(!ac->alias().length())
ac->alias(fieldDescr);
// add this agg col to returnedColumnList // add this agg col to returnedColumnList
boost::shared_ptr<ReturnedColumn> spac(ac); boost::shared_ptr<ReturnedColumn> spac(ac);
gwi.returnedCols.push_back(spac); gwi.returnedCols.push_back(spac);
// This item will be used in HAVING later. // This item could be used in projection or HAVING later.
Item_func_or_sum* isfp = reinterpret_cast<Item_func_or_sum*>(item); gwi.extSelAggColsItems.push_back(item);
if ( ! isfp->name.length )
{
gwi.havingAggColsItems.push_back(item);
}
gwi.selectCols.push_back('`' + escapeBackTick(spac->alias().c_str()) + '`'); gwi.selectCols.push_back('`' + escapeBackTick(spac->alias().c_str()) + '`');
String str(256); String str(256);

View File

@ -5265,7 +5265,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE
// MCOL-1052 Send Items lists down to the optimizer. // MCOL-1052 Send Items lists down to the optimizer.
gi.groupByTables = group_hand->table_list; gi.groupByTables = group_hand->table_list;
gi.groupByFields = group_hand->select; gi.groupByFields = group_hand->select;
gi.groupByAuxDescr = &group_hand->select_list_descr;
gi.groupByWhere = group_hand->where; gi.groupByWhere = group_hand->where;
gi.groupByGroup = group_hand->group_by; gi.groupByGroup = group_hand->group_by;
gi.groupByOrder = group_hand->order_by; gi.groupByOrder = group_hand->order_by;

View File

@ -99,7 +99,7 @@ struct gp_walk_info
execplan::CalpontSelectExecutionPlan::ReturnedColumnList groupByCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList groupByCols;
execplan::CalpontSelectExecutionPlan::ReturnedColumnList subGroupByCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList subGroupByCols;
execplan::CalpontSelectExecutionPlan::ReturnedColumnList orderByCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList orderByCols;
std::vector <Item*> havingAggColsItems; std::vector <Item*> extSelAggColsItems;
execplan::CalpontSelectExecutionPlan::ColumnMap columnMap; execplan::CalpontSelectExecutionPlan::ColumnMap columnMap;
// This vector temporarily hold the projection columns to be added // This vector temporarily hold the projection columns to be added
// to the returnedCols vector for subquery processing. It will be appended // to the returnedCols vector for subquery processing. It will be appended
@ -142,7 +142,6 @@ struct gp_walk_info
std::map<std::string, execplan::ParseTree*> derivedTbFilterMap; std::map<std::string, execplan::ParseTree*> derivedTbFilterMap;
uint32_t derivedTbCnt; uint32_t derivedTbCnt;
std::vector<execplan::SCSEP> subselectList; std::vector<execplan::SCSEP> subselectList;
List<char>* groupByAuxDescr;
// Kludge for Bug 750 // Kludge for Bug 750
int32_t recursionLevel; int32_t recursionLevel;
@ -200,7 +199,6 @@ struct cal_table_info
struct cal_group_info struct cal_group_info
{ {
cal_group_info() : groupByFields(0), cal_group_info() : groupByFields(0),
groupByAuxDescr(0),
groupByTables(0), groupByTables(0),
groupByWhere(0), groupByWhere(0),
groupByGroup(0), groupByGroup(0),
@ -211,7 +209,6 @@ struct cal_group_info
~cal_group_info() { } ~cal_group_info() { }
List<Item>* groupByFields; // MCOL-1052 SELECT List<Item>* groupByFields; // MCOL-1052 SELECT
List<char>* groupByAuxDescr; //MCOL-1052 Auxilary column descriptions
TABLE_LIST* groupByTables; // MCOL-1052 FROM TABLE_LIST* groupByTables; // MCOL-1052 FROM
Item* groupByWhere; // MCOL-1052 WHERE Item* groupByWhere; // MCOL-1052 WHERE
ORDER* groupByGroup; // MCOL-1052 GROUP BY ORDER* groupByGroup; // MCOL-1052 GROUP BY