From 62f296b4437df0ea27528a4c5c3e9435513109f9 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Thu, 30 Aug 2018 16:59:41 +0300 Subject: [PATCH] MCOL-1510 Make changes to allow aggregations as function arguments when build in release mode. See also MDEV-16842. --- dbcon/mysql/ha_calpont.cpp | 13 --- dbcon/mysql/ha_calpont.h | 1 - dbcon/mysql/ha_calpont_execplan.cpp | 118 ++++++++++++++++------------ dbcon/mysql/ha_calpont_impl.cpp | 1 - dbcon/mysql/ha_calpont_impl_if.h | 5 +- 5 files changed, 68 insertions(+), 70 deletions(-) diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index 6167054c5..8e906dd42 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -1187,18 +1187,6 @@ ha_calpont_group_by_handler::ha_calpont_group_by_handler(THD* thd_arg, Query* qu order_by(query->order_by), having(query->having) { - List_iterator_fast 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() { - select_list_descr.delete_elements(); } /*********************************************************** diff --git a/dbcon/mysql/ha_calpont.h b/dbcon/mysql/ha_calpont.h index 3c6f7e49e..e618ed4f0 100644 --- a/dbcon/mysql/ha_calpont.h +++ b/dbcon/mysql/ha_calpont.h @@ -286,7 +286,6 @@ public: int end_scan(); List* select; - List select_list_descr; TABLE_LIST* table_list; bool distinct; Item* where; diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 3fe05227d..da0fdbced 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -190,21 +190,57 @@ bool nonConstFunc(Item_func* ifp) 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; - uint32_t i; - for (i = 0; i < gwi.returnedCols.size(); i++) + Item_field* ifip = NULL; + Item_ref* irip; + Item_func_or_sum* isfp; + + switch ( item->type() ) { - if (item->ref[0] && item->ref[0]->name.length && - gwi.returnedCols[i]->alias().c_str() && - !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(); + case Item::FIELD_ITEM: + ifip = reinterpret_cast(item); break; + default: + irip = reinterpret_cast(item); + if ( irip ) + ifip = reinterpret_cast(irip->ref[0]); + break; + } + + if (ifip && ifip->field) + { + std::vector::iterator iter = gwi.extSelAggColsItems.begin(); + for ( ; iter != gwi.extSelAggColsItems.end(); iter++ ) + { + //Item* temp_isfp = *iter; + isfp = reinterpret_cast(*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 // list so find the corresponding column. - ReturnedColumn* rc = findCorrespTempField(static_cast(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) lhs = new ParseTree(rc); } @@ -3117,7 +3156,10 @@ ArithmeticColumn* buildArithmeticColumn( { // There must be an aggregation column in extended SELECT // list so find the corresponding column. - ReturnedColumn* rc = findCorrespTempField(static_cast(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) rhs = new ParseTree(rc); } @@ -3456,10 +3498,11 @@ ReturnedColumn* buildFunctionColumn( ReturnedColumn* rc = buildReturnedColumn(ifp->arguments()[i], gwi, nonSupport, pushdownHand); // 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) { - rc = findCorrespTempField(static_cast(ifp->arguments()[i]), gwi); + gwi.fatalParseError = false; + rc = buildAggFrmTempField(ifp->arguments()[i], gwi); } 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) { - Item_field* ifip = static_cast(col); - std::vector::iterator iter = gwip->havingAggColsItems.begin(); - Item_func_or_sum* isfp = NULL; - - for ( ; iter != gwip->havingAggColsItems.end(); iter++ ) - { - Item* temp_isfp = *iter; - isfp = reinterpret_cast(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; - } - } + ReturnedColumn* rc = buildAggFrmTempField(const_cast(item), *gwip); + if (rc) + gwip->rcWorkStack.push(rc); break; } @@ -5628,7 +5654,7 @@ void parse_item (Item* item, vector& field_vec, // and set hasNonSupportItem if it is so. ReturnedColumn* rc = NULL; if (gwi) - rc = findCorrespTempField(ref, *gwi, false); + rc = buildAggFrmTempField(ref, *gwi); 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; gp_walk_info gwi; gwi.thd = thd; - gwi.groupByAuxDescr = gi.groupByAuxDescr; int status = getGroupPlan(gwi, select_lex, csep, gi); +#ifdef DEBUG_WALK_COND cerr << "---------------- cp_get_group_plan EXECUTION PLAN ----------------" << endl; cerr << *csep << endl ; cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; +#endif if (status > 0) 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_select; bool redo = false; - List_iterator_fast itDescr(*gi.groupByAuxDescr); - char* fieldDescr; // empty rcWorkStack and ptWorkStack. They should all be empty by now. clearStacks(gwi); @@ -8640,14 +8665,12 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro while ((item = it++)) { - // Given the size of gi.groupByAuxDescr is equal to gi.groupByFields - fieldDescr = itDescr++; string itemAlias; if(item->name.length) itemAlias = (item->name.str); else { - itemAlias = (fieldDescr ? fieldDescr: ""); + itemAlias = ""; } // @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; } - if(!ac->alias().length()) - ac->alias(fieldDescr); // add this agg col to returnedColumnList boost::shared_ptr spac(ac); gwi.returnedCols.push_back(spac); - // This item will be used in HAVING later. - Item_func_or_sum* isfp = reinterpret_cast(item); - - if ( ! isfp->name.length ) - { - gwi.havingAggColsItems.push_back(item); - } + // This item could be used in projection or HAVING later. + gwi.extSelAggColsItems.push_back(item); gwi.selectCols.push_back('`' + escapeBackTick(spac->alias().c_str()) + '`'); String str(256); diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index c2ff80950..59a3df714 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -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. gi.groupByTables = group_hand->table_list; gi.groupByFields = group_hand->select; - gi.groupByAuxDescr = &group_hand->select_list_descr; gi.groupByWhere = group_hand->where; gi.groupByGroup = group_hand->group_by; gi.groupByOrder = group_hand->order_by; diff --git a/dbcon/mysql/ha_calpont_impl_if.h b/dbcon/mysql/ha_calpont_impl_if.h index 77b30d988..4ebc7adb2 100644 --- a/dbcon/mysql/ha_calpont_impl_if.h +++ b/dbcon/mysql/ha_calpont_impl_if.h @@ -99,7 +99,7 @@ struct gp_walk_info execplan::CalpontSelectExecutionPlan::ReturnedColumnList groupByCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList subGroupByCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList orderByCols; - std::vector havingAggColsItems; + std::vector extSelAggColsItems; execplan::CalpontSelectExecutionPlan::ColumnMap columnMap; // This vector temporarily hold the projection columns to be added // to the returnedCols vector for subquery processing. It will be appended @@ -142,7 +142,6 @@ struct gp_walk_info std::map derivedTbFilterMap; uint32_t derivedTbCnt; std::vector subselectList; - List* groupByAuxDescr; // Kludge for Bug 750 int32_t recursionLevel; @@ -200,7 +199,6 @@ struct cal_table_info struct cal_group_info { cal_group_info() : groupByFields(0), - groupByAuxDescr(0), groupByTables(0), groupByWhere(0), groupByGroup(0), @@ -211,7 +209,6 @@ struct cal_group_info ~cal_group_info() { } List* groupByFields; // MCOL-1052 SELECT - List* groupByAuxDescr; //MCOL-1052 Auxilary column descriptions TABLE_LIST* groupByTables; // MCOL-1052 FROM Item* groupByWhere; // MCOL-1052 WHERE ORDER* groupByGroup; // MCOL-1052 GROUP BY