From a62a2e321ec3dece0fcfa85cce776875db4e7556 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Thu, 12 Jul 2018 14:25:46 +0300 Subject: [PATCH] MCOL-1510 CS prints IDB-1001 error when agregates used in non-supported functions, e.g. NOT(sum(i)). --- dbcon/mysql/ha_calpont_execplan.cpp | 37 ++++++++++++++++++++++------- dbcon/mysql/ha_calpont_impl_if.h | 4 ++-- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index fad5747fc..889a9d77f 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -191,7 +191,7 @@ bool nonConstFunc(Item_func* ifp) return false; } -ReturnedColumn* findCorrespTempField(Item_ref* item, gp_walk_info& gwi) +ReturnedColumn* findCorrespTempField(Item_ref* item, gp_walk_info& gwi, bool clone = true) { ReturnedColumn* result = NULL; uint32_t i; @@ -201,7 +201,10 @@ ReturnedColumn* findCorrespTempField(Item_ref* item, gp_walk_info& gwi) gwi.returnedCols[i]->alias().c_str() && !strcasecmp(item->ref[0]->name, gwi.returnedCols[i]->alias().c_str())) { - result = gwi.returnedCols[i]->clone(); + if (clone) + result = gwi.returnedCols[i]->clone(); + else + result = gwi.returnedCols[i].get(); break; } } @@ -5455,7 +5458,10 @@ void gp_walk(const Item* item, void* arg) * the involved item_fields to the passed in vector. It's used in parsing * functions or arithmetic expressions for vtable post process. */ -void parse_item (Item* item, vector& field_vec, bool& hasNonSupportItem, uint16_t& parseInfo) +void parse_item (Item* item, vector& field_vec, + bool& hasNonSupportItem, + uint16_t& parseInfo, + gp_walk_info* gwi) { Item::Type itype = item->type(); @@ -5493,7 +5499,7 @@ void parse_item (Item* item, vector& field_vec, bool& hasNonSupport } for (uint32_t i = 0; i < isp->argument_count(); i++) - parse_item(isp->arguments()[i], field_vec, hasNonSupportItem, parseInfo); + parse_item(isp->arguments()[i], field_vec, hasNonSupportItem, parseInfo, gwi); // parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); break; @@ -5538,8 +5544,20 @@ void parse_item (Item* item, vector& field_vec, bool& hasNonSupport } else if ((*(ref->ref))->type() == Item::FIELD_ITEM) { - Item_field* ifp = reinterpret_cast(*(ref->ref)); - field_vec.push_back(ifp); + // MCOL-1510. This could be a non-supported function + // argument in form of a temp_table_field, so check + // and set hasNonSupportItem if it is so. + ReturnedColumn* rc = NULL; + if (gwi) + rc = findCorrespTempField(ref, *gwi, false); + + if (!rc) + { + Item_field* ifp = reinterpret_cast(*(ref->ref)); + field_vec.push_back(ifp); + } + else + hasNonSupportItem = true; break; } else if ((*(ref->ref))->type() == Item::FUNC_ITEM) @@ -8771,7 +8789,10 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro { hasNonSupportItem = false; uint32_t before_size = funcFieldVec.size(); - parse_item(ifp, funcFieldVec, hasNonSupportItem, parseInfo); + // MCOL-1510 Use gwi pointer here to catch funcs with + // not supported aggregate args in projections, + // e.g. NOT(SUM(i)). + parse_item(ifp, funcFieldVec, hasNonSupportItem, parseInfo, &gwi); uint32_t after_size = funcFieldVec.size(); // group by func and func in subquery can not be post processed @@ -8861,7 +8882,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro redo = true; // @bug 1706 String funcStr; - //ifp->print(&funcStr, QT_INFINIDB); + ifp->print(&funcStr, QT_INFINIDB); gwi.selectCols.push_back(string(funcStr.c_ptr()) + " `" + escapeBackTick(ifp->name) + "`"); // clear the error set by buildFunctionColumn gwi.fatalParseError = false; diff --git a/dbcon/mysql/ha_calpont_impl_if.h b/dbcon/mysql/ha_calpont_impl_if.h index 40e746917..b7e668b2d 100644 --- a/dbcon/mysql/ha_calpont_impl_if.h +++ b/dbcon/mysql/ha_calpont_impl_if.h @@ -329,7 +329,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& cse void setError(THD* thd, uint32_t errcode, const std::string errmsg, gp_walk_info* gwi); void setError(THD* thd, uint32_t errcode, const std::string errmsg); void gp_walk(const Item* item, void* arg); -void parse_item (Item* item, std::vector& field_vec, bool& hasNonSupportItem, uint16& parseInfo); +void parse_item (Item* item, std::vector& field_vec, bool& hasNonSupportItem, uint16& parseInfo, gp_walk_info* gwip = NULL); const std::string bestTableName(const Item_field* ifp); bool isInfiniDB(TABLE* table_ptr); @@ -348,7 +348,7 @@ void addIntervalArgs(Item_func* ifp, funcexp::FunctionParm& functionParms); void castCharArgs(Item_func* ifp, funcexp::FunctionParm& functionParms); void castDecimalArgs(Item_func* ifp, funcexp::FunctionParm& functionParms); void castTypeArgs(Item_func* ifp, funcexp::FunctionParm& functionParms); -void parse_item (Item* item, std::vector& field_vec, bool& hasNonSupportItem, uint16& parseInfo); +//void parse_item (Item* item, std::vector& field_vec, bool& hasNonSupportItem, uint16& parseInfo); bool isPredicateFunction(Item* item, gp_walk_info* gwip); execplan::ParseTree* buildRowPredicate(execplan::RowColumn* lhs, execplan::RowColumn* rhs, std::string predicateOp); bool buildRowColumnFilter(gp_walk_info* gwip, execplan::RowColumn* rhs, execplan::RowColumn* lhs, Item_func* ifp);