diff --git a/dbcon/mysql/CMakeLists.txt b/dbcon/mysql/CMakeLists.txt index 7721aed80..a1786481d 100644 --- a/dbcon/mysql/CMakeLists.txt +++ b/dbcon/mysql/CMakeLists.txt @@ -20,8 +20,8 @@ SET ( libcalmysql_SRCS ha_pseudocolumn.cpp) add_definitions(-DMYSQL_DYNAMIC_PLUGIN) -add_definitions(-DDEBUG_WALK_COND) -add_definitions(-DINFINIDB_DEBUG) +add_definitions(-DDEBUG_WALK_COND=1) +add_definitions(-DINFINIDB_DEBUG=1) #add_definitions(-DOUTER_JOIN_DEBUG) set_source_files_properties(ha_calpont.cpp PROPERTIES COMPILE_FLAGS "-fno-rtti -fno-implicit-templates") diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index a780a72e0..e07beade3 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -1139,9 +1139,7 @@ static MYSQL_SYSVAR_ULONG( 0); #endif -/*@brief ha_calpont_impl_group_by_init - Get data for MariaDB group_by - pushdown handler -*/ +/*@brief create_calpont_group_by_handler- Creates handler*/ /*********************************************************** * DESCRIPTION: * Creates a group_by pushdown handler. @@ -1158,16 +1156,27 @@ create_calpont_group_by_handler(THD *thd, Query *query) { ha_calpont_group_by_handler *handler = NULL; - handler = new ha_calpont_group_by_handler(thd, query); + if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE ) + { + handler = new ha_calpont_group_by_handler(thd, query); + + // Notify the server, that CS handles GROUP BY, ORDER BY and HAVING clauses. + query->group_by = NULL; + query->order_by = NULL; + query->having = NULL; + } - // Notify the server, that CS handles GROUP BY, ORDER BY and HAVING clauses. - query->group_by = NULL; - query->order_by = NULL; - query->having = NULL; + return handler; } +/*********************************************************** + * DESCRIPTION: + * Makes the plan and prepares the data + * RETURN: + * int rc + ***********************************************************/ int ha_calpont_group_by_handler::init_scan() { DBUG_ENTER("ha_calpont_group_by_handler::init_scan"); @@ -1181,6 +1190,12 @@ int ha_calpont_group_by_handler::init_scan() DBUG_RETURN(rc); } +/*********************************************************** + * DESCRIPTION: + * Fetches a row and saves it to a temporary table. + * RETURN: + * int rc + ***********************************************************/ int ha_calpont_group_by_handler::next_row() { DBUG_ENTER("ha_calpont_group_by_handler::next_row"); @@ -1189,6 +1204,12 @@ int ha_calpont_group_by_handler::next_row() DBUG_RETURN(rc); } +/*********************************************************** + * DESCRIPTION: + * Shuts the scan down. + * RETURN: + * int rc + ***********************************************************/ int ha_calpont_group_by_handler::end_scan() { DBUG_ENTER("ha_calpont_group_by_handler::end_scan"); @@ -1196,7 +1217,6 @@ int ha_calpont_group_by_handler::end_scan() int rc = ha_calpont_impl_group_by_end(this, table); DBUG_RETURN(rc); -// return 0; } diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 7ed3c0e69..78b65bd18 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -2713,7 +2713,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp if ( gwi.thd) { - if ( ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI )) + //if ( ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI )) { if ( !item->fixed) { @@ -2959,6 +2959,260 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp return rc; } +ReturnedColumn* buildReturnedColumnGr(Item* item, gp_walk_info& gwi, bool& nonSupport) +{ + ReturnedColumn* rc = NULL; + + if ( gwi.thd) + { + //if ( ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI )) + { + if ( !item->fixed) + { + item->fix_fields(gwi.thd, (Item**)&item); + } + } + } + + Item::Type itype = Item::SUM_FUNC_ITEM; + + switch (itype) + { + case Item::FIELD_ITEM: + { + Item_field* ifp = (Item_field*)item; + return buildSimpleColumn(ifp, gwi); + } + + case Item::INT_ITEM: + case Item::VARBIN_ITEM: + { + String val, *str = item->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + + if (item->unsigned_flag) + { + //cc = new ConstantColumn(valStr, (uint64_t)item->val_uint(), ConstantColumn::NUM); + // It seems that str at this point is crap if val_uint() is > MAX_BIGINT. By using + // this constructor, ConstantColumn is built with the proper string. For whatever reason, + // ExeMgr converts the fConstval member to numeric, rather than using the existing numeric + // values available, so it's important to have fConstval correct. + rc = new ConstantColumn((uint64_t)item->val_uint(), ConstantColumn::NUM); + } + else + { + rc = new ConstantColumn(valStr, (int64_t)item->val_int(), ConstantColumn::NUM); + } + + //return cc; + break; + } + + case Item::STRING_ITEM: + { + String val, *str = item->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + rc = new ConstantColumn(valStr); + break; + } + + case Item::REAL_ITEM: + { + String val, *str = item->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + rc = new ConstantColumn(valStr, item->val_real()); + break; + } + + case Item::DECIMAL_ITEM: + { + rc = buildDecimalColumn(item, gwi); + break; + } + + case Item::FUNC_ITEM: + { + Item_func* ifp = (Item_func*)item; + string func_name = ifp->func_name(); + + // try to evaluate const F&E. only for select clause + vector tmpVec; + //bool hasAggColumn = false; + uint16_t parseInfo = 0; + parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo); + + if (parseInfo & SUB_BIT) + { + gwi.fatalParseError = true; + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SELECT_SUB); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + break; + } + + if (!gwi.fatalParseError && + !nonConstFunc(ifp) && + !(parseInfo & AF_BIT) && + (tmpVec.size() == 0)) + { + String val, *str = ifp->val_str(&val); + string valStr; + + if (str) + { + valStr.assign(str->ptr(), str->length()); + } + + if (!str) + { + rc = new ConstantColumn("", ConstantColumn::NULLDATA); + } + else if (ifp->result_type() == STRING_RESULT) + { + rc = new ConstantColumn(valStr, ConstantColumn::LITERAL); + rc->resultType(colType_MysqlToIDB(item)); + } + else if (ifp->result_type() == DECIMAL_RESULT) + rc = buildDecimalColumn(ifp, gwi); + else + { + rc = new ConstantColumn(valStr, ConstantColumn::NUM); + rc->resultType(colType_MysqlToIDB(item)); + } + + break; + } + + if (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/" ) + return buildArithmeticColumn(ifp, gwi, nonSupport); + else + return buildFunctionColumn(ifp, gwi, nonSupport); + } + + case Item::SUM_FUNC_ITEM: + { + return buildAggregateColumn(item, gwi); + } + + case Item::REF_ITEM: + { + Item_ref* ref = (Item_ref*)item; + + switch ((*(ref->ref))->type()) + { + case Item::SUM_FUNC_ITEM: + return buildAggregateColumn(*(ref->ref), gwi); + + case Item::FIELD_ITEM: + return buildReturnedColumn(*(ref->ref), gwi, nonSupport); + + case Item::REF_ITEM: + return buildReturnedColumn(*(((Item_ref*)(*(ref->ref)))->ref), gwi, nonSupport); + + case Item::FUNC_ITEM: + return buildFunctionColumn((Item_func*)(*(ref->ref)), gwi, nonSupport); + + case Item::WINDOW_FUNC_ITEM: + return buildWindowFunctionColumn(*(ref->ref), gwi, nonSupport); + + default: + gwi.fatalParseError = true; + gwi.parseErrorText = "Unknown REF item"; + break; + } + } + + case Item::NULL_ITEM: + { + if (gwi.condPush) + return new SimpleColumn("noop"); + + return new ConstantColumn("", ConstantColumn::NULLDATA); + } + + case Item::CACHE_ITEM: + { + Item* col = ((Item_cache*)item)->get_example(); + rc = buildReturnedColumn(col, gwi, nonSupport); + + if (rc) + { + ConstantColumn* cc = dynamic_cast(rc); + + if (!cc) + { + rc->joinInfo(rc->joinInfo() | JOIN_CORRELATED); + + if (gwi.subQuery) + gwi.subQuery->correlated(true); + } + } + + break; + } + + case Item::EXPR_CACHE_ITEM: + { + // TODO: item is a Item_cache_wrapper + printf("EXPR_CACHE_ITEM in buildReturnedColumn\n"); + cerr << "EXPR_CACHE_ITEM in buildReturnedColumn" << endl; + break; + } + + case Item::DATE_ITEM: + { + String val, *str = item->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + rc = new ConstantColumn(valStr); + break; + } + + case Item::WINDOW_FUNC_ITEM: + { + return buildWindowFunctionColumn(item, gwi, nonSupport); + } + +#if INTERVAL_ITEM + + case Item::INTERVAL_ITEM: + { + Item_interval* interval = (Item_interval*)item; + SRCP srcp; + srcp.reset(buildReturnedColumn(interval->item, gwi, nonSupport)); + + if (!srcp) + return NULL; + + rc = new IntervalColumn(srcp, (int)interval->interval); + rc->resultType(srcp->resultType()); + break; + } + +#endif + + case Item::SUBSELECT_ITEM: + { + gwi.hasSubSelect = true; + break; + } + + default: + { + gwi.fatalParseError = true; + gwi.parseErrorText = "Unknown item type"; + break; + } + } + + if (rc && item->name) + rc->alias(item->name); + + return rc; +} + ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool& nonSupport) { if (!(gwi.thd->infinidb_vtable.cal_conn_info)) @@ -5029,7 +5283,13 @@ void gp_walk(const Item* item, void* arg) gwip->clauseType = SELECT; if (col->type() != Item::COND_ITEM) - rc = buildReturnedColumn(col, *gwip, gwip->fatalParseError); + { + /*if ( col->type() == Item::FIELD_ITEM ) + { + rc = buildReturnedColumnGr(col, *gwip, gwip->fatalParseError); + } else*/ + rc = buildReturnedColumn(col, *gwip, gwip->fatalParseError); + } SimpleColumn* sc = dynamic_cast(rc); @@ -7937,8 +8197,7 @@ int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti) return 0; } -// ti is useless -int cp_get_group_plan(THD* thd, SCSEP& csep, cal_group_info& gi ) +int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi) { LEX* lex = thd->lex; idbassert(lex != 0); @@ -7957,176 +8216,15 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_group_info& gi ) cerr << *csep << endl ; cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; - // Derived table projection and filter optimization. - //derivedTableOptimization(csep); - return 0; } -/* -int cp_get_group_plan(THD* thd, SCSEP& csep, cal_table_info& ti ) -{ - gp_walk_info* gwi = ti.condInfo; - List_iterator_fast it(*ti.groupByFields); - Item* item; - - if (!gwi) - gwi = new gp_walk_info(); - - gwi->thd = thd; - LEX* lex = thd->lex; - idbassert(lex != 0); - uint32_t sessionID = csep->sessionID(); - gwi->sessionid = sessionID; - TABLE* table = ti.msTablePtr; - TABLE_LIST* table_list = ti.groupByTables; - boost::shared_ptr csc = - CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID); - csc->identity(CalpontSystemCatalog::FE); - - // get all columns that mysql needs to fetch - MY_BITMAP* read_set = table->read_set; - Field** f_ptr, *field; - gwi->columnMap.clear(); - - CalpontSystemCatalog::TableAliasName tan= - make_aliastable(table->s->db.str, table->s->table_name.str, table->alias.c_ptr()); - - gwi->tbList.push_back(tan); - gwi->tableMap[tan] = make_pair(0, table_list); - - while ((item = it++)) - { - Item *arg0; - Field *field; - ReturnedColumn* rc = buildAggregateColumn(item, *gwi); - //string alias(table->alias.c_ptr()); - //rc->tableAlias(lower(alias)); - assert (rc); - boost::shared_ptr sprc(rc); - gwi->returnedCols.push_back(sprc); - } - - // TO DO add table into tableMap - // TO DO add the column only if there is no any for a table. - TableMap::iterator tb_iter = gwi->tableMap.begin(); - try - { - for (; tb_iter != gwi->tableMap.end(); tb_iter++) - { - if ((*tb_iter).second.first == 1) continue; - - CalpontSystemCatalog::TableAliasName tan = (*tb_iter).first; - CalpontSystemCatalog::TableName tn = make_table((*tb_iter).first.schema, (*tb_iter).first.table); - SimpleColumn* sc = getSmallestColumn(csc, tn, tan, (*tb_iter).second.second->table, *gwi); - SRCP srcp(sc); - gwi->columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(sc->columnName(), srcp)); - (*tb_iter).second.first = 1; - } - } - catch (runtime_error& e) - { - setError(gwi->thd, ER_INTERNAL_ERROR, e.what(), *gwi); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - return ER_INTERNAL_ERROR; - } - catch (...) - { - string emsg = IDBErrorInfo::instance()->errorMsg(ERR_LOST_CONN_EXEMGR); - setError(gwi->thd, ER_INTERNAL_ERROR, emsg, *gwi); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - return ER_INTERNAL_ERROR; - } - - //if (gwi->columnMap.empty()) - //{ - // CalpontSystemCatalog::TableName tn = make_table(table->s->db.str, table->s->table_name.str); - // CalpontSystemCatalog::TableAliasName tan = make_aliastable(table->s->db.str, table->s->table_name.str, table->alias.c_ptr()); - // SimpleColumn* sc = getSmallestColumn(csc, tn, tan, table, *gwi); - // SRCP srcp(sc); - // gwi->columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(sc->columnName(), srcp)); - // gwi->returnedCols.push_back(srcp); - //} - - - CalpontSystemCatalog::TableName tn = make_table(table->s->db.str, table->s->table_name.str); - //SimpleColumn* minSc = getSmallestColumn(csc, tn, tan, table, *gwi); - SRCP minSc; - minSc = gwi->returnedCols[0]; - std::vector::iterator coliter; - for (coliter = gwi->count_asterisk_list.begin(); coliter != gwi->count_asterisk_list.end(); ++coliter) - { - (*coliter)->functionParms(minSc); - } - - // get filter - if (ti.condInfo) - { - gp_walk_info* gwi = ti.condInfo; - ParseTree* filters = 0; - ParseTree* ptp = 0; - ParseTree* rhs = 0; - - while (!gwi->ptWorkStack.empty()) - { - filters = gwi->ptWorkStack.top(); - gwi->ptWorkStack.pop(); - SimpleFilter* sf = dynamic_cast(filters->data()); - - if (sf && sf->op()->data() == "noop") - { - delete filters; - filters = 0; - - if (gwi->ptWorkStack.empty()) - break; - - continue; - } - - if (gwi->ptWorkStack.empty()) - break; - - ptp = new ParseTree(new LogicOperator("and")); - ptp->left(filters); - rhs = gwi->ptWorkStack.top(); - gwi->ptWorkStack.pop(); - ptp->right(rhs); - gwi->ptWorkStack.push(ptp); - } - - csep->filters(filters); - } - - csep->returnedCols(gwi->returnedCols); - csep->columnMap(gwi->columnMap); - CalpontSelectExecutionPlan::TableList tblist; - tblist.push_back(tan); - csep->tableList(tblist); - - // @bug 3321. Set max number of blocks in a dictionary file to be scanned for filtering - csep->stringScanThreshold(gwi->thd->variables.infinidb_string_scan_threshold); - - return 0; -} -*/ - int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_group_info& gi, bool isUnion) { #ifdef DEBUG_WALK_COND cerr << "getGroupPlan()" << endl; #endif - // by pass the derived table resolve phase of mysql - /*if (!(((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || - ((gwi.thd->lex)->sql_command == SQLCOM_DELETE ) || - ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) || - ((gwi.thd->lex)->sql_command == SQLCOM_DELETE_MULTI ) ) && gwi.thd->derived_tables_processing) - { - gwi.thd->infinidb_vtable.isUnion = false; - return -1; - } - */ // rollup is currently not supported if (select_lex.olap == ROLLUP_TYPE) { @@ -8324,74 +8422,9 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro bool unionSel = false; - // MCOL-1052 - /* - if (!isUnion && select_lex.master_unit()->is_union()) - { -// gwi.thd->infinidb_vtable.isUnion = true; - CalpontSelectExecutionPlan::SelectList unionVec; - SELECT_LEX* select_cursor = select_lex.master_unit()->first_select(); - unionSel = true; - uint8_t distUnionNum = 0; - - for (SELECT_LEX* sl = select_cursor; sl; sl = sl->next_select()) - { - SCSEP plan(new CalpontSelectExecutionPlan()); - plan->txnID(csep->txnID()); - plan->verID(csep->verID()); - plan->sessionID(csep->sessionID()); - plan->traceFlags(csep->traceFlags()); - plan->data(csep->data()); - - // @bug 3853. When one or more sides or union queries contain derived tables, - // sl->join->zero_result_cause is not trustable. Since we've already handled - // constant filter now (0/1), we can relax the following checking. - // @bug 2547. ignore union unit of zero result set case -// if (sl->join) -// { -// sl->join->optimize(); - // @bug 3067. not clear MySQL's behavior. when in subquery, this variable - // is not trustable. -// if (sl->join->zero_result_cause && !gwi.subQuery) -// continue; -// } - - // gwi for the union unit - gp_walk_info union_gwi; - union_gwi.thd = gwi.thd; - uint32_t err = 0; - - if ((err = getGroupPlan(union_gwi, *sl, plan, gi, unionSel)) != 0) - return err; - - unionVec.push_back(SCEP(plan)); - - // distinct union num - if (sl == select_lex.master_unit()->union_distinct) - distUnionNum = unionVec.size(); - - *//*#ifdef DEBUG_WALK_COND - IDEBUG( cerr << ">>>> UNION DEBUG" << endl ); - JOIN* join = sl->join; - Item_cond* icp = 0; - if (join != 0) - icp = reinterpret_cast(join->conds); - if (icp) - icp->traverse_cond(debug_walk, &gwi, Item::POSTFIX); - IDEBUG ( cerr << *plan << endl ); - IDEBUG ( cerr << "<<<unionVec(unionVec); - csep->distinctUnionNum(distUnionNum); - - if (unionVec.empty()) - gwi.thd->infinidb_vtable.impossibleWhereOnUnion = true; - } - */ gwi.clauseType = WHERE; + if (icp) { // MCOL-1052 The condition could be useless. @@ -8434,6 +8467,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro { gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM)); } + // ZZ - the followinig debug shows the structure of nested outer join. should @@ -9148,9 +9182,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro gwi.fatalParseError = false; gwi.parseErrorText = ""; - if (gi.groupByHaving != 0) + //if (gi.groupByHaving != 0) + if ( select_lex.having != 0 ) { - Item_cond* having = reinterpret_cast(gi.groupByHaving); + Item_cond* having = reinterpret_cast(select_lex.having); + //Item_cond* having = reinterpret_cast(gi.groupByHaving); #ifdef DEBUG_WALK_COND cerr << "------------------- HAVING ---------------------" << endl; having->traverse_cond(debug_walk, &gwi, Item::POSTFIX); @@ -9270,13 +9306,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro SRCP minSc; // min width projected column. for count(*) use // Group by list. not valid for union main query - - /* if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && !unionSel) { gwi.clauseType = GROUP_BY; Item* nonSupportItem = NULL; - ORDER* groupcol = reinterpret_cast(gi.groupByGr.first); + ORDER* groupcol = reinterpret_cast(gi.groupByGroup); // check if window functions are in order by. InfiniDB process order by list if // window functions are involved, either in order by or projection. @@ -9298,7 +9332,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro } gwi.hasWindowFunc = hasWindowFunc; - groupcol = reinterpret_cast(gi.groupByGr.first); + groupcol = reinterpret_cast(gi.groupByGroup); for (; groupcol; groupcol = groupcol->next) { @@ -9547,13 +9581,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); return ER_CHECK_NOT_IMPLEMENTED; } - } - */ + } // GROUP processing ends here if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) { - //SQL_I_List order_list = gi.groupByOrder; ORDER* ordercol = reinterpret_cast(gi.groupByOrder); string create_query(gwi.thd->infinidb_vtable.create_vtable_query.c_ptr()); string select_query(gwi.thd->infinidb_vtable.select_vtable_query.c_ptr()); @@ -9576,7 +9608,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // for subquery, order+limit by will be supported in infinidb. build order by columns // @todo union order by and limit support - if (gwi.hasWindowFunc || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT) + //if (gwi.hasWindowFunc || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT) { for (; ordercol; ordercol = ordercol->next) { @@ -9634,6 +9666,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro gwi.orderByCols.push_back(SRCP(rc)); } } + /* else if (!isUnion) { vector fieldVec; @@ -9817,12 +9850,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro Item_field* field = reinterpret_cast(ord_item); ReturnedColumn* rc = buildSimpleColumn(field, gwi); fullname = field->full_name(); -// if (field->db_name) -// fullname += string(field->db_name) + "."; -// if (field->table_name) -// fullname += string(field->table_name) + "."; -// if (field->field_name) -// fullname += string(field->field_name); for (uint32_t i = 0; i < gwi.returnedCols.size(); i++) { @@ -9933,6 +9960,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro } } } + */ // make sure columnmap, returnedcols and count(*) arg_list are not empty TableMap::iterator tb_iter = gwi.tableMap.begin(); @@ -10291,127 +10319,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro select_query += ord_cols; } } - -// MCOL-1052 LIMIT -/* - if (unionSel || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT) - { - if (select_lex.master_unit()->global_parameters()->explicit_limit) - { - if (select_lex.master_unit()->global_parameters()->offset_limit) - { - Item_int* offset = (Item_int*)select_lex.master_unit()->global_parameters()->offset_limit; - csep->limitStart(offset->val_int()); - } - - if (select_lex.master_unit()->global_parameters()->select_limit) - { - Item_int* select = (Item_int*)select_lex.master_unit()->global_parameters()->select_limit; - csep->limitNum(select->val_int()); - } - - if (unionSel && gwi.subSelectType == CalpontSelectExecutionPlan::MAIN_SELECT) - { - ostringstream limit; - limit << " limit "; - limit << csep->limitStart() << ", "; - limit << csep->limitNum(); - select_query += limit.str(); - } - } - } - else if (isUnion && select_lex.explicit_limit) - { - if (select_lex.braces) - { - if (select_lex.offset_limit) - csep->limitStart(((Item_int*)select_lex.offset_limit)->val_int()); - - if (select_lex.select_limit) - csep->limitNum(((Item_int*)select_lex.select_limit)->val_int()); - } - } - else if (select_lex.explicit_limit) - { - uint32_t limitOffset = 0; - uint32_t limitNum = std::numeric_limits::max(); - - if (join) - { -#if MYSQL_VERSION_ID >= 50172 - - // @bug5729. After upgrade, join->unit sometimes is uninitialized pointer - // (not null though) and will cause seg fault. Prefer checking - // select_lex->offset_limit if not null. - if (join->select_lex && - join->select_lex->offset_limit && - join->select_lex->offset_limit->fixed && - join->select_lex->select_limit && - join->select_lex->select_limit->fixed) - { - limitOffset = join->select_lex->offset_limit->val_int(); - limitNum = join->select_lex->select_limit->val_int(); - } - - else if (join->unit) - { - limitOffset = join->unit->offset_limit_cnt; - limitNum = join->unit->select_limit_cnt - limitOffset; - } - -#else - limitOffset = (join->unit)->offset_limit_cnt; - limitNum = (join->unit)->select_limit_cnt - (join->unit)->offset_limit_cnt; -#endif - } - else - { - if (select_lex.master_unit()->global_parameters()->offset_limit) - { - Item_int* offset = (Item_int*)select_lex.master_unit()->global_parameters()->offset_limit; - limitOffset = offset->val_int(); - } - - if (select_lex.master_unit()->global_parameters()->select_limit) - { - Item_int* select = (Item_int*)select_lex.master_unit()->global_parameters()->select_limit; - limitNum = select->val_int(); - } - } - - // relate to bug4848. let mysql drive limit when limit session variable set. - // do not set in csep. @bug5096. ignore session limit setting for dml - if ((gwi.thd->variables.select_limit == (uint64_t) - 1 || - (gwi.thd->variables.select_limit != (uint64_t) - 1 && - gwi.thd->infinidb_vtable.vtable_state != THD::INFINIDB_CREATE_VTABLE)) && - !csep->hasOrderBy()) - { - csep->limitStart(limitOffset); - csep->limitNum(limitNum); - } - else - { - ostringstream limit; - limit << " limit " << limitOffset << ", " << limitNum; - select_query += limit.str(); - } - } - gwi.thd->infinidb_vtable.select_vtable_query.free(); - gwi.thd->infinidb_vtable.select_vtable_query.append(select_query.c_str(), select_query.length()); - - // We don't currently support limit with correlated subquery - if (csep->limitNum() != (uint64_t) - 1 && - gwi.subQuery && !gwi.correlatedTbNameVec.empty()) - { - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_LIMIT_SUB); - setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - */ - } - - + } // ORDER BY processing ends here if ( gi.groupByDistinct ) csep->distinct(true); diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 09e125421..4232d4985 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -5932,7 +5932,7 @@ int ha_calpont_impl_rnd_pos(uchar* buf, uchar* pos) * Prepares data for group_by_handler::next_row() calls. * PARAMETERS: * group_hand - group by handler, that preserves initial table and items lists. . - * table - TABLE pointer The table to save the result set in. + * table - TABLE pointer The table to save the result set into. * RETURN: * 0 if success * others if something went wrong whilst getting the result set @@ -5967,25 +5967,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE // prevent "create table as select" from running on slave thd->infinidb_vtable.hasInfiniDBTable = true; - /* If this node is the slave, ignore DML to IDB tables */ - /*if (thd->slave_thread && ( - thd->lex->sql_command == SQLCOM_INSERT || - thd->lex->sql_command == SQLCOM_INSERT_SELECT || - thd->lex->sql_command == SQLCOM_UPDATE || - thd->lex->sql_command == SQLCOM_UPDATE_MULTI || - thd->lex->sql_command == SQLCOM_DELETE || - thd->lex->sql_command == SQLCOM_DELETE_MULTI || - thd->lex->sql_command == SQLCOM_TRUNCATE || - thd->lex->sql_command == SQLCOM_LOAD)) - return 0; - */ - - // @bug 3005. if the table is not $vtable, then this could be a UDF defined on the connector. - // watch this for other complications - //if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE && - // string(table->s->table_name.str).find("$vtable") != 0) - // return 0; - // return error if error status has been already set if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR) return ER_INTERNAL_ERROR; @@ -6007,14 +5988,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1 || thd->infinidb_vtable.vtable_state == THD::INFINIDB_ORDER_BY) return 0; - - if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) - return 0; - - - //Update and delete code - if ( ((thd->lex)->sql_command == SQLCOM_UPDATE) || ((thd->lex)->sql_command == SQLCOM_DELETE) || ((thd->lex)->sql_command == SQLCOM_DELETE_MULTI) || ((thd->lex)->sql_command == SQLCOM_UPDATE_MULTI)) - return doUpdateDelete(thd); */ uint32_t sessionID = tid2sid(thd->thread_id); @@ -6032,10 +6005,11 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE MySQL sometimes calls rnd_init multiple times, plan should only be generated and sent once. TO DO Check this statement. - */ + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE && !thd->infinidb_vtable.isNewQuery) return 0; + */ if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) { @@ -6068,101 +6042,9 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE sm::cpsm_conhdl_t* hndl; SCSEP csep; - // update traceFlags according to the autoswitch state. replication query - // on slave are in table mode (create table as...) - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) - { - ci->traceFlags |= CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; - } - - // MCOL-1052 TO DO Remove this - ci->traceFlags = CalpontSelectExecutionPlan::TRACE_LOG; - bool localQuery = (thd->variables.infinidb_local_query > 0 ? true : false); - /* - // table mode - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) - { - ti = ci->tableMap[group_hand->table_list->table]; - - // get connection handle for this table handler - // re-establish table handle - if (ti.conn_hndl) - { - sm::sm_cleanup(ti.conn_hndl); - ti.conn_hndl = 0; - } - - sm::sm_init(sessionID, &ti.conn_hndl, localQuery); - ti.conn_hndl->csc = csc; - hndl = ti.conn_hndl; - - try - { - ti.conn_hndl->connect(); - } - catch (...) - { - setError(thd, ER_INTERNAL_ERROR, IDBErrorInfo::instance()->errorMsg(ERR_LOST_CONN_EXEMGR)); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - goto error; - } - - // get filter plan for table - if (ti.csep.get() == 0) - { - ti.csep.reset(new CalpontSelectExecutionPlan()); - - SessionManager sm; - BRM::TxnID txnID; - txnID = sm.getTxnID(sessionID); - - if (!txnID.valid) - { - txnID.id = 0; - txnID.valid = true; - } - - QueryContext verID; - verID = sm.verID(); - - ti.csep->txnID(txnID.id); - ti.csep->verID(verID); - ti.csep->sessionID(sessionID); - - if (group_hand->table_list->db_length) - ti.csep->schemaName(group_hand->table_list->db); - - ti.csep->traceFlags(ci->traceFlags); - ti.msTablePtr = group_hand->table_list->table; - //ti.groupByTables = group_hand->table_list; - //ti.groupByFields = group_hand->fields; - - gi.groupByTables = group_hand->table_list; - gi.groupByFields = group_hand->select; - gi.groupByWhere = group_hand->where; - gi.groupByGroup = group_hand->group_by; - gi.groupByOrder = group_hand->order_by; - gi.groupByHaving = group_hand->having; - gi.groupByDistinct = group_hand->distinct; - - // send plan whenever group_init is called - cp_get_group_plan(thd, ti.csep, ti, gi); - } - - IDEBUG( cerr << tableName << " send plan:" << endl ); - IDEBUG( cerr << *ti.csep << endl ); - csep = ti.csep; - - // for ExeMgr logging sqltext. only log once for the query although multi plans may be sent - if (ci->tableMap.size() == 1) - ti.csep->data(idb_mysql_query_str(thd)); - } - */ - // vtable mode - //else - { + //if (!ci->cal_conn_hndl || thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) { @@ -6240,7 +6122,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE csep->schemaName(group_hand->table_list->db); csep->traceFlags(ci->traceFlags); - //ti.msTablePtr = group_hand->table_list->table; gi.groupByTables = group_hand->table_list; gi.groupByFields = group_hand->select; @@ -6311,7 +6192,7 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE IDEBUG( cout << "-------------- EXECUTION PLAN END --------------\n" << endl ); } } - }// end of execution plan generation + // end of execution plan generation if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE) { diff --git a/dbcon/mysql/ha_calpont_impl_if.h b/dbcon/mysql/ha_calpont_impl_if.h index 21560a4a0..b74025d54 100644 --- a/dbcon/mysql/ha_calpont_impl_if.h +++ b/dbcon/mysql/ha_calpont_impl_if.h @@ -320,7 +320,7 @@ int cp_get_plan(THD* thd, execplan::SCSEP& csep); int cp_get_table_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_table_info& ti); int cp_get_group_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_group_info& gi); int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, bool isUnion = false); -int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep,cal_group_info& gi, bool isUnion = false); +int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, cal_group_info& gi, bool isUnion = false); 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);