From 2071716ebd77f9479cbe93733db161aa9791d178 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Wed, 30 Jan 2019 18:59:44 +0300 Subject: [PATCH 01/11] MCOL-2121 New derived_handler(MDEV-17096) infrastructure. Renamed isInfiniDB() into isMCSTable Changed getSelectPlan() to reuse it with derived and other handler types. Separate pushdown handlers methods and functions. Removed vcxproj files from the source. Added fix for MCOL-2166. Merged with MCOL-2121 --- dbcon/mysql/CMakeLists.txt | 2 + dbcon/mysql/ha_calpont.cpp | 266 +---------- dbcon/mysql/ha_calpont.h | 49 +-- dbcon/mysql/ha_calpont_execplan.cpp | 290 ++++++++++-- dbcon/mysql/ha_calpont_impl.cpp | 557 ++++++++++++++++++++++- dbcon/mysql/ha_calpont_impl.h | 6 +- dbcon/mysql/ha_calpont_impl_if.h | 6 +- dbcon/mysql/ha_mcs_pushdown.cpp | 661 ++++++++++++++++++++++++++++ dbcon/mysql/ha_mcs_pushdown.h | 142 ++++++ dbcon/mysql/ha_view.cpp | 2 +- dbcon/mysql/idb_mysql.h | 2 + 11 files changed, 1643 insertions(+), 340 deletions(-) create mode 100644 dbcon/mysql/ha_mcs_pushdown.cpp create mode 100644 dbcon/mysql/ha_mcs_pushdown.h diff --git a/dbcon/mysql/CMakeLists.txt b/dbcon/mysql/CMakeLists.txt index c74e19343..0aa6ddcc0 100644 --- a/dbcon/mysql/CMakeLists.txt +++ b/dbcon/mysql/CMakeLists.txt @@ -22,6 +22,8 @@ SET ( libcalmysql_SRCS ha_pseudocolumn.cpp) add_definitions(-DMYSQL_DYNAMIC_PLUGIN) +add_definitions(-DEBUG_WALK_COND) +add_definitions(-DINFINIDB_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 552a895d6..f1b375480 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -21,6 +21,7 @@ #define NEED_CALPONT_EXTERNS #include "ha_calpont_impl.h" +#include "ha_mcs_pushdown.h" static handler* calpont_create_handler(handlerton* hton, TABLE_SHARE* table, @@ -32,9 +33,17 @@ static int calpont_rollback(handlerton* hton, THD* thd, bool all); static int calpont_close_connection ( handlerton* hton, THD* thd ); handlerton* calpont_hton; +// handlers creation function for hton. +// Look into ha_mcs_pushdown.* for more details. static group_by_handler* create_calpont_group_by_handler(THD* thd, Query* query); +static derived_handler* +create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived); + +static select_handler* +create_columnstore_select_handler(THD* thd, SELECT_LEX* sel); + /* Variables for example share methods */ /* @@ -131,6 +140,8 @@ static int columnstore_init_func(void* p) calpont_hton->rollback = calpont_rollback; calpont_hton->close_connection = calpont_close_connection; calpont_hton->create_group_by = create_calpont_group_by_handler; + calpont_hton->create_derived = create_columnstore_derived_handler; + calpont_hton->create_select = create_columnstore_select_handler; DBUG_RETURN(0); } @@ -159,6 +170,10 @@ static int infinidb_init_func(void* p) calpont_hton->commit = calpont_commit; calpont_hton->rollback = calpont_rollback; calpont_hton->close_connection = calpont_close_connection; + calpont_hton->create_group_by = create_calpont_group_by_handler; + calpont_hton->create_derived = create_columnstore_derived_handler; + calpont_hton->create_select = create_columnstore_select_handler; + DBUG_RETURN(0); } @@ -929,256 +944,7 @@ struct st_mysql_storage_engine columnstore_storage_engine = struct st_mysql_storage_engine infinidb_storage_engine = { MYSQL_HANDLERTON_INTERFACE_VERSION }; -/*@brief check_walk - It traverses filter conditions*/ -/************************************************************ - * DESCRIPTION: - * It traverses filter predicates looking for unsupported - * JOIN types: non-equi JOIN, e.g t1.c1 > t2.c2; - * logical OR. - * PARAMETERS: - * thd - THD pointer. - * derived - TABLE_LIST* to work with. - * RETURN: - * derived_handler if possible - * NULL in other case - ***********************************************************/ -void check_walk(const Item* item, void* arg) -{ - bool* unsupported_feature = static_cast(arg); - if ( *unsupported_feature ) - return; - switch (item->type()) - { - case Item::FUNC_ITEM: - { - const Item_func* ifp = static_cast(item); - - if ( ifp->functype() != Item_func::EQ_FUNC ) // NON-equi JOIN - { - if ( ifp->argument_count() == 2 && - ifp->arguments()[0]->type() == Item::FIELD_ITEM && - ifp->arguments()[1]->type() == Item::FIELD_ITEM ) - { - Item_field* left= static_cast(ifp->arguments()[0]); - Item_field* right= static_cast(ifp->arguments()[1]); - - if ( left->field->table != right->field->table ) - { - *unsupported_feature = true; - return; - } - } - else // IN + correlated subquery - { - if ( ifp->functype() == Item_func::NOT_FUNC - && ifp->arguments()[0]->type() == Item::EXPR_CACHE_ITEM ) - { - check_walk(ifp->arguments()[0], arg); - } - } - } - break; - } - - case Item::EXPR_CACHE_ITEM: // IN + correlated subquery - { - const Item_cache_wrapper* icw = static_cast(item); - if ( icw->get_orig_item()->type() == Item::FUNC_ITEM ) - { - const Item_func *ifp = static_cast(icw->get_orig_item()); - if ( ifp->argument_count() == 2 && - ( ifp->arguments()[0]->type() == Item::Item::SUBSELECT_ITEM - || ifp->arguments()[1]->type() == Item::Item::SUBSELECT_ITEM )) - { - *unsupported_feature = true; - return; - } - } - break; - } - - case Item::COND_ITEM: // OR in cods is unsupported yet - { - Item_cond* icp = (Item_cond*)item; - if ( is_cond_or(icp) ) - { - *unsupported_feature = true; - } - break; - } - default: - { - break; - } - } -} - -/*@brief create_calpont_group_by_handler- Creates handler*/ -/*********************************************************** - * DESCRIPTION: - * Creates a group_by pushdown handler if there is no: - * non-equi JOIN, e.g * t1.c1 > t2.c2 - * logical OR in the filter predicates - * Impossible WHERE - * Impossible HAVING - * and there is either GROUP BY or aggregation function - * exists at the top level. - * Valid queries with the last two crashes the server if - * processed. - * Details are in server/sql/group_by_handler.h - * PARAMETERS: - * thd - THD pointer - * query - Query structure LFM in group_by_handler.h - * RETURN: - * group_by_handler if success - * NULL in other case - ***********************************************************/ -static group_by_handler* -create_calpont_group_by_handler(THD* thd, Query* query) -{ - ha_calpont_group_by_handler* handler = NULL; - // same as thd->lex->current_select - SELECT_LEX *select_lex = query->from->select_lex; - - // Create a handler if query is valid. See comments for details. - if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE - && ( thd->variables.infinidb_vtable_mode == 0 - || thd->variables.infinidb_vtable_mode == 2 ) - && ( query->group_by || select_lex->with_sum_func ) ) - { - bool unsupported_feature = false; - // revisit SELECT_LEX for all units - for(TABLE_LIST* tl = query->from; !unsupported_feature && tl; tl = tl->next_global) - { - select_lex = tl->select_lex; - // Correlation subquery. Comming soon so fail on this yet. - unsupported_feature = select_lex->is_correlated; - - // Impossible HAVING or WHERE - if ( ( !unsupported_feature && query->having && select_lex->having_value == Item::COND_FALSE ) - || ( select_lex->cond_count > 0 - && select_lex->cond_value == Item::COND_FALSE ) ) - { - unsupported_feature = true; - } - - // Unsupported JOIN conditions - if ( !unsupported_feature ) - { - JOIN *join = select_lex->join; - Item_cond *icp = 0; - - if (join != 0) - icp = reinterpret_cast(join->conds); - - if ( unsupported_feature == false - && icp ) - { - icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); - } - - // Optimizer could move some join conditions into where - if (select_lex->where != 0) - icp = reinterpret_cast(select_lex->where); - - if ( unsupported_feature == false - && icp ) - { - icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); - } - - } - } // unsupported features check ends here - - if ( !unsupported_feature ) - { - 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; - } - } - - return handler; -} - -/*********************************************************** - * DESCRIPTION: - * GROUP BY handler constructor - * PARAMETERS: - * thd - THD pointer. - * query - Query describing structure - ***********************************************************/ -ha_calpont_group_by_handler::ha_calpont_group_by_handler(THD* thd_arg, Query* query) - : group_by_handler(thd_arg, calpont_hton), - select(query->select), - table_list(query->from), - distinct(query->distinct), - where(query->where), - group_by(query->group_by), - order_by(query->order_by), - having(query->having) -{ -} - -/*********************************************************** - * DESCRIPTION: - * GROUP BY destructor - ***********************************************************/ -ha_calpont_group_by_handler::~ha_calpont_group_by_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"); - - // Save vtable_state to restore the after we inited. - THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; - // MCOL-1052 Should be removed after cleaning the code up. - thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; - int rc = ha_calpont_impl_group_by_init(this, table); - thd->infinidb_vtable.vtable_state = oldState; - - 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"); - int rc = ha_calpont_impl_group_by_next(this, table); - - 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"); - - int rc = ha_calpont_impl_group_by_end(this, table); - - DBUG_RETURN(rc); -} +#include "ha_mcs_pushdown.cpp" mysql_declare_plugin(columnstore) { diff --git a/dbcon/mysql/ha_calpont.h b/dbcon/mysql/ha_calpont.h index bab756851..070f5380b 100644 --- a/dbcon/mysql/ha_calpont.h +++ b/dbcon/mysql/ha_calpont.h @@ -24,7 +24,7 @@ extern handlerton* calpont_hton; /** @brief - This structure will be shared among all open handlers. + INFINIDB_SHARE is a structure that will be shared among all open handlers. This example implements the minimum of what you will probably need. */ typedef struct st_calpont_share @@ -228,51 +228,4 @@ public: } }; - -/*@brief group_by_handler class*/ -/*********************************************************** - * DESCRIPTION: - * Provides server with group_by_handler API methods. - * One should read comments in server/sql/group_by_handler.h - * Attributes: - * select - attribute contains all GROUP BY, HAVING, ORDER items and calls it - * an extended SELECT list according to comments in - * server/sql/group_handler.cc. - * So the temporary table for - * select count(*) from b group by a having a > 3 order by a - * will have 4 columns not 1. - * However server ignores all NULLs used in - * GROUP BY, HAVING, ORDER. - * select_list_descr - contains Item description returned by Item->print() - * that is used in lookup for corresponding columns in - * extended SELECT list. - * table_list - contains all tables involved. Must be CS tables only. - * distinct - looks like a useless thing for now. Couldn't get it set by server. - * where - where items. - * group_by - group by ORDER items. - * order_by - order by ORDER items. - * having - having Item. - * Methods: - * init_scan - get plan and send it to ExeMgr. Get the execution result. - * next_row - get a row back from sm. - * end_scan - finish and clean the things up. - ***********************************************************/ -class ha_calpont_group_by_handler: public group_by_handler -{ -public: - ha_calpont_group_by_handler(THD* thd_arg, Query* query); - ~ha_calpont_group_by_handler(); - int init_scan(); - int next_row(); - int end_scan(); - - List* select; - TABLE_LIST* table_list; - bool distinct; - Item* where; - ORDER* group_by; - ORDER* order_by; - Item* having; -}; #endif //HA_CALPONT_H__ - diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index d40584109..c8b6aa058 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -192,6 +192,150 @@ bool nonConstFunc(Item_func* ifp) return false; } +/*@brief getColNameFromItem - builds a name from an Item */ +/*********************************************************** + * DESCRIPTION: + * This f() looks for a first proper Item_ident and populate + * ostream with schema, table and column names. + * Used to build db.table.field tuple for debugging output + * in getSelectPlan(). TBD getGroupPlan must use this also. + * PARAMETERS: + * item source Item* + * ostream output stream + * RETURNS + * void + ***********************************************************/ +void getColNameFromItem(std::ostringstream& ostream, Item* item) +{ +// MCOL-2121 WIP +// Item_func doesn't have proper db.table.field values +// inherited from Item_ident. TBD what is the valid output. +// !!!dynamic_cast fails compilation + ostream << "'"; + + if (item->type() != Item::FIELD_ITEM) + { + ostream << "unknown db" << '.'; + ostream << "unknown table" << '.'; + ostream << "unknown field"; + } + else + { + Item_ident* iip = reinterpret_cast(item); + + if (iip->db_name) + ostream << iip->db_name << '.'; + else + ostream << "unknown db" << '.'; + + if (iip->table_name) + ostream << iip->table_name << '.'; + else + ostream << "unknown table" << '.'; + + if (iip->field_name.length) + ostream << iip->field_name.str; + else + ostream << "unknown field"; + } + + ostream << "'"; + return; +} + +/*@brf sortItemIsInGroupRec - seeks for an item in grouping*/ +/*********************************************************** + * DESCRIPTION: + * This f() recursively traverses grouping items and looks + * for an FUNC_ITEM, REF_ITEM or FIELD_ITEM. + * f() is used by sortItemIsInGrouping(). + * PARAMETERS: + * sort_item Item* used to build aggregation. + * group_item GROUP BY item. + * RETURNS + * bool + ***********************************************************/ +bool sortItemIsInGroupRec(Item* sort_item, Item* group_item) +{ + bool found = false; + // If ITEM_REF::ref is NULL + if (sort_item == NULL) + { + return found; + } + + Item_func* ifp_sort = reinterpret_cast(sort_item); + + // base cases for Item_field and Item_ref. The second arg is binary cmp switch + found = group_item->eq(sort_item, false); + if (!found && sort_item->type() == Item::REF_ITEM) + { + Item_ref* ifp_sort_ref = reinterpret_cast(sort_item); + found = sortItemIsInGroupRec(*ifp_sort_ref->ref, group_item); + } + + // seeking for a group_item match + for (uint32_t i = 0; !found && i < ifp_sort->argument_count(); i++) + { + Item* ifp_sort_arg = ifp_sort->arguments()[i]; + if (ifp_sort_arg->type() == Item::FUNC_ITEM + || ifp_sort_arg->type() == Item::FIELD_ITEM) + { + Item* ifp_sort_arg = ifp_sort->arguments()[i]; + found = sortItemIsInGroupRec(ifp_sort_arg, group_item); + } + else if (ifp_sort_arg->type() == Item::REF_ITEM) + { + // dereference the Item + Item_ref* ifp_sort_ref = reinterpret_cast(ifp_sort_arg); + found = sortItemIsInGroupRec(*ifp_sort_ref->ref, group_item); + } + } + + return found; +} + +/*@brief sortItemIsInGrouping- seeks for an item in grouping*/ +/*********************************************************** + * DESCRIPTION: + * This f() traverses grouping items and looks for an item. + * only Item_fields, Item_func are considered. However there + * could be Item_ref down the tree. + * f() is used in sorting parsing by getSelectPlan(). + * PARAMETERS: + * sort_item Item* used to build aggregation. + * groupcol GROUP BY items from this unit. + * RETURNS + * bool + ***********************************************************/ +bool sortItemIsInGrouping(Item* sort_item, ORDER* groupcol) +{ + bool found = false; + + if(sort_item->type() == Item::SUM_FUNC_ITEM) + { + found = true; + } + + for (; !found && groupcol; groupcol = groupcol->next) + { + Item* group_item = *(groupcol->item); + found = (group_item->eq(sort_item, false)) ? true : false; + // Detect aggregation functions first then traverse + // if sort field is a Func and group field + // is either Field or Func + // Consider nonConstFunc() check here + if(!found && sort_item->type() == Item::FUNC_ITEM + && (group_item->type() == Item::FUNC_ITEM + || group_item->type() == Item::FIELD_ITEM)) + { + found = sortItemIsInGroupRec(sort_item, group_item); + } + } + + return found; +} + /*@brief buildAggFrmTempField- build aggr func from extSELECT list item*/ /*********************************************************** * DESCRIPTION: @@ -230,7 +374,6 @@ ReturnedColumn* buildAggFrmTempField(Item* item, gp_walk_info& gwi) 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 && @@ -4079,10 +4222,10 @@ SimpleColumn* buildSimpleColumn(Item_field* ifp, gp_walk_info& gwi) { // check foreign engine if (ifp->cached_table && ifp->cached_table->table) - infiniDB = isInfiniDB(ifp->cached_table->table); + infiniDB = isMCSTable(ifp->cached_table->table); // @bug4509. ifp->cached_table could be null for myisam sometimes else if (ifp->field && ifp->field->table) - infiniDB = isInfiniDB(ifp->field->table); + infiniDB = isMCSTable(ifp->field->table); if (infiniDB) { @@ -5732,7 +5875,7 @@ void parse_item (Item* item, vector& field_vec, } } -bool isInfiniDB(TABLE* table_ptr) +bool isMCSTable(TABLE* table_ptr) { #if (defined(_MSC_VER) && defined(_DEBUG)) || defined(SAFE_MUTEX) @@ -5754,14 +5897,18 @@ bool isInfiniDB(TABLE* table_ptr) return false; } -int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool isUnion) +int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, + SCSEP& csep, + bool isUnion, + bool isPushdownHand) { #ifdef DEBUG_WALK_COND cerr << "getSelectPlan()" << endl; #endif // by pass the derived table resolve phase of mysql - if (!(((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || + if ( !isPushdownHand && + !(((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) @@ -5913,7 +6060,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i else { // check foreign engine tables - bool infiniDB = (table_ptr->table ? isInfiniDB(table_ptr->table) : true); + bool infiniDB = (table_ptr->table ? isMCSTable(table_ptr->table) : true); // trigger system catalog cache if (infiniDB) @@ -5965,6 +6112,10 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i bool unionSel = false; + // UNION master unit check + // Existed pushdown handlers won't get in this scope + // except UNION pushdown that is to come. + // is_unit_op() give a segv for derived_handler's SELECT_LEX if (!isUnion && select_lex.master_unit()->is_unit_op()) { gwi.thd->infinidb_vtable.isUnion = true; @@ -7212,16 +7363,29 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i { if ((*(ordercol->item))->type() == Item::WINDOW_FUNC_ITEM) gwi.hasWindowFunc = true; + // MCOL-2166 Looking for this sorting item in GROUP_BY items list. + if(isPushdownHand + && !sortItemIsInGrouping(*ordercol->item, select_lex.group_list.first)) + { + std::ostringstream ostream; + std::ostringstream& osr = ostream; + getColNameFromItem(osr, *ordercol->item); + Message::Args args; + args.add(ostream.str()); + string emsg = IDBErrorInfo::instance()->errorMsg(ERR_NOT_GROUPBY_EXPRESSION, args); + gwi.parseErrorText = emsg; + setError(gwi.thd, ER_INTERNAL_ERROR, emsg, gwi); + return ERR_NOT_GROUPBY_EXPRESSION; + } } // re-visit the first of ordercol list ordercol = reinterpret_cast(order_list.first); - // 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 - || ( isUnion && ordercol )) + // for subquery or pushdown query, order+limit by will be supported in CS + // union order by and limit are supported + if (gwi.hasWindowFunc || isPushdownHand || ( isUnion && ordercol ) + || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT ) { for (; ordercol; ordercol = ordercol->next) { @@ -7654,12 +7818,13 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i gwi.returnedCols.push_back(minSc); } - if (!isUnion && !gwi.hasWindowFunc && gwi.subSelectType == CalpontSelectExecutionPlan::MAIN_SELECT) + // ORDER BY translation part + if (!isUnion && !gwi.hasWindowFunc + && gwi.subSelectType == CalpontSelectExecutionPlan::MAIN_SELECT ) { std::ostringstream vtb; vtb << "infinidb_vtable.$vtable_" << gwi.thd->thread_id; - //vtb << "$vtable_" << gwi.thd->thread_id; // re-construct the select query and redo phase 1 if (redo) { @@ -7927,11 +8092,20 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i { gwi.thd->infinidb_vtable.has_order_by = true; csep->hasOrderBy(true); + // To activate LimitedOrderBy + if(isPushdownHand) + { + csep->specHandlerProcessed(true); + } ord_cols = " order by " + ord_cols; select_query += ord_cols; } } + // LIMIT processing part + uint64_t limitNum = std::numeric_limits::max(); + + // non-MAIN union branch if (unionSel || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT) { if (select_lex.master_unit()->global_parameters()->explicit_limit) @@ -7958,6 +8132,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i } } } + // union with explicit select at the top level else if (isUnion && select_lex.explicit_limit) { if (select_lex.braces) @@ -7969,10 +8144,10 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i csep->limitNum(((Item_int*)select_lex.select_limit)->val_int()); } } + // other types of queries that have explicit LIMIT else if (select_lex.explicit_limit) { uint32_t limitOffset = 0; - uint32_t limitNum = std::numeric_limits::max(); if (join) { @@ -8027,6 +8202,12 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i csep->limitStart(limitOffset); csep->limitNum(limitNum); } + // Pushdown queries w ORDER BY and LIMIT + else if (isPushdownHand && csep->hasOrderBy()) + { + csep->limitStart(limitOffset); + csep->limitNum(limitNum); + } else { ostringstream limit; @@ -8034,6 +8215,12 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i select_query += limit.str(); } } + // Pushdown queries with ORDER BY w/o explicit limit + else if (isPushdownHand && csep->hasOrderBy()) + { + // We must set this to activate LimitedOrderBy in ExeMgr + csep->limitNum((uint64_t) - 2); + } gwi.thd->infinidb_vtable.select_vtable_query.free(); gwi.thd->infinidb_vtable.select_vtable_query.append(select_query.c_str(), select_query.length()); @@ -8047,9 +8234,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi); return ER_CHECK_NOT_IMPLEMENTED; } - } + } // LIMIT processing finishes here - if (/*join->select_options*/select_lex.options & SELECT_DISTINCT) + if (select_lex.options & SELECT_DISTINCT) csep->distinct(true); // add the smallest column to count(*) parm. @@ -8283,6 +8470,49 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi) return 0; } +int cs_get_derived_plan(derived_handler* handler, THD* thd, SCSEP& csep) +{ + SELECT_LEX select_lex = *handler->select; + gp_walk_info gwi; + gwi.thd = thd; + int status = getSelectPlan(gwi, select_lex, csep, false, true); + + if (status > 0) + return ER_INTERNAL_ERROR; + else if (status < 0) + return status; + +#ifdef DEBUG_WALK_COND + cerr << "---------------- cp_get_derived_plan EXECUTION PLAN ----------------" << endl; + cerr << *csep << endl ; + cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; +#endif + + return 0; +} + +int cs_get_select_plan(select_handler* handler, THD* thd, SCSEP& csep) +{ + SELECT_LEX select_lex = *handler->select; + gp_walk_info gwi; + gwi.thd = thd; + int status = getSelectPlan(gwi, select_lex, csep, false, true); + + if (status > 0) + return ER_INTERNAL_ERROR; + else if (status < 0) + return status; + +#ifdef DEBUG_WALK_COND + cerr << "---------------- cp_get_select_plan EXECUTION PLAN ----------------" << endl; + cerr << *csep << endl ; + cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; +#endif + + return 0; +} + + /*@brief buildConstColFromFilter- change SimpleColumn into ConstColumn*/ /*********************************************************** * DESCRIPTION: @@ -8290,6 +8520,8 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi) * filter predicate is used, e.g. * field = 'AIR', field IN ('AIR'). This utility function tries to * replace such fields with ConstantColumns using cond_pushed filters. + * TBD Take into account that originalSC SimpleColumn could be: + * SimpleColumn, ArithmeticColumn, FunctionColumn. * PARAMETERS: * originalSC SimpleColumn* removed field * gwi main strucutre @@ -8470,7 +8702,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro else { // check foreign engine tables - bool infiniDB = (table_ptr->table ? isInfiniDB(table_ptr->table) : true); + bool infiniDB = (table_ptr->table ? isMCSTable(table_ptr->table) : true); // trigger system catalog cache if (infiniDB) @@ -9652,6 +9884,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro } // GROUP processing ends here + // ORDER BY processing starts here if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) { ORDER* ordercol = reinterpret_cast(gi.groupByOrder); @@ -9752,26 +9985,9 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // this ORDER BY item. if ( iter == gwi.groupByCols.end() ) { - Item_ident* iip = reinterpret_cast(ord_item); std::ostringstream ostream; - ostream << "'"; - - if (iip->db_name) - ostream << iip->db_name << '.'; - else - ostream << "unknown db" << '.'; - - if (iip->table_name) - ostream << iip->table_name << '.'; - else - ostream << "unknown table" << '.'; - - if (iip->field_name.length) - ostream << iip->field_name.str; - else - ostream << "unknown field"; - - ostream << "'"; + std::ostringstream& osr = ostream; + getColNameFromItem(osr, *ordercol->item); Message::Args args; args.add(ostream.str()); string emsg = IDBErrorInfo::instance()->errorMsg(ERR_NOT_GROUPBY_EXPRESSION, args); diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 1d3c98003..3c53c518a 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -80,6 +80,7 @@ using namespace execplan; using namespace dataconvert; #include "sm.h" +#include "ha_mcs_pushdown.h" #include "bytestream.h" #include "messagequeue.h" @@ -3019,7 +3020,7 @@ int ha_calpont_impl_rnd_next(uchar* buf, TABLE* table) return rc; } -int ha_calpont_impl_rnd_end(TABLE* table) +int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) { int rc = 0; THD* thd = current_thd; @@ -3047,6 +3048,12 @@ int ha_calpont_impl_rnd_end(TABLE* table) thd->infinidb_vtable.isNewQuery = true; + // Workaround because CS doesn't reset isUnion in a normal way. + if (is_pushdown_hand) + { + thd->infinidb_vtable.isUnion = false; + } + if (get_fe_conn_info_ptr() != NULL) ci = reinterpret_cast(get_fe_conn_info_ptr()); if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ORDER_BY ) @@ -5275,4 +5282,552 @@ int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, TABLE* return rc; } + +/*@brief Initiate the query for derived_handler */ +/*********************************************************** + * DESCRIPTION: + * Execute the query and saves derived table query. + * There is an extra handler argument so I ended up with a + * new init function. The code is a copy of + * ha_calpont_impl_rnd_init() mostly. We should come up with + * a semi-universal structure that allows to save any + * extra data. + * PARAMETERS: + * void* handler either select_ or derived_handler + * TABLE* table - table where to save the results + * RETURN: + * rc as int + ***********************************************************/ +int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) +{ +#ifdef DEBUG_SETENV + string home(getenv("HOME")); + + if (!getenv("CALPONT_HOME")) + { + string calpontHome(home + "/Calpont/etc/"); + setenv("CALPONT_HOME", calpontHome.c_str(), 1); + } + + if (!getenv("CALPONT_CONFIG_FILE")) + { + string calpontConfigFile(home + "/Calpont/etc/Columnstore.xml"); + setenv("CALPONT_CONFIG_FILE", calpontConfigFile.c_str(), 1); + } + + if (!getenv("CALPONT_CSC_IDENT")) + setenv("CALPONT_CSC_IDENT", "dm", 1); + +#endif + + IDEBUG( cout << "pushdown_init for table " << endl ); + THD* thd = current_thd; + + //check whether the system is ready to process statement. +#ifndef _MSC_VER + static DBRM dbrm(true); + bool bSystemQueryReady = dbrm.getSystemQueryReady(); + + if (bSystemQueryReady == 0) + { + // Still not ready + setError(thd, ER_INTERNAL_ERROR, "The system is not yet ready to accept queries"); + thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + return ER_INTERNAL_ERROR; + } + else if (bSystemQueryReady < 0) + { + // Still not ready + setError(thd, ER_INTERNAL_ERROR, "DBRM is not responding. Cannot accept queries"); + thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + return ER_INTERNAL_ERROR; + } + +#endif + // 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; + + // return error is error status is already set + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR) + return ER_INTERNAL_ERROR; + + // @bug 2232. Basic SP support. Error out non support sp cases. + // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. + if (thd->infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) + { + setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); + thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + return ER_INTERNAL_ERROR; + } + + // mysql reads table twice for order by + 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); + boost::shared_ptr csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID); + csc->identity(CalpontSystemCatalog::FE); + + if (!thd->infinidb_vtable.cal_conn_info) + thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info()); + + cal_connection_info* ci = reinterpret_cast(thd->infinidb_vtable.cal_conn_info); + + idbassert(ci != 0); + + // MySQL sometimes calls rnd_init multiple times, plan should only be + // generated and sent once. + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && + !thd->infinidb_vtable.isNewQuery) + return 0; + + if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) + { + if (ci->cal_conn_hndl) + { + // send ExeMgr a signal before closing the connection + ByteStream msg; + ByteStream::quadbyte qb = 0; + msg << qb; + + try + { + ci->cal_conn_hndl->exeMgr->write(msg); + } + catch (...) + { + // canceling query. ignore connection failure. + } + + sm::sm_cleanup(ci->cal_conn_hndl); + ci->cal_conn_hndl = 0; + } + + return 0; + } + + sm::tableid_t tableid = 0; + cal_table_info ti; + sm::cpsm_conhdl_t* hndl; + SCSEP csep; + // Declare handlers ptrs in this scope for future use. + select_handler* sh = NULL; + derived_handler* dh = NULL; + + // 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 || + (thd->slave_thread && thd->infinidb_vtable.vtable_state == THD::INFINIDB_INIT)) + { + ci->traceFlags |= CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; + thd->infinidb_vtable.vtable_state = THD::INFINIDB_DISABLE_VTABLE; + } + else + { + ci->traceFlags = (ci->traceFlags | CalpontSelectExecutionPlan::TRACE_TUPLE_OFF)^ + CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; + } + + bool localQuery = (thd->variables.infinidb_local_query > 0 ? true : false); + + { + //if (!ci->cal_conn_hndl || thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + { + ci->stats.reset(); // reset query stats + ci->stats.setStartTime(); + ci->stats.fUser = thd->main_security_ctx.user; + + if (thd->main_security_ctx.host) + ci->stats.fHost = thd->main_security_ctx.host; + else if (thd->main_security_ctx.host_or_ip) + ci->stats.fHost = thd->main_security_ctx.host_or_ip; + else + ci->stats.fHost = "unknown"; + + try + { + ci->stats.userPriority(ci->stats.fHost, ci->stats.fUser); + } + catch (std::exception& e) + { + string msg = string("Columnstore User Priority - ") + e.what(); + ci->warningMsg = msg; + } + + // if the previous query has error, re-establish the connection + if (ci->queryState != 0) + { + sm::sm_cleanup(ci->cal_conn_hndl); + ci->cal_conn_hndl = 0; + } + } + + sm::sm_init(sessionID, &ci->cal_conn_hndl, localQuery); + idbassert(ci->cal_conn_hndl != 0); + ci->cal_conn_hndl->csc = csc; + idbassert(ci->cal_conn_hndl->exeMgr != 0); + + try + { + ci->cal_conn_hndl->connect(); + } + catch (...) + { + setError(thd, ER_INTERNAL_ERROR, IDBErrorInfo::instance()->errorMsg(ERR_LOST_CONN_EXEMGR)); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto error; + } + + hndl = ci->cal_conn_hndl; + + if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE) + { + if (!csep) + 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(); + + csep->txnID(txnID.id); + csep->verID(verID); + csep->sessionID(sessionID); + + if (thd->db.length) + csep->schemaName(thd->db.str); + + csep->traceFlags(ci->traceFlags); + + if (thd->infinidb_vtable.isInsertSelect) + csep->queryType(CalpontSelectExecutionPlan::INSERT_SELECT); + + // cast the handler and get a plan. + int status = 42; + if (handler_info->hndl_type == mcs_handler_types_t::SELECT) + { + sh = reinterpret_cast(handler_info->hndl_ptr); + status = cs_get_select_plan(sh, thd, csep); + } + else if (handler_info->hndl_type == DERIVED) + { + dh = reinterpret_cast(handler_info->hndl_ptr); + status = cs_get_derived_plan(dh, thd, csep); + } + + // WIP MCOL-2121 Find a way to return an actual error + // It either ends up with 42 or other error status + if (status > 0) + goto internal_error; + else if (status < 0) + return 0; + + // @bug 2547. don't need to send the plan if it's impossible where for all unions. + if (thd->infinidb_vtable.impossibleWhereOnUnion) + return 0; + + string query; + query.assign(idb_mysql_query_str(thd)); + //query.assign(thd->infinidb_vtable.original_query.ptr(), + // thd->infinidb_vtable.original_query.length()); + csep->data(query); + + try + { + csep->priority( ci->stats.userPriority(ci->stats.fHost, ci->stats.fUser)); + } + catch (std::exception& e) + { + string msg = string("Columnstore User Priority - ") + e.what(); + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, msg.c_str()); + } + +#ifdef PLAN_HEX_FILE + // plan serialization + ifstream ifs("/tmp/li1-plan.hex"); + ByteStream bs1; + ifs >> bs1; + ifs.close(); + csep->unserialize(bs1); +#endif + + if (ci->traceFlags & 1) + { + cerr << "---------------- EXECUTION PLAN ----------------" << endl; + cerr << *csep << endl ; + cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; + } + else + { + IDEBUG( cout << "---------------- EXECUTION PLAN ----------------" << endl ); + IDEBUG( cerr << *csep << endl ); + IDEBUG( cout << "-------------- EXECUTION PLAN END --------------\n" << endl ); + } + } + }// end of execution plan generation + + if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE) + { + ByteStream msg; + ByteStream emsgBs; + + while (true) + { + try + { + ByteStream::quadbyte qb = 4; + msg << qb; + hndl->exeMgr->write(msg); + msg.restart(); + csep->rmParms(rmParms); + + //send plan + csep->serialize(msg); + hndl->exeMgr->write(msg); + + //get ExeMgr status back to indicate a vtable joblist success or not + msg.restart(); + emsgBs.restart(); + msg = hndl->exeMgr->read(); + emsgBs = hndl->exeMgr->read(); + string emsg; + + if (msg.length() == 0 || emsgBs.length() == 0) + { + emsg = "Lost connection to ExeMgr. Please contact your administrator"; + setError(thd, ER_INTERNAL_ERROR, emsg); + return ER_INTERNAL_ERROR; + } + + string emsgStr; + emsgBs >> emsgStr; + bool err = false; + + if (msg.length() == 4) + { + msg >> qb; + + if (qb != 0) + { + err = true; + // for makejoblist error, stats contains only error code and insert from here + // because table fetch is not started + ci->stats.setEndTime(); + ci->stats.fQuery = csep->data(); + ci->stats.fQueryType = csep->queryType(); + ci->stats.fErrorNo = qb; + + try + { + ci->stats.insert(); + } + catch (std::exception& e) + { + string msg = string("Columnstore Query Stats - ") + e.what(); + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, msg.c_str()); + } + } + } + else + { + err = true; + } + + if (err) + { + setError(thd, ER_INTERNAL_ERROR, emsgStr); + return ER_INTERNAL_ERROR; + } + + rmParms.clear(); + + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + { + ci->tableMap[table] = ti; + } + else + { + ci->queryState = 1; + } + + break; + } + catch (...) + { + sm::sm_cleanup(hndl); + hndl = 0; + + sm::sm_init(sessionID, &hndl, localQuery); + idbassert(hndl != 0); + hndl->csc = csc; + + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + ti.conn_hndl = hndl; + else + ci->cal_conn_hndl = hndl; + + try + { + hndl->connect(); + } + catch (...) + { + setError(thd, ER_INTERNAL_ERROR, IDBErrorInfo::instance()->errorMsg(ERR_LOST_CONN_EXEMGR)); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto error; + } + + msg.restart(); + } + } + } + + // set query state to be in_process. Sometimes mysql calls rnd_init multiple + // times, this makes sure plan only being generated and sent once. It will be + // reset when query finishes in sm::end_query + thd->infinidb_vtable.isNewQuery = false; + + // common path for both vtable select phase and table mode -- open scan handle + ti = ci->tableMap[table]; + // This is the server's temp table for the result. + if(sh) + { + ti.msTablePtr = sh->table; + } + else + { + ti.msTablePtr = dh->table; + } + + { + if (ti.tpl_ctx == 0) + { + ti.tpl_ctx = new sm::cpsm_tplh_t(); + ti.tpl_scan_ctx = sm::sp_cpsm_tplsch_t(new sm::cpsm_tplsch_t()); + } + + // make sure rowgroup is null so the new meta data can be taken. This is for some case mysql + // call rnd_init for a table more than once. + ti.tpl_scan_ctx->rowGroup = NULL; + + try + { + tableid = execplan::IDB_VTABLE_ID; + } + catch (...) + { + string emsg = "No table ID found for table " + string(table->s->table_name.str); + setError(thd, ER_INTERNAL_ERROR, emsg); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto internal_error; + } + + try + { + sm::tpl_open(tableid, ti.tpl_ctx, hndl); + sm::tpl_scan_open(tableid, ti.tpl_scan_ctx, hndl); + } + catch (std::exception& e) + { + string emsg = "table can not be opened: " + string(e.what()); + setError(thd, ER_INTERNAL_ERROR, emsg); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto internal_error; + } + catch (...) + { + string emsg = "table can not be opened"; + setError(thd, ER_INTERNAL_ERROR, emsg); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto internal_error; + } + + ti.tpl_scan_ctx->traceFlags = ci->traceFlags; + + if ((ti.tpl_scan_ctx->ctp).size() == 0) + { + uint32_t num_attr = table->s->fields; + + for (uint32_t i = 0; i < num_attr; i++) + { + CalpontSystemCatalog::ColType ctype; + ti.tpl_scan_ctx->ctp.push_back(ctype); + } + + // populate coltypes here for table mode because tableband gives treeoid for dictionary column + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + { + CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(make_table(table->s->db.str, table->s->table_name.str), true); + + if (oidlist.size() != num_attr) + { + string emsg = "Size mismatch probably caused by front end out of sync"; + setError(thd, ER_INTERNAL_ERROR, emsg); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto internal_error; + } + + for (unsigned int j = 0; j < oidlist.size(); j++) + { + CalpontSystemCatalog::ColType ctype = csc->colType(oidlist[j].objnum); + ti.tpl_scan_ctx->ctp[ctype.colPosition] = ctype; + ti.tpl_scan_ctx->ctp[ctype.colPosition].colPosition = -1; + } + } + } + } + + ci->tableMap[table] = ti; + return 0; + +error: + + if (ci->cal_conn_hndl) + { + sm::sm_cleanup(ci->cal_conn_hndl); + ci->cal_conn_hndl = 0; + } + + // do we need to close all connection handle of the table map? + return ER_INTERNAL_ERROR; + +internal_error: + + if (ci->cal_conn_hndl) + { + sm::sm_cleanup(ci->cal_conn_hndl); + ci->cal_conn_hndl = 0; + } + + return ER_INTERNAL_ERROR; +} // vim:sw=4 ts=4: diff --git a/dbcon/mysql/ha_calpont_impl.h b/dbcon/mysql/ha_calpont_impl.h index bdc0e0eef..7e8de5ce5 100644 --- a/dbcon/mysql/ha_calpont_impl.h +++ b/dbcon/mysql/ha_calpont_impl.h @@ -20,6 +20,7 @@ #define HA_CALPONT_IMPL_H__ #include "idb_mysql.h" +#include "ha_mcs_pushdown.h" #ifdef NEED_CALPONT_EXTERNS extern int ha_calpont_impl_discover_existence(const char* schema, const char* name); @@ -29,7 +30,7 @@ extern int ha_calpont_impl_open(const char* name, int mode, uint32_t test_if_loc extern int ha_calpont_impl_close(void); extern int ha_calpont_impl_rnd_init(TABLE* table); extern int ha_calpont_impl_rnd_next(uchar* buf, TABLE* table); -extern int ha_calpont_impl_rnd_end(TABLE* table); +extern int ha_calpont_impl_rnd_end(TABLE* table, bool is_derived_hand = false); extern int ha_calpont_impl_write_row(uchar* buf, TABLE* table); extern void ha_calpont_impl_start_bulk_insert(ha_rows rows, TABLE* table); extern int ha_calpont_impl_end_bulk_insert(bool abort, TABLE* table); @@ -45,6 +46,7 @@ extern int ha_calpont_impl_rnd_pos(uchar* buf, uchar* pos); extern int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE* table); extern int ha_calpont_impl_group_by_next(ha_calpont_group_by_handler* group_hand, TABLE* table); extern int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, TABLE* table); +extern int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info , TABLE* table); #endif @@ -52,6 +54,7 @@ extern int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, #include "ha_calpont_impl_if.h" #include "calpontsystemcatalog.h" #include "ha_calpont.h" +#include "ha_mcs_pushdown.h" extern int ha_calpont_impl_rename_table_(const char* from, const char* to, cal_impl_if::cal_connection_info& ci); extern int ha_calpont_impl_write_row_(uchar* buf, TABLE* table, cal_impl_if::cal_connection_info& ci, ha_rows& rowsInserted); extern int ha_calpont_impl_write_batch_row_(uchar* buf, TABLE* table, cal_impl_if::cal_connection_info& ci); @@ -71,6 +74,7 @@ extern std::string ha_calpont_impl_cleartablelock( cal_impl_if::cal_connection_ extern int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE* table); extern int ha_calpont_impl_group_by_next(ha_calpont_group_by_handler* group_hand, TABLE* table); extern int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, TABLE* table); +extern int ha_cs_impl_derived_next(TABLE* table); #endif #endif diff --git a/dbcon/mysql/ha_calpont_impl_if.h b/dbcon/mysql/ha_calpont_impl_if.h index 6d8945ad8..820f8d430 100644 --- a/dbcon/mysql/ha_calpont_impl_if.h +++ b/dbcon/mysql/ha_calpont_impl_if.h @@ -337,14 +337,16 @@ const std::string infinidb_err_msg = "\nThe query includes syntax that is not su 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 cs_get_derived_plan(derived_handler* handler, THD* thd, SCSEP& csep); +int cs_get_select_plan(select_handler* handler, THD* thd, SCSEP& csep); +int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, bool isUnion = false, bool isPushdownHand = 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); 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); +bool isMCSTable(TABLE* table_ptr); // execution plan util functions prototypes execplan::ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupport, bool pushdownHand = false); diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp new file mode 100644 index 000000000..bc4673a11 --- /dev/null +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -0,0 +1,661 @@ +/* + Copyright (c) 2019 MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + + +// ha_calpont.cpp includes this file. + +/*@brief check_walk - It traverses filter conditions*/ +/************************************************************ + * DESCRIPTION: + * It traverses filter predicates looking for unsupported + * JOIN types: non-equi JOIN, e.g t1.c1 > t2.c2; + * logical OR. + * PARAMETERS: + * thd - THD pointer. + * derived - TABLE_LIST* to work with. + * RETURN: + * derived_handler if possible + * NULL in other case + ***********************************************************/ +void check_walk(const Item* item, void* arg) +{ + bool* unsupported_feature = static_cast(arg); + if ( *unsupported_feature ) + return; + switch (item->type()) + { + case Item::FUNC_ITEM: + { + const Item_func* ifp = static_cast(item); + + if ( ifp->functype() != Item_func::EQ_FUNC ) // NON-equi JOIN + { + if ( ifp->argument_count() == 2 && + ifp->arguments()[0]->type() == Item::FIELD_ITEM && + ifp->arguments()[1]->type() == Item::FIELD_ITEM ) + { + Item_field* left= static_cast(ifp->arguments()[0]); + Item_field* right= static_cast(ifp->arguments()[1]); + + if ( left->field->table != right->field->table ) + { + *unsupported_feature = true; + return; + } + } + else // IN + correlated subquery + { + if ( ifp->functype() == Item_func::NOT_FUNC + && ifp->arguments()[0]->type() == Item::EXPR_CACHE_ITEM ) + { + check_walk(ifp->arguments()[0], arg); + } + } + } + break; + } + + case Item::EXPR_CACHE_ITEM: // IN + correlated subquery + { + const Item_cache_wrapper* icw = static_cast(item); + if ( icw->get_orig_item()->type() == Item::FUNC_ITEM ) + { + const Item_func *ifp = static_cast(icw->get_orig_item()); + if ( ifp->argument_count() == 2 && + ( ifp->arguments()[0]->type() == Item::Item::SUBSELECT_ITEM + || ifp->arguments()[1]->type() == Item::Item::SUBSELECT_ITEM )) + { + *unsupported_feature = true; + return; + } + } + break; + } + + case Item::COND_ITEM: // OR in JOIN conds is unsupported yet + { + Item_cond* icp = (Item_cond*)item; + if ( is_cond_or(icp) ) + { + *unsupported_feature = true; + } + break; + } + default: + { + break; + } + } +} + +/*@brief create_calpont_group_by_handler- Creates handler*/ +/*********************************************************** + * DESCRIPTION: + * Creates a group_by pushdown handler if there is no: + * non-equi JOIN, e.g * t1.c1 > t2.c2 + * logical OR in the filter predicates + * Impossible WHERE + * Impossible HAVING + * and there is either GROUP BY or aggregation function + * exists at the top level. + * Valid queries with the last two crashes the server if + * processed. + * Details are in server/sql/group_by_handler.h + * PARAMETERS: + * thd - THD pointer + * query - Query structure LFM in group_by_handler.h + * RETURN: + * group_by_handler if success + * NULL in other case + ***********************************************************/ +static group_by_handler* +create_calpont_group_by_handler(THD* thd, Query* query) +{ + ha_calpont_group_by_handler* handler = NULL; + // same as thd->lex->current_select + SELECT_LEX *select_lex = query->from->select_lex; + + // Create a handler if query is valid. See comments for details. + if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE + && ( thd->variables.infinidb_vtable_mode == 0 + || thd->variables.infinidb_vtable_mode == 2 ) + && ( query->group_by || select_lex->with_sum_func ) ) + { + bool unsupported_feature = false; + // revisit SELECT_LEX for all units + for(TABLE_LIST* tl = query->from; !unsupported_feature && tl; tl = tl->next_global) + { + select_lex = tl->select_lex; + // Correlation subquery. Comming soon so fail on this yet. + unsupported_feature = select_lex->is_correlated; + + // Impossible HAVING or WHERE + if ( ( !unsupported_feature && query->having && select_lex->having_value == Item::COND_FALSE ) + || ( select_lex->cond_count > 0 + && select_lex->cond_value == Item::COND_FALSE ) ) + { + unsupported_feature = true; + } + + // Unsupported JOIN conditions + if ( !unsupported_feature ) + { + JOIN *join = select_lex->join; + Item_cond *icp = 0; + + if (join != 0) + icp = reinterpret_cast(join->conds); + + if ( unsupported_feature == false + && icp ) + { + icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); + } + + // Optimizer could move some join conditions into where + if (select_lex->where != 0) + icp = reinterpret_cast(select_lex->where); + + if ( unsupported_feature == false + && icp ) + { + icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); + } + + } + } // unsupported features check ends here + + if ( !unsupported_feature ) + { + 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; + } + } + + return handler; +} + +/*@brief create_columnstore_derived_handler- Creates handler*/ +/************************************************************ + * DESCRIPTION: + * Creates a derived handler if there is no non-equi JOIN, e.g + * t1.c1 > t2.c2 and logical OR in the filter predicates. + * More details in server/sql/derived_handler.h + * PARAMETERS: + * thd - THD pointer. + * derived - TABLE_LIST* to work with. + * RETURN: + * derived_handler if possible + * NULL in other case + ***********************************************************/ +static derived_handler* +create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived) +{ + ha_columnstore_derived_handler* handler = NULL; + handlerton *ht= 0; + + SELECT_LEX_UNIT *unit= derived->derived; + + if ( thd->infinidb_vtable.vtable_state != THD::INFINIDB_DISABLE_VTABLE + && thd->variables.infinidb_vtable_mode != 0 ) + { + return 0; + } + + for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) + { + if (!(sl->join)) + return 0; + for (TABLE_LIST *tbl= sl->join->tables_list; tbl; tbl= tbl->next_local) + { + if (!tbl->table) + return 0; + // Same handlerton type check. + if (!ht) + ht= tbl->table->file->partition_ht(); + else if (ht != tbl->table->file->partition_ht()) + return 0; + } + } + + bool unsupported_feature = false; + { + SELECT_LEX select_lex = *unit->first_select(); + JOIN* join = select_lex.join; + Item_cond* icp = 0; + + if (join != 0) + icp = reinterpret_cast(join->conds); + + if (!join) + { + icp = reinterpret_cast(select_lex.where); + } + + if ( icp ) + { + icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); + } + } + + if ( !unsupported_feature ) + handler= new ha_columnstore_derived_handler(thd, derived); + + return handler; +} + +/*********************************************************** + * DESCRIPTION: + * derived_handler constructor + * PARAMETERS: + * thd - THD pointer. + * tbl - tables involved. + ***********************************************************/ +ha_columnstore_derived_handler::ha_columnstore_derived_handler(THD *thd, + TABLE_LIST *dt) + : derived_handler(thd, calpont_hton) +{ + derived = dt; +} + +/*********************************************************** + * DESCRIPTION: + * derived_handler destructor + ***********************************************************/ +ha_columnstore_derived_handler::~ha_columnstore_derived_handler() +{} + +/*@brief Initiate the query for derived_handler */ +/*********************************************************** + * DESCRIPTION: + * Execute the query and saves derived table query. + * ATM this function sets vtable_state and restores it afterwards + * since it reuses existed vtable code internally. + * PARAMETERS: + * + * RETURN: + * rc as int + ***********************************************************/ +int ha_columnstore_derived_handler::init_scan() +{ + char query_buff[4096]; + + DBUG_ENTER("ha_columnstore_derived_handler::init_scan"); + + // Save query for logging + String derived_query(query_buff, sizeof(query_buff), thd->charset()); + derived_query.length(0); + derived->derived->print(&derived_query, QT_ORDINARY); + + // Save vtable_state to restore the after we inited. + THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + + mcs_handler_info mhi = mcs_handler_info(static_cast(this), DERIVED); + // this::table is the place for the result set + int rc = ha_cs_impl_pushdown_init(&mhi, table); + + thd->infinidb_vtable.vtable_state = oldState; + + DBUG_RETURN(rc); +} + +/*@brief Fetch next row for derived_handler */ +/*********************************************************** + * DESCRIPTION: + * Fetches next row and saves it in the temp table + * ATM this function sets vtable_state and restores it + * afterwards since it reuses existed vtable code internally. + * PARAMETERS: + * + * RETURN: + * rc as int + * + ***********************************************************/ +int ha_columnstore_derived_handler::next_row() +{ + DBUG_ENTER("ha_columnstore_derived_handler::next_row"); + + // Save vtable_state to restore the after we inited. + THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + + thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + + int rc = ha_calpont_impl_rnd_next(table->record[0], table); + + thd->infinidb_vtable.vtable_state = oldState; + + DBUG_RETURN(rc); +} + +/*@brief Finishes the scan and clean it up */ +/*********************************************************** + * DESCRIPTION: + * Finishes the scan for derived handler + * ATM this function sets vtable_state and restores it + * afterwards since it reuses existed vtable code internally. + * PARAMETERS: + * + * RETURN: + * rc as int + * + ***********************************************************/ +int ha_columnstore_derived_handler::end_scan() +{ + DBUG_ENTER("ha_columnstore_derived_handler::end_scan"); + + THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + thd->infinidb_vtable.vtable_state = THD::INFINIDB_SELECT_VTABLE; + + int rc = ha_calpont_impl_rnd_end(table, true); + + thd->infinidb_vtable.vtable_state = oldState; + + DBUG_RETURN(rc); +} + +void ha_columnstore_derived_handler::print_error(int, unsigned long) +{ +} + +/*********************************************************** + * DESCRIPTION: + * GROUP BY handler constructor + * PARAMETERS: + * thd - THD pointer. + * query - Query describing structure + ***********************************************************/ +ha_calpont_group_by_handler::ha_calpont_group_by_handler(THD* thd_arg, Query* query) + : group_by_handler(thd_arg, calpont_hton), + select(query->select), + table_list(query->from), + distinct(query->distinct), + where(query->where), + group_by(query->group_by), + order_by(query->order_by), + having(query->having) +{ +} + +/*********************************************************** + * DESCRIPTION: + * GROUP BY destructor + ***********************************************************/ +ha_calpont_group_by_handler::~ha_calpont_group_by_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"); + + // Save vtable_state to restore the after we inited. + THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + // MCOL-1052 Should be removed after cleaning the code up. + thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + int rc = ha_calpont_impl_group_by_init(this, table); + thd->infinidb_vtable.vtable_state = oldState; + + 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"); + int rc = ha_calpont_impl_group_by_next(this, table); + + 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"); + + int rc = ha_calpont_impl_group_by_end(this, table); + + DBUG_RETURN(rc); +} + +/*@brief create_columnstore_select_handler- Creates handler*/ +/************************************************************ + * DESCRIPTION: + * Creates a select handler if there is no non-equi JOIN, e.g + * t1.c1 > t2.c2 and logical OR in the filter predicates. + * More details in server/sql/select_handler.h + * PARAMETERS: + * thd - THD pointer. + * sel - SELECT_LEX* that describes the query. + * RETURN: + * select_handler if possible + * NULL in other case + ***********************************************************/ +static select_handler* +create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) +{ + ha_columnstore_select_handler* handler = NULL; + handlerton *ht= 0; + + // Return if vtable enabled. + if ( thd->infinidb_vtable.vtable_state != THD::INFINIDB_DISABLE_VTABLE + && thd->variables.infinidb_vtable_mode != 0 ) + { + return 0; + } + for (SELECT_LEX* sl = select_lex;sl; sl= sl->next_select()) + { + if (!(sl->join)) + return 0; + for (TABLE_LIST *tbl= sl->join->tables_list; tbl; tbl= tbl->next_local) + { + if (!tbl->table) + return 0; + // Same handlerton type check. + if (!ht) + ht= tbl->table->file->partition_ht(); + else if (ht != tbl->table->file->partition_ht()) + return 0; + } + } + + bool unsupported_feature = false; + // Impossible HAVING or WHERE + if ( ( select_lex->having && select_lex->having_value == Item::COND_FALSE ) + || ( select_lex->cond_count > 0 + && select_lex->cond_value == Item::COND_FALSE ) ) + { + unsupported_feature = true; + } + + // Unsupported query check. + if ( !unsupported_feature ) + { + // JOIN expression from WHERE, ON expressions + JOIN* join = select_lex->join; + Item_cond* where_icp = 0; + Item_cond* on_icp = 0; + + if (join != 0) + { + where_icp = reinterpret_cast(join->conds); + } + + if ( where_icp ) + { + where_icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); + } + + // Looking for JOIN with ON expression through + // TABLE_LIST in FROM until CS meets unsupported feature + TABLE_LIST* table_ptr = select_lex->get_table_list(); + for (; !unsupported_feature && table_ptr; table_ptr = table_ptr->next_global) + { + if(table_ptr->on_expr) + { + on_icp = reinterpret_cast(table_ptr->on_expr); + on_icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); + } + } + + // CROSS JOIN w/o conditions isn't supported until MCOL-301 + // is ready. + if (join && join->table_count >= 2 && ( !where_icp && !on_icp )) + { + unsupported_feature = true; + } + } + + if (!unsupported_feature) + { + handler = new ha_columnstore_select_handler(thd, select_lex); + } + + return handler; +} + +/*********************************************************** + * DESCRIPTION: + * select_handler constructor + * PARAMETERS: + * thd - THD pointer. + * select_lex - sematic tree for the query. + ***********************************************************/ +ha_columnstore_select_handler::ha_columnstore_select_handler(THD *thd, + SELECT_LEX* select_lex) + : select_handler(thd, calpont_hton) +{ + select = select_lex; +} + +/*********************************************************** + * DESCRIPTION: + * select_handler constructor + ***********************************************************/ +ha_columnstore_select_handler::~ha_columnstore_select_handler() +{} + +/*@brief Initiate the query for select_handler */ +/*********************************************************** + * DESCRIPTION: + * Execute the query and saves select table query. + * ATM this function sets vtable_state and restores it afterwards + * since it reuses existed vtable code internally. + * PARAMETERS: + * + * RETURN: + * rc as int + ***********************************************************/ +int ha_columnstore_select_handler::init_scan() +{ + char query_buff[4096]; + + DBUG_ENTER("ha_columnstore_select_handler::init_scan"); + + // Save query for logging + String select_query(query_buff, sizeof(query_buff), thd->charset()); + select_query.length(0); + select->print(thd, &select_query, QT_ORDINARY); + + // Save vtable_state to restore the after we inited. + THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + + mcs_handler_info mhi = mcs_handler_info(static_cast(this), SELECT); + // this::table is the place for the result set + int rc = ha_cs_impl_pushdown_init(&mhi, table); + + thd->infinidb_vtable.vtable_state = oldState; + + DBUG_RETURN(rc); +} + +/*@brief Fetch next row for select_handler */ +/*********************************************************** + * DESCRIPTION: + * Fetches next row and saves it in the temp table + * ATM this function sets vtable_state and restores it + * afterwards since it reuses existed vtable code internally. + * PARAMETERS: + * + * RETURN: + * rc as int + * + ***********************************************************/ +int ha_columnstore_select_handler::next_row() +{ + DBUG_ENTER("ha_columnstore_select_handler::next_row"); + + // Save vtable_state to restore the after we inited. + THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + + thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + + int rc = ha_calpont_impl_rnd_next(table->record[0], table); + + thd->infinidb_vtable.vtable_state = oldState; + + DBUG_RETURN(rc); +} + +/*@brief Finishes the scan and clean it up */ +/*********************************************************** + * DESCRIPTION: + * Finishes the scan for select handler + * ATM this function sets vtable_state and restores it + * afterwards since it reuses existed vtable code internally. + * PARAMETERS: + * + * RETURN: + * rc as int + * + ***********************************************************/ +int ha_columnstore_select_handler::end_scan() +{ + DBUG_ENTER("ha_columnstore_select_handler::end_scan"); + + THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + thd->infinidb_vtable.vtable_state = THD::INFINIDB_SELECT_VTABLE; + + int rc = ha_calpont_impl_rnd_end(table, true); + + thd->infinidb_vtable.vtable_state = oldState; + + DBUG_RETURN(rc); +} + +void ha_columnstore_select_handler::print_error(int, unsigned long) +{} diff --git a/dbcon/mysql/ha_mcs_pushdown.h b/dbcon/mysql/ha_mcs_pushdown.h new file mode 100644 index 000000000..2849cb530 --- /dev/null +++ b/dbcon/mysql/ha_mcs_pushdown.h @@ -0,0 +1,142 @@ +/* + Copyright (c) 2019 MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + + +#ifndef HA_MCS_PUSH +#define HA_MCS_PUSH + +#include "idb_mysql.h" +#include "ha_calpont.h" + +enum mcs_handler_types_t +{ + SELECT, + DERIVED, + GROUP_BY, + LEGACY +}; + +struct mcs_handler_info +{ + mcs_handler_info() : hndl_ptr(NULL), hndl_type(LEGACY) { }; + mcs_handler_info(mcs_handler_types_t type) : hndl_ptr(NULL), hndl_type(type) { }; + mcs_handler_info(void* ptr, mcs_handler_types_t type) : hndl_ptr(ptr), hndl_type(type) { }; + ~mcs_handler_info() { }; + void* hndl_ptr; + mcs_handler_types_t hndl_type; +}; + +/*@brief group_by_handler class*/ +/*********************************************************** + * DESCRIPTION: + * Provides server with group_by_handler API methods. + * One should read comments in server/sql/group_by_handler.h + * Attributes: + * select - attribute contains all GROUP BY, HAVING, ORDER items and calls it + * an extended SELECT list according to comments in + * server/sql/group_handler.cc. + * So the temporary table for + * select count(*) from b group by a having a > 3 order by a + * will have 4 columns not 1. + * However server ignores all NULLs used in + * GROUP BY, HAVING, ORDER. + * select_list_descr - contains Item description returned by Item->print() + * that is used in lookup for corresponding columns in + * extended SELECT list. + * table_list - contains all tables involved. Must be CS tables only. + * distinct - looks like a useless thing for now. Couldn't get it set by server. + * where - where items. + * group_by - group by ORDER items. + * order_by - order by ORDER items. + * having - having Item. + * Methods: + * init_scan - get plan and send it to ExeMgr. Get the execution result. + * next_row - get a row back from sm. + * end_scan - finish and clean the things up. + ***********************************************************/ +class ha_calpont_group_by_handler: public group_by_handler +{ +public: + ha_calpont_group_by_handler(THD* thd_arg, Query* query); + ~ha_calpont_group_by_handler(); + int init_scan(); + int next_row(); + int end_scan(); + + List* select; + TABLE_LIST* table_list; + bool distinct; + Item* where; + ORDER* group_by; + ORDER* order_by; + Item* having; +}; + +/*@brief derived_handler class*/ +/*********************************************************** + * DESCRIPTION: + * derived_handler API methods. Could be used by the server + * tp process sub-queries. + * More details in server/sql/dervied_handler.h + * INFINIDB_SHARE* hton share + * tbl in the constructor is the list of the tables involved. + * Methods: + * init_scan - get plan and send it to ExeMgr. Get the execution result. + * next_row - get a row back from sm. + * end_scan - finish and clean the things up. + ***********************************************************/ +class ha_columnstore_derived_handler: public derived_handler +{ +private: + INFINIDB_SHARE *share; + +public: + ha_columnstore_derived_handler(THD* thd_arg, TABLE_LIST *tbl); + ~ha_columnstore_derived_handler(); + int init_scan(); + int next_row(); + int end_scan(); + void print_error(int, unsigned long); +}; + +/*@brief select_handler class*/ +/*********************************************************** + * DESCRIPTION: + * select_handler API methods. Could be used by the server + * tp pushdown the whole query described by SELECT_LEX. + * More details in server/sql/select_handler.h + * INFINIDB_SHARE* hton share + * sel in the constructor is the semantic tree for the query. + * Methods: + * init_scan - get plan and send it to ExeMgr. Get the execution result. + * next_row - get a row back from sm. + * end_scan - finish and clean the things up. + ***********************************************************/ +class ha_columnstore_select_handler: public select_handler +{ +private: + INFINIDB_SHARE *share; + +public: + ha_columnstore_select_handler(THD* thd_arg, SELECT_LEX* sel); + ~ha_columnstore_select_handler(); + int init_scan(); + int next_row(); + int end_scan(); + void print_error(int, unsigned long); +}; + +#endif diff --git a/dbcon/mysql/ha_view.cpp b/dbcon/mysql/ha_view.cpp index 764c2c5c5..3bc49b2a8 100644 --- a/dbcon/mysql/ha_view.cpp +++ b/dbcon/mysql/ha_view.cpp @@ -117,7 +117,7 @@ void View::transform() else { // check foreign engine tables - bool infiniDB = (table_ptr->table ? isInfiniDB(table_ptr->table) : true); + bool infiniDB = (table_ptr->table ? isMCSTable(table_ptr->table) : true); // trigger system catalog cache if (infiniDB) diff --git a/dbcon/mysql/idb_mysql.h b/dbcon/mysql/idb_mysql.h index 25f3effcf..cb842d740 100644 --- a/dbcon/mysql/idb_mysql.h +++ b/dbcon/mysql/idb_mysql.h @@ -70,6 +70,8 @@ template bool isnan(T); #include "item_windowfunc.h" #include "sql_cte.h" #include "tztime.h" +#include "derived_handler.h" +#include "select_handler.h" // Now clean up the pollution as best we can... #undef min From 6fd5b2f22d905ffbd743aa2b623fd329953acd13 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Tue, 19 Feb 2019 20:37:44 +0300 Subject: [PATCH 02/11] MCOL-2178 Merging with 10.4 SELECT_LEX had been moved in THD so changed all references. Avoid writing CS decimal scales into MDB decimal fields d-only dec attribute. WIP Replaced infinidb_vtable with a singleton MIGR. Merged with MCOL-2121. Added new wsrep include paths needed by UDaF code. Removed .vcxproj from Connector code. --- CMakeLists.txt | 4 +- dbcon/mysql/ha_calpont_ddl.cpp | 4 +- dbcon/mysql/ha_calpont_dml.cpp | 4 +- dbcon/mysql/ha_calpont_execplan.cpp | 87 ++++---- dbcon/mysql/ha_calpont_impl.cpp | 321 ++++++++++++++-------------- dbcon/mysql/ha_mcs_pushdown.cpp | 59 ++--- dbcon/mysql/ha_mcs_sysvars.cpp | 150 +++---------- dbcon/mysql/ha_view.cpp | 2 +- dbcon/mysql/idb_mysql.h | 63 ++++++ 9 files changed, 335 insertions(+), 359 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b931d30c0..3be90eaa4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,11 +283,13 @@ SET (ENGINE_WE_CONFIGCPP_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/writeengine/x SET (ENGINE_SERVER_SQL_INCLUDE "${SERVER_SOURCE_ROOT_DIR}/sql") SET (ENGINE_SERVER_INCLUDE_INCLUDE "${SERVER_SOURCE_ROOT_DIR}/include") SET (ENGINE_SERVER_PCRE_INCLUDE "${SERVER_BUILD_INCLUDE_DIR}/../pcre") +SET (ENGINE_SERVER_WSREP_INCLUDE "${SERVER_BUILD_INCLUDE_DIR}/../wsrep-lib/include") +SET (ENGINE_SERVER_WSREP_API_INCLUDE "${SERVER_BUILD_INCLUDE_DIR}/../wsrep-lib/wsrep-API/v26/") SET (ENGINE_UTILS_UDFSDK_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/utils/udfsdk") SET (ENGINE_DEFAULT_INCLUDES ${CMAKE_BINARY_DIR} "." "../" "../../" ${SERVER_BUILD_INCLUDE_DIR}) -SET (ENGINE_COMMON_INCLUDES ${ENGINE_DEFAULT_INCLUDES} ${Boost_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ${ENGINE_UTILS_MESSAGEQCPP_INCLUDE} ${ENGINE_WE_SHARED_INCLUDE} ${ENGINE_UTILS_IDBDATAFILE_INCLUDE} ${ENGINE_UTILS_LOGGINGCPP_INCLUDE} ${ENGINE_UTILS_CONFIGCPP_INCLUDE} ${ENGINE_UTILS_COMPRESS_INCLUDE} ${ENGINE_VERSIONING_BRM_INCLUDE} ${ENGINE_UTILS_ROWGROUP_INCLUDE} ${ENGINE_UTILS_COMMON_INCLUDE} ${ENGINE_UTILS_DATACONVERT_INCLUDE} ${ENGINE_UTILS_RWLOCK_INCLUDE} ${ENGINE_UTILS_FUNCEXP_INCLUDE} ${ENGINE_OAMAPPS_ALARMMANAGER_INCLUDE} ${ENGINE_UTILS_INCLUDE} ${ENGINE_OAM_OAMCPP_INCLUDE} ${ENGINE_DBCON_DDLPKGPROC_INCLUDE} ${ENGINE_DBCON_DDLPKG_INCLUDE} ${ENGINE_DBCON_EXECPLAN_INCLUDE} ${ENGINE_UTILS_STARTUP_INCLUDE} ${ENGINE_DBCON_JOBLIST_INCLUDE} ${ENGINE_WE_WRAPPER_INCLUDE} ${ENGINE_WE_SERVER_INCLUDE} ${ENGINE_DBCON_DMLPKG_INCLUDE} ${ENGINE_WE_CLIENT_INCLUDE} ${ENGINE_DBCON_DMLPKGPROC_INCLUDE} ${ENGINE_UTILS_CACHEUTILS_INCLUDE} ${ENGINE_UTILS_MYSQLCL_INCLUDE} ${ENGINE_UTILS_QUERYTELE_INCLUDE} ${ENGINE_UTILS_THRIFT_INCLUDE} ${ENGINE_UTILS_JOINER_INCLUDE} ${ENGINE_UTILS_THREADPOOL_INCLUDE} ${ENGINE_UTILS_BATCHLDR_INCLUDE} ${ENGINE_UTILS_DDLCLEANUP_INCLUDE} ${ENGINE_UTILS_QUERYSTATS_INCLUDE} ${ENGINE_WE_CONFIGCPP_INCLUDE} ${ENGINE_SERVER_SQL_INCLUDE} ${ENGINE_SERVER_INCLUDE_INCLUDE} ${ENGINE_SERVER_PCRE_INCLUDE} ${ENGINE_UTILS_UDFSDK_INCLUDE} ${ENGINE_UTILS_LIBMYSQL_CL_INCLUDE}) +SET (ENGINE_COMMON_INCLUDES ${ENGINE_DEFAULT_INCLUDES} ${Boost_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ${ENGINE_UTILS_MESSAGEQCPP_INCLUDE} ${ENGINE_WE_SHARED_INCLUDE} ${ENGINE_UTILS_IDBDATAFILE_INCLUDE} ${ENGINE_UTILS_LOGGINGCPP_INCLUDE} ${ENGINE_UTILS_CONFIGCPP_INCLUDE} ${ENGINE_UTILS_COMPRESS_INCLUDE} ${ENGINE_VERSIONING_BRM_INCLUDE} ${ENGINE_UTILS_ROWGROUP_INCLUDE} ${ENGINE_UTILS_COMMON_INCLUDE} ${ENGINE_UTILS_DATACONVERT_INCLUDE} ${ENGINE_UTILS_RWLOCK_INCLUDE} ${ENGINE_UTILS_FUNCEXP_INCLUDE} ${ENGINE_OAMAPPS_ALARMMANAGER_INCLUDE} ${ENGINE_UTILS_INCLUDE} ${ENGINE_OAM_OAMCPP_INCLUDE} ${ENGINE_DBCON_DDLPKGPROC_INCLUDE} ${ENGINE_DBCON_DDLPKG_INCLUDE} ${ENGINE_DBCON_EXECPLAN_INCLUDE} ${ENGINE_UTILS_STARTUP_INCLUDE} ${ENGINE_DBCON_JOBLIST_INCLUDE} ${ENGINE_WE_WRAPPER_INCLUDE} ${ENGINE_WE_SERVER_INCLUDE} ${ENGINE_DBCON_DMLPKG_INCLUDE} ${ENGINE_WE_CLIENT_INCLUDE} ${ENGINE_DBCON_DMLPKGPROC_INCLUDE} ${ENGINE_UTILS_CACHEUTILS_INCLUDE} ${ENGINE_UTILS_MYSQLCL_INCLUDE} ${ENGINE_UTILS_QUERYTELE_INCLUDE} ${ENGINE_UTILS_THRIFT_INCLUDE} ${ENGINE_UTILS_JOINER_INCLUDE} ${ENGINE_UTILS_THREADPOOL_INCLUDE} ${ENGINE_UTILS_BATCHLDR_INCLUDE} ${ENGINE_UTILS_DDLCLEANUP_INCLUDE} ${ENGINE_UTILS_QUERYSTATS_INCLUDE} ${ENGINE_WE_CONFIGCPP_INCLUDE} ${ENGINE_SERVER_SQL_INCLUDE} ${ENGINE_SERVER_INCLUDE_INCLUDE} ${ENGINE_SERVER_PCRE_INCLUDE} ${ENGINE_SERVER_WSREP_API_INCLUDE} ${ENGINE_SERVER_WSREP_INCLUDE} ${ENGINE_UTILS_UDFSDK_INCLUDE} ${ENGINE_UTILS_LIBMYSQL_CL_INCLUDE}) ADD_SUBDIRECTORY(utils) ADD_SUBDIRECTORY(oam/oamcpp) diff --git a/dbcon/mysql/ha_calpont_ddl.cpp b/dbcon/mysql/ha_calpont_ddl.cpp index 833a0ab38..3c411e529 100644 --- a/dbcon/mysql/ha_calpont_ddl.cpp +++ b/dbcon/mysql/ha_calpont_ddl.cpp @@ -2307,7 +2307,7 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* bool isCreate = true; // relate to bug 1793. Make sure this is not for a select statement because - if (db == "calpontsys" && thd->infinidb_vtable.vtable_state == THD::INFINIDB_INIT + if (db == "calpontsys" && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT && tbl != "systable" && tbl != "syscolumn" && tbl != "sysindex" && tbl != "sysconstraint" && tbl != "sysindexcol" @@ -2337,7 +2337,7 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* return 0; } - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE) //check if it is select + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ALTER_VTABLE) //check if it is select { return 0; } diff --git a/dbcon/mysql/ha_calpont_dml.cpp b/dbcon/mysql/ha_calpont_dml.cpp index 20462e2c8..5dcf087e5 100644 --- a/dbcon/mysql/ha_calpont_dml.cpp +++ b/dbcon/mysql/ha_calpont_dml.cpp @@ -2117,8 +2117,8 @@ int ha_calpont_impl_commit_ (handlerton* hton, THD* thd, bool all, cal_connectio { int rc = 0; - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE || - thd->infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE ) + if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE || + MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE ) return rc; if (thd->slave_thread && !ci.replicationEnabled) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index c8b6aa058..f7940bc17 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -1304,8 +1304,8 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) { if (gwi.thd->derived_tables_processing) { - gwi.thd->infinidb_vtable.isUnion = false; - gwi.thd->infinidb_vtable.isUpdateWithDerive = true; + MIGR::infinidb_vtable.isUnion = false; + MIGR::infinidb_vtable.isUpdateWithDerive = true; return -1; } } @@ -2628,8 +2628,8 @@ void setError(THD* thd, uint32_t errcode, string errmsg) } thd->raise_error_printf(errcode, errmsg.c_str()); - thd->infinidb_vtable.isNewQuery = true; - thd->infinidb_vtable.override_largeside_estimate = false; + MIGR::infinidb_vtable.isNewQuery = true; + MIGR::infinidb_vtable.override_largeside_estimate = false; // reset expressionID if (get_fe_conn_info_ptr() == NULL) @@ -5556,7 +5556,7 @@ void gp_walk(const Item* item, void* arg) gwip->hasSubSelect = true; gwip->subQuery = existsSub; gwip->ptWorkStack.push(existsSub->transform()); - current_thd->infinidb_vtable.isUnion = true; // only temp. bypass the 2nd phase. + current_MIGR::infinidb_vtable.isUnion = true; // only temp. bypass the 2nd phase. // recover original gwip->subQuery = orig; gwip->lastSub = existsSub; @@ -5913,7 +5913,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, ((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; + MIGR::infinidb_vtable.isUnion = false; return -1; } @@ -5961,7 +5961,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // @bug 2123. Override large table estimate if infinidb_ordered hint was used. // @bug 2404. Always override if the infinidb_ordered_only variable is turned on. - if (gwi.thd->infinidb_vtable.override_largeside_estimate || get_ordered_only(gwi.thd)) + if (MIGR::infinidb_vtable.override_largeside_estimate || get_ordered_only(gwi.thd)) csep->overrideLargeSideEstimate(true); // @bug 5741. Set a flag when in Local PM only query mode @@ -6047,7 +6047,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, gwi.tbList.push_back(tn); CalpontSystemCatalog::TableAliasName tan = make_aliastable("", alias, alias); gwi.tableMap[tan] = make_pair(0, table_ptr); - gwi.thd->infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init + MIGR::infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init } else if (table_ptr->view) { @@ -6118,7 +6118,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // is_unit_op() give a segv for derived_handler's SELECT_LEX if (!isUnion && select_lex.master_unit()->is_unit_op()) { - gwi.thd->infinidb_vtable.isUnion = true; + MIGR::infinidb_vtable.isUnion = true; CalpontSelectExecutionPlan::SelectList unionVec; SELECT_LEX* select_cursor = select_lex.master_unit()->first_select(); unionSel = true; @@ -6177,7 +6177,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, csep->distinctUnionNum(distUnionNum); if (unionVec.empty()) - gwi.thd->infinidb_vtable.impossibleWhereOnUnion = true; + MIGR::infinidb_vtable.impossibleWhereOnUnion = true; } gwi.clauseType = WHERE; @@ -6210,8 +6210,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // processing. if (gwi.thd->derived_tables_processing) { - gwi.thd->infinidb_vtable.isUnion = false; - gwi.thd->infinidb_vtable.isUpdateWithDerive = true; + MIGR::infinidb_vtable.isUnion = false; + MIGR::infinidb_vtable.isUpdateWithDerive = true; return -1; } @@ -7068,7 +7068,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, 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) + if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && !unionSel) { gwi.clauseType = GROUP_BY; Item* nonSupportItem = NULL; @@ -7345,14 +7345,14 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } } - if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) { SQL_I_List order_list = select_lex.order_list; ORDER* ordercol = reinterpret_cast(order_list.first); - string create_query(gwi.thd->infinidb_vtable.create_vtable_query.c_ptr()); - string select_query(gwi.thd->infinidb_vtable.select_vtable_query.c_ptr()); - string lower_create_query(gwi.thd->infinidb_vtable.create_vtable_query.c_ptr()); - string lower_select_query(gwi.thd->infinidb_vtable.select_vtable_query.c_ptr()); + string create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); + string select_query(MIGR::infinidb_vtable.select_vtable_query.c_ptr()); + string lower_create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); + string lower_select_query(MIGR::infinidb_vtable.select_vtable_query.c_ptr()); boost::algorithm::to_lower(lower_create_query); boost::algorithm::to_lower(lower_select_query); @@ -7923,9 +7923,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } - gwi.thd->infinidb_vtable.create_vtable_query.free(); - gwi.thd->infinidb_vtable.create_vtable_query.append(create_query.c_str(), create_query.length()); - gwi.thd->infinidb_vtable.vtable_state = THD::INFINIDB_REDO_PHASE1; // redo phase 1 + MIGR::infinidb_vtable.create_vtable_query.free(); + MIGR::infinidb_vtable.create_vtable_query.append(create_query.c_str(), create_query.length()); + MIGR::infinidb_vtable.vtable_state = THD::INFINIDB_REDO_PHASE1; // redo phase 1 // turn off select distinct from post process unless there're post process functions // on the select list. @@ -8090,7 +8090,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, if (ord_cols.length() > 0) // has order by { - gwi.thd->infinidb_vtable.has_order_by = true; + MIGR::infinidb_vtable.has_order_by = true; csep->hasOrderBy(true); // To activate LimitedOrderBy if(isPushdownHand) @@ -8196,7 +8196,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // 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)) && + MIGR::infinidb_vtable.vtable_state != THD::INFINIDB_CREATE_VTABLE)) && !csep->hasOrderBy()) { csep->limitStart(limitOffset); @@ -8222,8 +8222,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, csep->limitNum((uint64_t) - 2); } - gwi.thd->infinidb_vtable.select_vtable_query.free(); - gwi.thd->infinidb_vtable.select_vtable_query.append(select_query.c_str(), select_query.length()); + MIGR::infinidb_vtable.select_vtable_query.free(); + MIGR::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 && @@ -8319,7 +8319,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, csep->derivedTableList(gwi.derivedTbList); csep->selectSubList(selectSubList); csep->subSelectList(gwi.subselectList); - gwi.thd->infinidb_vtable.duplicate_field_name = false; + MIGR::infinidb_vtable.duplicate_field_name = false; clearStacks(gwi); return 0; } @@ -8603,7 +8603,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // @bug 2123. Override large table estimate if infinidb_ordered hint was used. // @bug 2404. Always override if the infinidb_ordered_only variable is turned on. - if (gwi.thd->infinidb_vtable.override_largeside_estimate || get_ordered_only(gwi.thd)) + if (MIGR::infinidb_vtable.override_largeside_estimate || get_ordered_only(gwi.thd)) csep->overrideLargeSideEstimate(true); // @bug 5741. Set a flag when in Local PM only query mode @@ -8689,7 +8689,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro gwi.tbList.push_back(tn); CalpontSystemCatalog::TableAliasName tan = make_aliastable("", alias, alias); gwi.tableMap[tan] = make_pair(0, table_ptr); -// gwi.thd->infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init +// MIGR::infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init } else if (table_ptr->view) { @@ -8786,8 +8786,8 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // processing. if (gwi.thd->derived_tables_processing) { - gwi.thd->infinidb_vtable.isUnion = false; - gwi.thd->infinidb_vtable.isUpdateWithDerive = true; + MIGR::infinidb_vtable.isUnion = false; + MIGR::infinidb_vtable.isUpdateWithDerive = true; return -1; } @@ -9606,7 +9606,7 @@ 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) + if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && !unionSel) { gwi.clauseType = GROUP_BY; Item* nonSupportItem = NULL; @@ -9885,13 +9885,13 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // ORDER BY processing starts here - if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) { 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()); - string lower_create_query(gwi.thd->infinidb_vtable.create_vtable_query.c_ptr()); - string lower_select_query(gwi.thd->infinidb_vtable.select_vtable_query.c_ptr()); + string create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); + string select_query(MIGR::infinidb_vtable.select_vtable_query.c_ptr()); + string lower_create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); + string lower_select_query(MIGR::infinidb_vtable.select_vtable_query.c_ptr()); boost::algorithm::to_lower(lower_create_query); boost::algorithm::to_lower(lower_select_query); @@ -10219,9 +10219,9 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro } - gwi.thd->infinidb_vtable.create_vtable_query.free(); - gwi.thd->infinidb_vtable.create_vtable_query.append(create_query.c_str(), create_query.length()); - gwi.thd->infinidb_vtable.vtable_state = THD::INFINIDB_REDO_PHASE1; // redo phase 1 + MIGR::infinidb_vtable.create_vtable_query.free(); + MIGR::infinidb_vtable.create_vtable_query.append(create_query.c_str(), create_query.length()); + MIGR::infinidb_vtable.vtable_state = THD::INFINIDB_REDO_PHASE1; // redo phase 1 // turn off select distinct from post process unless there're post process functions // on the select list. @@ -10391,7 +10391,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro if ( gwi.orderByCols.size() ) // has order by { - gwi.thd->infinidb_vtable.has_order_by = true; + MIGR::infinidb_vtable.has_order_by = true; csep->hasOrderBy(true); csep->specHandlerProcessed(true); } @@ -10418,8 +10418,9 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro csep->limitStart(((Item_int*)gi.groupByTables->select_lex->offset_limit)->val_int()); } - //gwi.thd->infinidb_vtable.select_vtable_query.free(); - //gwi.thd->infinidb_vtable.select_vtable_query.append(select_query.c_str(), select_query.length()); + // WIP MCOL-2178 + //MIGR::infinidb_vtable.select_vtable_query.free(); + //MIGR::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 && @@ -10516,7 +10517,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro csep->derivedTableList(gwi.derivedTbList); csep->selectSubList(selectSubList); csep->subSelectList(gwi.subselectList); - gwi.thd->infinidb_vtable.duplicate_field_name = false; + MIGR::infinidb_vtable.duplicate_field_name = false; clearStacks(gwi); return 0; } diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 3c53c518a..6790664a7 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -169,8 +169,6 @@ static const string interval_names[] = const unsigned NONSUPPORTED_ERR_THRESH = 2000; -//TODO: make this session-safe (put in connMap?) -//vector rmParms; ResourceManager* rm = ResourceManager::instance(); bool useHdfs = rm->useHdfs(); @@ -273,8 +271,8 @@ void storeNumericField(Field** f, int64_t value, CalpontSystemCatalog::ColType& // @bug4388 stick to InfiniDB's scale in case mysql gives wrong scale due // to create vtable limitation. - if (f2->dec < ct.scale) - f2->dec = ct.scale; + //if (f2->dec < ct.scale) + // f2->dec = ct.scale; char buf[256]; dataconvert::DataConvert::decimalToString(value, (unsigned)ct.scale, buf, 256, ct.colDataType); @@ -755,7 +753,8 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h //float float_val = *(float*)(&value); //f2->store(float_val); if (f2->decimals() < (uint32_t)row.getScale(s)) - f2->dec = (uint32_t)row.getScale(s); + // WIP MCOL-2178 + //f2->dec = (uint32_t)row.getScale(s); f2->store(dl); @@ -784,11 +783,15 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h //double double_val = *(double*)(&value); //f2->store(double_val); + + + // WIP MCOL-2178 + /* if ((f2->decimals() == DECIMAL_NOT_SPECIFIED && row.getScale(s) > 0) || f2->decimals() < row.getScale(s)) { f2->dec = row.getScale(s); - } + }*/ f2->store(dl); @@ -1235,7 +1238,7 @@ uint32_t doUpdateDelete(THD* thd) //@Bug 4387. Check BRM status before start statement. boost::scoped_ptr dbrmp(new DBRM()); int rc = dbrmp->isReadWrite(); - thd->infinidb_vtable.isInfiniDBDML = true; + MIGR::infinidb_vtable.isInfiniDBDML = true; if (rc != 0 ) { @@ -1335,8 +1338,8 @@ uint32_t doUpdateDelete(THD* thd) { ColumnAssignment* columnAssignmentPtr; Item_field* item; -// TABLE_LIST* table_ptr = thd->lex->select_lex.get_table_list(); - List_iterator_fast field_it(thd->lex->select_lex.item_list); +// TABLE_LIST* table_ptr = thd->lex->thd->lex->first_select_lex()->get_table_list(); + List_iterator_fast field_it(thd->lex->thd->lex->first_select_lex()->item_list); List_iterator_fast value_it(thd->lex->value_list); // dmlStmt += "update "; updateCP->queryType(CalpontSelectExecutionPlan::UPDATE); @@ -1587,7 +1590,7 @@ uint32_t doUpdateDelete(THD* thd) } colAssignmentListPtr->push_back ( columnAssignmentPtr ); -// if (cnt < thd->lex->select_lex.item_list.elements) +// if (cnt < thd->lex->thd->lex->first_select_lex()->item_list.elements) // dmlStmt += ", "; } @@ -1636,7 +1639,7 @@ uint32_t doUpdateDelete(THD* thd) } else { - first_table = (TABLE_LIST*) thd->lex->select_lex.table_list.first; + first_table = (TABLE_LIST*) thd->lex->thd->lex->first_select_lex()->table_list.first; aTableName.schema = first_table->table->s->db.str; aTableName.table = first_table->table->s->table_name.str; } @@ -1687,9 +1690,9 @@ uint32_t doUpdateDelete(THD* thd) } else if ((thd->lex)->sql_command == SQLCOM_DELETE_MULTI) //@Bug 6121 error out on multi tables delete. { - if ( (thd->lex->select_lex.join) != 0) + if ( (thd->lex->thd->lex->first_select_lex()->join) != 0) { - multi_delete* deleteTable = (multi_delete*)((thd->lex->select_lex.join)->result); + multi_delete* deleteTable = (multi_delete*)((thd->lex->thd->lex->first_select_lex()->join)->result); first_table = (TABLE_LIST*) deleteTable->get_tables(); if (deleteTable->get_num_of_tables() == 1) @@ -1712,7 +1715,7 @@ uint32_t doUpdateDelete(THD* thd) } else { - first_table = (TABLE_LIST*) thd->lex->select_lex.table_list.first; + first_table = (TABLE_LIST*) thd->lex->thd->lex->first_select_lex()->table_list.first; schemaName = first_table->table->s->db.str; tableName = first_table->table->s->table_name.str; aliasName = first_table->alias.str; @@ -1723,7 +1726,7 @@ uint32_t doUpdateDelete(THD* thd) } else { - first_table = (TABLE_LIST*) thd->lex->select_lex.table_list.first; + first_table = (TABLE_LIST*) thd->lex->thd->lex->first_select_lex()->table_list.first; schemaName = first_table->table->s->db.str; tableName = first_table->table->s->table_name.str; aliasName = first_table->alias.str; @@ -1756,16 +1759,16 @@ uint32_t doUpdateDelete(THD* thd) if (( (thd->lex)->sql_command == SQLCOM_UPDATE ) || ( (thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ) { - items = (thd->lex->select_lex.item_list); - thd->lex->select_lex.item_list = thd->lex->value_list; + items = (thd->lex->thd->lex->first_select_lex()->item_list); + thd->lex->thd->lex->first_select_lex()->item_list = thd->lex->value_list; } - select_lex = lex->select_lex; + select_lex = *lex->first_select_lex(); //@Bug 2808 Error out on order by or limit clause //@bug5096. support dml limit. - if (/*( select_lex.explicit_limit ) || */( select_lex.order_list.elements != 0 ) ) + if (/*( thd->lex->first_select_lex()->explicit_limit ) || */( thd->lex->first_select_lex()->order_list.elements != 0 ) ) { string emsg("DML Statement with order by clause is not currently supported."); thd->raise_error_printf(ER_INTERNAL_ERROR, emsg.c_str()); @@ -1774,12 +1777,12 @@ uint32_t doUpdateDelete(THD* thd) return 0; } - //thd->infinidb_vtable.isInfiniDBDML = true; - THD::infinidb_state origState = thd->infinidb_vtable.vtable_state; + //MIGR::infinidb_vtable.isInfiniDBDML = true; + MIGR::infinidb_state origState = MIGR::infinidb_vtable.vtable_state; //if (( (thd->lex)->sql_command == SQLCOM_UPDATE ) || ( (thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ) { gp_walk_info gwi; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; gwi.thd = thd; //updateCP->subType (CalpontSelectExecutionPlan::SINGLEROW_SUBS); //set scalar updateCP->subType (CalpontSelectExecutionPlan::SELECT_SUBS); @@ -1816,13 +1819,13 @@ uint32_t doUpdateDelete(THD* thd) if (getSelectPlan(gwi, select_lex, updateCP) != 0) //@Bug 3030 Modify the error message for unsupported functions { - if (thd->infinidb_vtable.isUpdateWithDerive) + if (MIGR::infinidb_vtable.isUpdateWithDerive) { // @bug 4457. MySQL inconsistence! for some queries, some structures are only available // in the derived_tables_processing phase. So by pass the phase for DML only when the // execution plan can not be successfully generated. recover lex before returning; - thd->lex->select_lex.item_list = items; - thd->infinidb_vtable.vtable_state = origState; + thd->lex->thd->lex->first_select_lex()->item_list = items; + MIGR::infinidb_vtable.vtable_state = origState; return 0; } @@ -1972,7 +1975,7 @@ uint32_t doUpdateDelete(THD* thd) //cout<< "Plan is " << endl << *updateCP << endl; if (( (thd->lex)->sql_command == SQLCOM_UPDATE ) || ( (thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ) - thd->lex->select_lex.item_list = items; + thd->lex->thd->lex->first_select_lex()->item_list = items; } //cout<< "Plan is " << endl << *updateCP << endl; @@ -1989,7 +1992,7 @@ uint32_t doUpdateDelete(THD* thd) updateCP->rmParms(ci->rmParms); updateCP->serialize(*plan); // recover original vtable state - thd->infinidb_vtable.vtable_state = origState; + MIGR::infinidb_vtable.vtable_state = origState; //cout << "plan has bytes " << plan->length() << endl; pDMLPackage->write(bytestream); @@ -2368,20 +2371,20 @@ int ha_calpont_impl_rnd_init(TABLE* table) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "The system is not yet ready to accept queries"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } else if (bSystemQueryReady < 0) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "DBRM is not responding. Cannot accept queries"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } #endif // prevent "create table as select" from running on slave - thd->infinidb_vtable.hasInfiniDBTable = true; + MIGR::infinidb_vtable.hasInfiniDBTable = true; cal_connection_info* ci = reinterpret_cast(get_fe_conn_info_ptr()); @@ -2398,30 +2401,30 @@ int ha_calpont_impl_rnd_init(TABLE* table) // @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 && + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE && string(table->s->table_name.str).find("$vtable") != 0) return 0; // return error is error status is already set - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) return ER_INTERNAL_ERROR; // by pass the extra union trips. return 0 - if (thd->infinidb_vtable.isUnion && thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + if (MIGR::infinidb_vtable.isUnion && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) return 0; // @bug 2232. Basic SP support. Error out non support sp cases. // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - if (thd->infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) + if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) { setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } // mysql reads table twice for order by - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1 || - thd->infinidb_vtable.vtable_state == THD::INFINIDB_ORDER_BY) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1 || + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY) return 0; if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) @@ -2442,8 +2445,8 @@ int ha_calpont_impl_rnd_init(TABLE* table) // MySQL sometimes calls rnd_init multiple times, plan should only be // generated and sent once. - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && - !thd->infinidb_vtable.isNewQuery) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE && + !MIGR::infinidb_vtable.isNewQuery) return 0; if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) @@ -2459,11 +2462,11 @@ int ha_calpont_impl_rnd_init(TABLE* table) // 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 || - (thd->slave_thread && thd->infinidb_vtable.vtable_state == THD::INFINIDB_INIT)) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE || + (thd->slave_thread && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT)) { ci->traceFlags |= CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_DISABLE_VTABLE; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_DISABLE_VTABLE; } else { @@ -2474,7 +2477,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) bool localQuery = get_local_query(thd); // table mode - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { ti = ci->tableMap[table]; @@ -2544,8 +2547,8 @@ int ha_calpont_impl_rnd_init(TABLE* table) // 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) + //if (!ci->cal_conn_hndl || MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) + if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) { ci->stats.reset(); // reset query stats ci->stats.setStartTime(); @@ -2601,7 +2604,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) hndl = ci->cal_conn_hndl; - if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE) + if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) { //CalpontSelectExecutionPlan csep; if (!csep) @@ -2629,7 +2632,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) csep->traceFlags(ci->traceFlags); - if (thd->infinidb_vtable.isInsertSelect) + if (MIGR::infinidb_vtable.isInsertSelect) csep->queryType(CalpontSelectExecutionPlan::INSERT_SELECT); //get plan @@ -2642,12 +2645,12 @@ int ha_calpont_impl_rnd_init(TABLE* table) return 0; // @bug 2547. don't need to send the plan if it's impossible where for all unions. - if (thd->infinidb_vtable.impossibleWhereOnUnion) + if (MIGR::infinidb_vtable.impossibleWhereOnUnion) return 0; string query; - query.assign(thd->infinidb_vtable.original_query.ptr(), - thd->infinidb_vtable.original_query.length()); + query.assign(MIGR::infinidb_vtable.original_query.ptr(), + MIGR::infinidb_vtable.original_query.length()); csep->data(query); try @@ -2686,7 +2689,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) } }// end of execution plan generation - if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE) + if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) { ByteStream msg; ByteStream emsgBs; @@ -2761,7 +2764,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) ci->rmParms.clear(); - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { ci->tableMap[table] = ti; } @@ -2781,7 +2784,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) idbassert(hndl != 0); hndl->csc = csc; - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) ti.conn_hndl = hndl; else ci->cal_conn_hndl = hndl; @@ -2805,15 +2808,15 @@ int ha_calpont_impl_rnd_init(TABLE* table) // set query state to be in_process. Sometimes mysql calls rnd_init multiple // times, this makes sure plan only being generated and sent once. It will be // reset when query finishes in sm::end_query - thd->infinidb_vtable.isNewQuery = false; + MIGR::infinidb_vtable.isNewQuery = false; // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; ti.msTablePtr = table; - if ((thd->infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE) || - (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) || - (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_QUERY)) + if ((MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE) || + (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) || + (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_QUERY)) { if (ti.tpl_ctx == 0) { @@ -2870,7 +2873,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) } // populate coltypes here for table mode because tableband gives treeoid for dictionary column - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(make_table(table->s->db.str, table->s->table_name.str), true); @@ -2934,11 +2937,11 @@ int ha_calpont_impl_rnd_next(uchar* buf, TABLE* table) thd->lex->sql_command == SQLCOM_LOAD)) return 0; - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) return ER_INTERNAL_ERROR; // @bug 3005 - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE && + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE && string(table->s->table_name.str).find("$vtable") != 0) return HA_ERR_END_OF_FILE; @@ -2947,15 +2950,15 @@ int ha_calpont_impl_rnd_next(uchar* buf, TABLE* table) return HA_ERR_END_OF_FILE; // @bug 2547 - if (thd->infinidb_vtable.impossibleWhereOnUnion) + if (MIGR::infinidb_vtable.impossibleWhereOnUnion) return HA_ERR_END_OF_FILE; // @bug 2232. Basic SP support // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - if (thd->infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) + if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) { setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } @@ -3027,8 +3030,8 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) cal_connection_info* ci = NULL; bool replicationEnabled = false; - if (thd->infinidb_vtable.cal_conn_info) - ci = reinterpret_cast(thd->infinidb_vtable.cal_conn_info); + if (get_fe_conn_info_ptr() != NULL) + ci = reinterpret_cast(get_fe_conn_info_ptr()); if (ci && ci->replicationEnabled) { @@ -3046,23 +3049,23 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) thd->lex->sql_command == SQLCOM_LOAD)) return 0; - thd->infinidb_vtable.isNewQuery = true; + MIGR::infinidb_vtable.isNewQuery = true; // Workaround because CS doesn't reset isUnion in a normal way. if (is_pushdown_hand) { - thd->infinidb_vtable.isUnion = false; + MIGR::infinidb_vtable.isUnion = false; } if (get_fe_conn_info_ptr() != NULL) ci = reinterpret_cast(get_fe_conn_info_ptr()); - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ORDER_BY ) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY ) { - thd->infinidb_vtable.vtable_state = THD::INFINIDB_SELECT_VTABLE; // flip back to normal state + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; // flip back to normal state return rc; } -// if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1) +// if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1) // return rc; if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) @@ -3103,7 +3106,7 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) cal_table_info ti = ci->tableMap[table]; sm::cpsm_conhdl_t* hndl; - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) hndl = ti.conn_hndl; else hndl = ci->cal_conn_hndl; @@ -3129,7 +3132,7 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) sm::tpl_close(ti.tpl_ctx, &hndl, ci->stats); // set conn hndl back. could be changed in tpl_close - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) ti.conn_hndl = hndl; else ci->cal_conn_hndl = hndl; @@ -3163,9 +3166,9 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) ti.tpl_ctx = 0; - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE && - thd->infinidb_vtable.has_order_by) - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ORDER_BY; + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE && + MIGR::infinidb_vtable.has_order_by) + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ORDER_BY; ci->tableMap[table] = ti; @@ -3190,7 +3193,7 @@ int ha_calpont_impl_create(const char* name, TABLE* table_arg, HA_CREATE_INFO* c cal_connection_info* ci = reinterpret_cast(get_fe_conn_info_ptr()); // @bug1940 Do nothing for select query. Support of set default engine to IDB. - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE || + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE || string(name).find("@0024vtable") != string::npos) return 0; @@ -3250,7 +3253,7 @@ int ha_calpont_impl_delete_table(const char* name) } else { - TABLE_LIST* first_table = (TABLE_LIST*) thd->lex->select_lex.table_list.first; + TABLE_LIST* first_table = (TABLE_LIST*) thd->lex->thd->lex->first_select_lex()->table_list.first; dbName = const_cast(first_table->db.str); } @@ -3391,14 +3394,14 @@ void ha_calpont_impl_start_bulk_insert(ha_rows rows, TABLE* table) if (ci->alterTableState > 0) return; - if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_ALTER_VTABLE) - thd->infinidb_vtable.isInfiniDBDML = true; + if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_ALTER_VTABLE) + MIGR::infinidb_vtable.isInfiniDBDML = true; if (thd->slave_thread && !ci->replicationEnabled) return; //@bug 5660. Error out DDL/DML on slave node, or on local query node - if (ci->isSlaveNode && thd->infinidb_vtable.vtable_state != THD::INFINIDB_ALTER_VTABLE) + if (ci->isSlaveNode && MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_ALTER_VTABLE) { string emsg = logging::IDBErrorInfo::instance()->errorMsg(ERR_DML_DDL_SLAVE); setError(current_thd, ER_CHECK_NOT_IMPLEMENTED, emsg); @@ -4166,10 +4169,10 @@ int ha_calpont_impl_end_bulk_insert(bool abort, TABLE* table) int ha_calpont_impl_commit (handlerton* hton, THD* thd, bool all) { - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE || - thd->infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE || - thd->infinidb_vtable.vtable_state == THD::INFINIDB_DROP_VTABLE || - thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE || + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ALTER_VTABLE || + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DROP_VTABLE || + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1) return 0; if (get_fe_conn_info_ptr() == NULL) @@ -4297,7 +4300,7 @@ int ha_calpont_impl_rename_table(const char* from, const char* to) IDEBUG( cout << "ha_calpont_impl_rename_table: was in state ALTER_SECOND_RENAME, now in NOT_ALTER" << endl ); return 0; } - else if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE ) + else if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ALTER_VTABLE ) return 0; int rc = ha_calpont_impl_rename_table_(from, to, *ci); @@ -4314,10 +4317,10 @@ COND* ha_calpont_impl_cond_push(COND* cond, TABLE* table) { THD* thd = current_thd; - if (thd->slave_thread && thd->infinidb_vtable.vtable_state == THD::INFINIDB_INIT) - thd->infinidb_vtable.vtable_state = THD::INFINIDB_DISABLE_VTABLE; + if (thd->slave_thread && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT) + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_DISABLE_VTABLE; - if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE) return cond; if (((thd->lex)->sql_command == SQLCOM_UPDATE) || @@ -4404,11 +4407,11 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) string alias; alias.assign(table->alias.ptr(), table->alias.length()); IDEBUG( cout << "external_lock for " << alias << endl ); - idbassert((thd->infinidb_vtable.vtable_state >= THD::INFINIDB_INIT_CONNECT && - thd->infinidb_vtable.vtable_state <= THD::INFINIDB_REDO_QUERY) || - thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR); + idbassert((MIGR::infinidb_vtable.vtable_state >= MIGR::INFINIDB_INIT_CONNECT && + MIGR::infinidb_vtable.vtable_state <= MIGR::INFINIDB_REDO_QUERY) || + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR); - if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_INIT ) + if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT ) return 0; if (get_fe_conn_info_ptr() == NULL) @@ -4432,7 +4435,7 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) #endif { // table mode - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { if (mapiter->second.conn_hndl) { @@ -4454,7 +4457,7 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) // only push this warning for once if (ci->tableMap.size() == 1 && - thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE && thd->infinidb_vtable.autoswitch) + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE && MIGR::infinidb_vtable.autoswitch) { push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, infinidb_autoswitch_warning.c_str()); } @@ -4462,7 +4465,7 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) } else // vtable mode { - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE) { if (!ci->cal_conn_hndl) return 0; @@ -4474,7 +4477,7 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) ci->extendedStats = ci->cal_conn_hndl->extendedStats; ci->miniStats = ci->cal_conn_hndl->miniStats; ci->queryState = 0; - thd->infinidb_vtable.override_largeside_estimate = false; + MIGR::infinidb_vtable.override_largeside_estimate = false; // MCOL-3247 Use THD::ha_data as a per-plugin per-session // storage for cal_conn_hndl to use it later in close_connection thd_set_ha_data(thd, calpont_hton, get_fe_conn_info_ptr()); @@ -4523,36 +4526,36 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE { // Still not ready setError(thd, ER_INTERNAL_ERROR, "The system is not yet ready to accept queries"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } else if (bSystemQueryReady < 0) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "DBRM is not responding. Cannot accept queries"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } #endif // prevent "create table as select" from running on slave - thd->infinidb_vtable.hasInfiniDBTable = true; + MIGR::infinidb_vtable.hasInfiniDBTable = true; // return error if error status has been already set - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) return ER_INTERNAL_ERROR; // MCOL-1052 // by pass the extra union trips. return 0 - //if (thd->infinidb_vtable.isUnion && thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + //if (MIGR::infinidb_vtable.isUnion && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) // return 0; // @bug 2232. Basic SP support. Error out non support sp cases. // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - if (thd->infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) + if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) { setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } @@ -4570,8 +4573,8 @@ 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. - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE && - !thd->infinidb_vtable.isNewQuery) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE && + !MIGR::infinidb_vtable.isNewQuery) return 0; if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) @@ -4713,7 +4716,7 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE return 0; // @bug 2547. don't need to send the plan if it's impossible where for all unions. - if (thd->infinidb_vtable.impossibleWhereOnUnion) + if (MIGR::infinidb_vtable.impossibleWhereOnUnion) return 0; string query; @@ -4834,7 +4837,7 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE ci->rmParms.clear(); - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { ci->tableMap[table] = ti; } @@ -4855,7 +4858,7 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE hndl->csc = csc; // The next section is useless - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) ti.conn_hndl = hndl; else { @@ -4882,18 +4885,18 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE // set query state to be in_process. Sometimes mysql calls rnd_init multiple // times, this makes sure plan only being generated and sent once. It will be // reset when query finishes in sm::end_query - thd->infinidb_vtable.isNewQuery = false; + MIGR::infinidb_vtable.isNewQuery = false; // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; ti.msTablePtr = table; // MCOL-1052 - thd->infinidb_vtable.vtable_state = THD::INFINIDB_SELECT_VTABLE; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; - if ((thd->infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE) || - (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) || - (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_QUERY)) + if ((MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE) || + (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) || + (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_QUERY)) { // MCOL-1601 Using stacks of ExeMgr conn hndls, table and scan contexts. ti.tpl_ctx = new sm::cpsm_tplh_t(); @@ -4950,7 +4953,7 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE } // populate coltypes here for table mode because tableband gives treeoid for dictionary column - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(make_table(table->s->db.str, table->s->table_name.str), true); @@ -5017,7 +5020,7 @@ int ha_calpont_impl_group_by_next(ha_calpont_group_by_handler* group_hand, TABLE { THD* thd = current_thd; - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) return ER_INTERNAL_ERROR; if (((thd->lex)->sql_command == SQLCOM_UPDATE) || ((thd->lex)->sql_command == SQLCOM_DELETE) || @@ -5025,15 +5028,15 @@ int ha_calpont_impl_group_by_next(ha_calpont_group_by_handler* group_hand, TABLE return HA_ERR_END_OF_FILE; // @bug 2547 - if (thd->infinidb_vtable.impossibleWhereOnUnion) + if (MIGR::infinidb_vtable.impossibleWhereOnUnion) return HA_ERR_END_OF_FILE; // @bug 2232. Basic SP support // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - /*if (thd->infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) + /*if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) { setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } */ @@ -5118,18 +5121,6 @@ int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, TABLE* THD* thd = current_thd; cal_connection_info* ci = NULL; - thd->infinidb_vtable.isNewQuery = true; - thd->infinidb_vtable.isUnion = false; - - if (get_fe_conn_info_ptr() != NULL) - ci = reinterpret_cast(get_fe_conn_info_ptr()); - - if (!ci) - { - thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info()); - ci = reinterpret_cast(thd->infinidb_vtable.cal_conn_info); - } - if (thd->slave_thread && !ci->replicationEnabled && ( thd->lex->sql_command == SQLCOM_INSERT || thd->lex->sql_command == SQLCOM_INSERT_SELECT || @@ -5141,7 +5132,13 @@ int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, TABLE* thd->lex->sql_command == SQLCOM_LOAD)) return 0; - if (((thd->lex)->sql_command == SQLCOM_INSERT) || + MIGR::infinidb_vtable.isNewQuery = true; + MIGR::infinidb_vtable.isUnion = false; + + if (get_fe_conn_info_ptr() != NULL) + ci = reinterpret_cast(get_fe_conn_info_ptr()); + + if (((thd->lex)->sql_command == SQLCOM_INSERT) || ((thd->lex)->sql_command == SQLCOM_INSERT_SELECT) ) { force_close_fep_conn(thd, ci, true); // with checking prev command rc @@ -5332,20 +5329,20 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "The system is not yet ready to accept queries"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } else if (bSystemQueryReady < 0) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "DBRM is not responding. Cannot accept queries"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } #endif // prevent "create table as select" from running on slave - thd->infinidb_vtable.hasInfiniDBTable = true; + MIGR::infinidb_vtable.hasInfiniDBTable = true; /* If this node is the slave, ignore DML to IDB tables */ if (thd->slave_thread && ( @@ -5360,21 +5357,21 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) return 0; // return error is error status is already set - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) return ER_INTERNAL_ERROR; // @bug 2232. Basic SP support. Error out non support sp cases. // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - if (thd->infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) + if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) { setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - thd->infinidb_vtable.vtable_state = THD::INFINIDB_ERROR; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } // mysql reads table twice for order by - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1 || - thd->infinidb_vtable.vtable_state == THD::INFINIDB_ORDER_BY) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1 || + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY) return 0; if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) @@ -5388,17 +5385,17 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) boost::shared_ptr csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID); csc->identity(CalpontSystemCatalog::FE); - if (!thd->infinidb_vtable.cal_conn_info) - thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info()); + if (!get_fe_conn_info_ptr()) + set_fe_conn_info_ptr(reinterpret_cast(new cal_connection_info(), thd)); - cal_connection_info* ci = reinterpret_cast(thd->infinidb_vtable.cal_conn_info); + cal_connection_info* ci = reinterpret_cast(get_fe_conn_info_ptr()); idbassert(ci != 0); // MySQL sometimes calls rnd_init multiple times, plan should only be // generated and sent once. - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && - !thd->infinidb_vtable.isNewQuery) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE && + !MIGR::infinidb_vtable.isNewQuery) return 0; if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) @@ -5436,11 +5433,11 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) // 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 || - (thd->slave_thread && thd->infinidb_vtable.vtable_state == THD::INFINIDB_INIT)) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE || + (thd->slave_thread && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT)) { ci->traceFlags |= CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_DISABLE_VTABLE; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_DISABLE_VTABLE; } else { @@ -5448,11 +5445,11 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; } - bool localQuery = (thd->variables.infinidb_local_query > 0 ? true : false); + bool localQuery = (get_local_query(thd) > 0 ? true : false); { - //if (!ci->cal_conn_hndl || thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) - if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + //if (!ci->cal_conn_hndl || MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) + if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) { ci->stats.reset(); // reset query stats ci->stats.setStartTime(); @@ -5501,7 +5498,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) hndl = ci->cal_conn_hndl; - if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE) + if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) { if (!csep) csep.reset(new CalpontSelectExecutionPlan()); @@ -5528,7 +5525,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) csep->traceFlags(ci->traceFlags); - if (thd->infinidb_vtable.isInsertSelect) + if (MIGR::infinidb_vtable.isInsertSelect) csep->queryType(CalpontSelectExecutionPlan::INSERT_SELECT); // cast the handler and get a plan. @@ -5552,13 +5549,13 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) return 0; // @bug 2547. don't need to send the plan if it's impossible where for all unions. - if (thd->infinidb_vtable.impossibleWhereOnUnion) + if (MIGR::infinidb_vtable.impossibleWhereOnUnion) return 0; string query; query.assign(idb_mysql_query_str(thd)); - //query.assign(thd->infinidb_vtable.original_query.ptr(), - // thd->infinidb_vtable.original_query.length()); + //query.assign(MIGR::infinidb_vtable.original_query.ptr(), + // MIGR::infinidb_vtable.original_query.length()); csep->data(query); try @@ -5595,7 +5592,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) } }// end of execution plan generation - if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE) + if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) { ByteStream msg; ByteStream emsgBs; @@ -5608,7 +5605,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) msg << qb; hndl->exeMgr->write(msg); msg.restart(); - csep->rmParms(rmParms); + csep->rmParms(ci->rmParms); //send plan csep->serialize(msg); @@ -5668,9 +5665,9 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) return ER_INTERNAL_ERROR; } - rmParms.clear(); + ci->rmParms.clear(); - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { ci->tableMap[table] = ti; } @@ -5690,7 +5687,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) idbassert(hndl != 0); hndl->csc = csc; - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) ti.conn_hndl = hndl; else ci->cal_conn_hndl = hndl; @@ -5714,7 +5711,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) // set query state to be in_process. Sometimes mysql calls rnd_init multiple // times, this makes sure plan only being generated and sent once. It will be // reset when query finishes in sm::end_query - thd->infinidb_vtable.isNewQuery = false; + MIGR::infinidb_vtable.isNewQuery = false; // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; @@ -5784,7 +5781,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) } // populate coltypes here for table mode because tableband gives treeoid for dictionary column - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(make_table(table->s->db.str, table->s->table_name.str), true); diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp index bc4673a11..6b7f0ff89 100644 --- a/dbcon/mysql/ha_mcs_pushdown.cpp +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -129,9 +129,10 @@ create_calpont_group_by_handler(THD* thd, Query* query) SELECT_LEX *select_lex = query->from->select_lex; // Create a handler if query is valid. See comments for details. - if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE - && ( thd->variables.infinidb_vtable_mode == 0 - || thd->variables.infinidb_vtable_mode == 2 ) + if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE + // WIP MCOL-2178 + //&& ( MIGR::infinidb_vtable_mode == 0 + // || MIGR::infinidb_vtable_mode == 2 ) && ( query->group_by || select_lex->with_sum_func ) ) { bool unsupported_feature = false; @@ -213,8 +214,9 @@ create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived) SELECT_LEX_UNIT *unit= derived->derived; - if ( thd->infinidb_vtable.vtable_state != THD::INFINIDB_DISABLE_VTABLE - && thd->variables.infinidb_vtable_mode != 0 ) + if ( MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE ) +// WIP MCOL-2178 +// && MIGR::infinidb_vtable_mode != 0 ) { return 0; } @@ -305,14 +307,14 @@ int ha_columnstore_derived_handler::init_scan() derived->derived->print(&derived_query, QT_ORDINARY); // Save vtable_state to restore the after we inited. - THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; mcs_handler_info mhi = mcs_handler_info(static_cast(this), DERIVED); // this::table is the place for the result set int rc = ha_cs_impl_pushdown_init(&mhi, table); - thd->infinidb_vtable.vtable_state = oldState; + MIGR::infinidb_vtable.vtable_state = oldState; DBUG_RETURN(rc); } @@ -334,13 +336,13 @@ int ha_columnstore_derived_handler::next_row() DBUG_ENTER("ha_columnstore_derived_handler::next_row"); // Save vtable_state to restore the after we inited. - THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; int rc = ha_calpont_impl_rnd_next(table->record[0], table); - thd->infinidb_vtable.vtable_state = oldState; + MIGR::infinidb_vtable.vtable_state = oldState; DBUG_RETURN(rc); } @@ -361,12 +363,12 @@ int ha_columnstore_derived_handler::end_scan() { DBUG_ENTER("ha_columnstore_derived_handler::end_scan"); - THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_SELECT_VTABLE; + MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; int rc = ha_calpont_impl_rnd_end(table, true); - thd->infinidb_vtable.vtable_state = oldState; + MIGR::infinidb_vtable.vtable_state = oldState; DBUG_RETURN(rc); } @@ -413,11 +415,11 @@ int ha_calpont_group_by_handler::init_scan() DBUG_ENTER("ha_calpont_group_by_handler::init_scan"); // Save vtable_state to restore the after we inited. - THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; // MCOL-1052 Should be removed after cleaning the code up. - thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; int rc = ha_calpont_impl_group_by_init(this, table); - thd->infinidb_vtable.vtable_state = oldState; + MIGR::infinidb_vtable.vtable_state = oldState; DBUG_RETURN(rc); } @@ -471,8 +473,9 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) handlerton *ht= 0; // Return if vtable enabled. - if ( thd->infinidb_vtable.vtable_state != THD::INFINIDB_DISABLE_VTABLE - && thd->variables.infinidb_vtable_mode != 0 ) + if ( MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE ) +// WIP MCOL-2178 +// && MIGR::infinidb_vtable_mode != 0 ) { return 0; } @@ -591,14 +594,14 @@ int ha_columnstore_select_handler::init_scan() select->print(thd, &select_query, QT_ORDINARY); // Save vtable_state to restore the after we inited. - THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; mcs_handler_info mhi = mcs_handler_info(static_cast(this), SELECT); // this::table is the place for the result set int rc = ha_cs_impl_pushdown_init(&mhi, table); - thd->infinidb_vtable.vtable_state = oldState; + MIGR::infinidb_vtable.vtable_state = oldState; DBUG_RETURN(rc); } @@ -620,13 +623,13 @@ int ha_columnstore_select_handler::next_row() DBUG_ENTER("ha_columnstore_select_handler::next_row"); // Save vtable_state to restore the after we inited. - THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; + MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_CREATE_VTABLE; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; int rc = ha_calpont_impl_rnd_next(table->record[0], table); - thd->infinidb_vtable.vtable_state = oldState; + MIGR::infinidb_vtable.vtable_state = oldState; DBUG_RETURN(rc); } @@ -647,12 +650,12 @@ int ha_columnstore_select_handler::end_scan() { DBUG_ENTER("ha_columnstore_select_handler::end_scan"); - THD::infinidb_state oldState = thd->infinidb_vtable.vtable_state; - thd->infinidb_vtable.vtable_state = THD::INFINIDB_SELECT_VTABLE; + MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; int rc = ha_calpont_impl_rnd_end(table, true); - thd->infinidb_vtable.vtable_state = oldState; + MIGR::infinidb_vtable.vtable_state = oldState; DBUG_RETURN(rc); } diff --git a/dbcon/mysql/ha_mcs_sysvars.cpp b/dbcon/mysql/ha_mcs_sysvars.cpp index ff6943fa4..dc022b8f2 100644 --- a/dbcon/mysql/ha_mcs_sysvars.cpp +++ b/dbcon/mysql/ha_mcs_sysvars.cpp @@ -296,225 +296,135 @@ mcs_compression_type_t get_compression_type(THD* thd) { bool get_use_decimal_scale(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? false : thd->variables.infinidb_use_decimal_scale; - else - return ( thd == NULL ) ? false : THDVAR(thd, use_decimal_scale); + return ( thd == NULL ) ? false : THDVAR(thd, use_decimal_scale); } void set_use_decimal_scale(THD* thd, bool value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_use_decimal_scale = value; - else - THDVAR(thd, use_decimal_scale) = value; + THDVAR(thd, use_decimal_scale) = value; } ulong get_decimal_scale(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_decimal_scale; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, decimal_scale); + return ( thd == NULL ) ? 0 : THDVAR(thd, decimal_scale); } void set_decimal_scale(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_decimal_scale = value; - else - THDVAR(thd, decimal_scale) = value; + THDVAR(thd, decimal_scale) = value; } bool get_ordered_only(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? false : thd->variables.infinidb_ordered_only; - else - return ( thd == NULL ) ? false : THDVAR(thd, ordered_only); + return ( thd == NULL ) ? false : THDVAR(thd, ordered_only); } void set_ordered_only(THD* thd, bool value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_ordered_only = value; - else - THDVAR(thd, ordered_only) = value; + THDVAR(thd, ordered_only) = value; } ulong get_string_scan_threshold(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_string_scan_threshold; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, string_scan_threshold); + return ( thd == NULL ) ? 0 : THDVAR(thd, string_scan_threshold); } void set_string_scan_threshold(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_string_scan_threshold = value; - else - THDVAR(thd, string_scan_threshold) = value; + THDVAR(thd, string_scan_threshold) = value; } ulong get_stringtable_threshold(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_stringtable_threshold; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, stringtable_threshold); + return ( thd == NULL ) ? 0 : THDVAR(thd, stringtable_threshold); } void set_stringtable_threshold(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_stringtable_threshold = value; - else - THDVAR(thd, stringtable_threshold) = value; + THDVAR(thd, stringtable_threshold) = value; } ulong get_diskjoin_smallsidelimit(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_diskjoin_smallsidelimit; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, diskjoin_smallsidelimit); + return ( thd == NULL ) ? 0 : THDVAR(thd, diskjoin_smallsidelimit); } void set_diskjoin_smallsidelimit(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_diskjoin_smallsidelimit = value; - else - THDVAR(thd, diskjoin_smallsidelimit) = value; + THDVAR(thd, diskjoin_smallsidelimit) = value; } ulong get_diskjoin_largesidelimit(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_diskjoin_largesidelimit; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, diskjoin_largesidelimit); + return ( thd == NULL ) ? 0 : THDVAR(thd, diskjoin_largesidelimit); } void set_diskjoin_largesidelimit(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_diskjoin_largesidelimit = value; - else - THDVAR(thd, diskjoin_largesidelimit) = value; + THDVAR(thd, diskjoin_largesidelimit) = value; } ulong get_diskjoin_bucketsize(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_diskjoin_bucketsize; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, diskjoin_bucketsize); + return ( thd == NULL ) ? 0 : THDVAR(thd, diskjoin_bucketsize); } void set_diskjoin_bucketsize(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_diskjoin_bucketsize = value; - else - THDVAR(thd, diskjoin_bucketsize) = value; + THDVAR(thd, diskjoin_bucketsize) = value; } ulong get_um_mem_limit(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_um_mem_limit; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, um_mem_limit); + return ( thd == NULL ) ? 0 : THDVAR(thd, um_mem_limit); } void set_um_mem_limit(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_um_mem_limit = value; - else - THDVAR(thd, um_mem_limit) = value; + THDVAR(thd, um_mem_limit) = value; } bool get_varbin_always_hex(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? false : thd->variables.infinidb_varbin_always_hex; - else - return ( thd == NULL ) ? false : THDVAR(thd, varbin_always_hex); + return ( thd == NULL ) ? false : THDVAR(thd, varbin_always_hex); } void set_varbin_always_hex(THD* thd, bool value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_varbin_always_hex = value; - else - THDVAR(thd, varbin_always_hex) = value; + THDVAR(thd, varbin_always_hex) = value; } bool get_double_for_decimal_math(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? false : thd->variables.infinidb_double_for_decimal_math; - else - return ( thd == NULL ) ? false : THDVAR(thd, double_for_decimal_math); + return ( thd == NULL ) ? false : THDVAR(thd, double_for_decimal_math); } void set_double_for_decimal_math(THD* thd, bool value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_double_for_decimal_math = value; - else - THDVAR(thd, double_for_decimal_math) = value; + THDVAR(thd, double_for_decimal_math) = value; } ulong get_local_query(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_local_query; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, local_query); + return ( thd == NULL ) ? 0 : THDVAR(thd, local_query); } void set_local_query(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_local_query = value; - else - THDVAR(thd, local_query) = value; + THDVAR(thd, local_query) = value; } bool get_use_import_for_batchinsert(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? false : thd->variables.infinidb_use_import_for_batchinsert; - else - return ( thd == NULL ) ? false : THDVAR(thd, use_import_for_batchinsert); + return ( thd == NULL ) ? false : THDVAR(thd, use_import_for_batchinsert); } void set_use_import_for_batchinsert(THD* thd, bool value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_use_import_for_batchinsert = value; - else - THDVAR(thd, use_import_for_batchinsert) = value; + THDVAR(thd, use_import_for_batchinsert) = value; } ulong get_import_for_batchinsert_delimiter(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_import_for_batchinsert_delimiter; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, import_for_batchinsert_delimiter); + return ( thd == NULL ) ? 0 : THDVAR(thd, import_for_batchinsert_delimiter); } void set_import_for_batchinsert_delimiter(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_import_for_batchinsert_delimiter = value; - else - THDVAR(thd, import_for_batchinsert_delimiter) = value; + THDVAR(thd, import_for_batchinsert_delimiter) = value; } ulong get_import_for_batchinsert_enclosed_by(THD* thd) { - if(get_use_legacy_sysvars(thd)) - return ( thd == NULL ) ? 0 : thd->variables.infinidb_import_for_batchinsert_enclosed_by; - else - return ( thd == NULL ) ? 0 : THDVAR(thd, import_for_batchinsert_enclosed_by); + return ( thd == NULL ) ? 0 : THDVAR(thd, import_for_batchinsert_enclosed_by); } void set_import_for_batchinsert_enclosed_by(THD* thd, ulong value) { - if(get_use_legacy_sysvars(thd)) - thd->variables.infinidb_import_for_batchinsert_enclosed_by = value; - else - THDVAR(thd, import_for_batchinsert_enclosed_by) = value; + THDVAR(thd, import_for_batchinsert_enclosed_by) = value; } diff --git a/dbcon/mysql/ha_view.cpp b/dbcon/mysql/ha_view.cpp index 3bc49b2a8..761608d0e 100644 --- a/dbcon/mysql/ha_view.cpp +++ b/dbcon/mysql/ha_view.cpp @@ -102,7 +102,7 @@ void View::transform() CalpontSystemCatalog::TableAliasName tn = make_aliasview("", "", alias, viewName); gwi.tbList.push_back(tn); gwi.tableMap[tn] = make_pair(0, table_ptr); - gwi.thd->infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init + MIGR::infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init } else if (table_ptr->view) { diff --git a/dbcon/mysql/idb_mysql.h b/dbcon/mysql/idb_mysql.h index cb842d740..47dd61aff 100644 --- a/dbcon/mysql/idb_mysql.h +++ b/dbcon/mysql/idb_mysql.h @@ -111,6 +111,69 @@ inline char* idb_mysql_query_str(THD* thd) } } +class MIGR +{ + public: + enum infinidb_state + { + INFINIDB_INIT_CONNECT = 0, // intend to use to drop leftover vtable when logon. not being used now. + INFINIDB_INIT, + INFINIDB_CREATE_VTABLE, + INFINIDB_ALTER_VTABLE, + INFINIDB_SELECT_VTABLE, + INFINIDB_DROP_VTABLE, + INFINIDB_DISABLE_VTABLE, + INFINIDB_REDO_PHASE1, // post process requires to re-create vtable + INFINIDB_ORDER_BY, // for InfiniDB handler to ignore the 2nd scan for order by + INFINIDB_REDO_QUERY, // redo query with the normal mysql path + INFINIDB_ERROR_REDO_PHASE1, + INFINIDB_ERROR = 32, + }; + struct INFINIDB_VTABLE + { + String original_query; + String create_vtable_query; + String alter_vtable_query; + String select_vtable_query; + String drop_vtable_query; + String insert_vtable_query; + infinidb_state vtable_state; // flag for InfiniDB MySQL virtual table structure + bool autoswitch; + bool has_order_by; + bool duplicate_field_name; // @bug 1928. duplicate field name in create_phase will be ingored. + bool call_sp; + bool override_largeside_estimate; + void* cal_conn_info; + bool isUnion; + bool impossibleWhereOnUnion; + bool isInsertSelect; + bool isUpdateWithDerive; + bool isInfiniDBDML; // default false + bool hasInfiniDBTable; // default false + bool isNewQuery; + INFINIDB_VTABLE() : cal_conn_info(NULL) {init();} + void init() + { + vtable_state = INFINIDB_INIT_CONNECT; + autoswitch = false; + has_order_by = false; + duplicate_field_name = false; + call_sp = false; + override_largeside_estimate = false; + isUnion = false; + impossibleWhereOnUnion = false; + isUpdateWithDerive = false; + isInfiniDBDML = false; + hasInfiniDBTable = false; + isNewQuery = true; + } + }; + + static INFINIDB_VTABLE infinidb_vtable; // InfiniDB custom structure + +}; + + #endif // vim:ts=4 sw=4: From cd72326c4dab1f58f630c9a1ee460151d92269ef Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Mon, 25 Feb 2019 18:42:56 +0300 Subject: [PATCH 03/11] MCOL-2178 Introduced a dummy replacement for a infinidb_table. Used Item attribute getters introduced by 10.4 Make changes to support Item::CONST_ITEM introduced by 10.4 as a replacement for INT_,REAL_,STRING_ ITEM. Replaced QT_INFINIDB_DERIVED and similar flags with correponded flags for Item->print(). Replaced or commented out infinidb_ variable names with columnstore_ where applicable. --- dbcon/mysql/ha_calpont.cpp | 3 + dbcon/mysql/ha_calpont_dml.cpp | 4 +- dbcon/mysql/ha_calpont_execplan.cpp | 832 ++++++++++++++++------------ dbcon/mysql/ha_calpont_impl.cpp | 96 ++-- dbcon/mysql/ha_mcs_pushdown.cpp | 14 +- dbcon/mysql/ha_view.cpp | 4 +- dbcon/mysql/idb_mysql.h | 3 +- dbcon/mysql/my.cnf | 18 +- 8 files changed, 542 insertions(+), 432 deletions(-) diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index f1b375480..dfbb452ef 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -23,6 +23,8 @@ #include "ha_calpont_impl.h" #include "ha_mcs_pushdown.h" +MIGR::INFINIDB_VTABLE MIGR::infinidb_vtable; + static handler* calpont_create_handler(handlerton* hton, TABLE_SHARE* table, MEM_ROOT* mem_root); @@ -116,6 +118,7 @@ static int columnstore_init_func(void* p) struct tm tm; time_t t; + time(&t); localtime_r(&t, &tm); fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d ", diff --git a/dbcon/mysql/ha_calpont_dml.cpp b/dbcon/mysql/ha_calpont_dml.cpp index 5dcf087e5..9372491e2 100644 --- a/dbcon/mysql/ha_calpont_dml.cpp +++ b/dbcon/mysql/ha_calpont_dml.cpp @@ -2117,8 +2117,8 @@ int ha_calpont_impl_commit_ (handlerton* hton, THD* thd, bool all, cal_connectio { int rc = 0; - if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE || - MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE ) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ALTER_VTABLE || + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE ) return rc; if (thd->slave_thread && !ci.replicationEnabled) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index f7940bc17..d97c1b303 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -514,7 +514,7 @@ void debug_walk(const Item* item, void* arg) case Item_func::BETWEEN: inp = (Item_func_opt_neg*)ifp; - if (inp->negated) cerr << "not "; + if (inp->get_negated()) cerr << "not "; cerr << "between" << " (" << ifp->functype() << ")" << endl; break; @@ -1584,7 +1584,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) { // Starting with MariaDB 10.2, LIKE uses a negated flag instead of FUNC_NOT // Further processing is done below as before for LIKE - if (((Item_func_like*)ifp)->negated) + if (((Item_func_like*)ifp)->get_negated()) { sop->reverseOp(); } @@ -1722,7 +1722,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) String str; // @bug5811. This filter string is for cross engine to use. // Use real table name. - ifp->print(&str, QT_INFINIDB_DERIVED); + ifp->print(&str, QT_ORDINARY); IDEBUG(cerr << str.ptr() << endl); if (str.ptr()) @@ -2743,7 +2743,7 @@ uint32_t setAggOp(AggregateColumn* ac, Item_sum* isp) { Item_func_group_concat* gc = (Item_func_group_concat*)isp; ac->aggOp(AggregateColumn::GROUP_CONCAT); - ac->distinct(gc->isDistinct()); + ac->distinct(gc->get_distinct()); return rc; } @@ -3021,7 +3021,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp { //if ( ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI )) { - if ( !item->fixed) + if ( !item->is_fixed()) { item->fix_fields(gwi.thd, (Item**)&item); } @@ -3035,59 +3035,71 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp Item_field* ifp = (Item_field*)item; return buildSimpleColumn(ifp, gwi); } - - case Item::INT_ITEM: - case Item::VARBIN_ITEM: + case Item::CONST_ITEM: { - String val, *str = item->val_str(&val); - string valStr; - valStr.assign(str->ptr(), str->length()); - - if (item->unsigned_flag) + switch (item->cmp_type()) { - //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); + case INT_RESULT: + { + String val, *str = item->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + + if (item->unsigned_flag) + { + rc = new ConstantColumn((uint64_t)item->val_uint(), ConstantColumn::NUM); + } + else + { + rc = new ConstantColumn(valStr, (int64_t)item->val_int(), ConstantColumn::NUM); + } + + break; + } + case STRING_RESULT: + { + String val, *str = item->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + rc = new ConstantColumn(valStr); + break; + } + case REAL_RESULT: + { + String val, *str = item->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + rc = new ConstantColumn(valStr, item->val_real()); + break; + } + case DECIMAL_RESULT: + { + rc = buildDecimalColumn(item, gwi); + break; + } + case TIME_RESULT: + { + String val, *str = item->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + rc = new ConstantColumn(valStr); + break; + } + default: + { + gwi.fatalParseError = true; + gwi.parseErrorText = "Unknown item type"; + break; + } } - else + + if (rc && (item->cmp_type() != DECIMAL_RESULT)) { - rc = new ConstantColumn(valStr, (int64_t)item->val_int(), ConstantColumn::NUM); + (dynamic_cast(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); } - (dynamic_cast(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); - //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); - (dynamic_cast(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); - 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()); - (dynamic_cast(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); - break; - } - - case Item::DECIMAL_ITEM: - { - rc = buildDecimalColumn(item, gwi); - break; - } - case Item::FUNC_ITEM: { Item_func* ifp = (Item_func*)item; @@ -3221,16 +3233,6 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp break; } - case Item::DATE_ITEM: - { - String val, *str = item->val_str(&val); - string valStr; - valStr.assign(str->ptr(), str->length()); - rc = new ConstantColumn(valStr); - (dynamic_cast(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); - break; - } - case Item::WINDOW_FUNC_ITEM: { return buildWindowFunctionColumn(item, gwi, nonSupport); @@ -3587,11 +3589,16 @@ ReturnedColumn* buildFunctionColumn( for (uint32_t i = 1; i < ifp->argument_count(); i++) { - if (!(ifp->arguments()[i]->type() == Item::INT_ITEM || - ifp->arguments()[i]->type() == Item::STRING_ITEM || - ifp->arguments()[i]->type() == Item::REAL_ITEM || - ifp->arguments()[i]->type() == Item::DECIMAL_ITEM || - ifp->arguments()[i]->type() == Item::NULL_ITEM)) + if (!(ifp->arguments()[i]->type() == Item::NULL_ITEM || + (ifp->arguments()[i]->type() == Item::CONST_ITEM && + (ifp->arguments()[i]->cmp_type() == INT_RESULT || + ifp->arguments()[i]->cmp_type() == STRING_RESULT || + ifp->arguments()[i]->cmp_type() == REAL_RESULT || + ifp->arguments()[i]->cmp_type() == DECIMAL_RESULT + ) + ) + ) + ) { if (ifp->arguments()[i]->type() == Item::FUNC_ITEM) { @@ -4464,7 +4471,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) RowColumn* rowCol = new RowColumn(); vector selCols; - uint32_t select_ctn = gc->count_field(); + uint32_t select_ctn = gc->get_count_field(); ReturnedColumn* rc = NULL; for (uint32_t i = 0; i < select_ctn; i++) @@ -4485,12 +4492,13 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) ORDER** order_item, **end; for (order_item = gc->get_order(), - end = order_item + gc->order_field(); order_item < end; + end = order_item + gc->get_order_field(); order_item < end; order_item++) { Item* ord_col = *(*order_item)->item; - if (ord_col->type() == Item::INT_ITEM) + if (ord_col->type() == Item::CONST_ITEM + && ord_col->cmp_type() == INT_RESULT) { Item_int* id = (Item_int*)ord_col; @@ -4530,10 +4538,10 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) parm.reset(rowCol); ac->aggParms().push_back(parm); - if (gc->str_separator()) + if (gc->get_separator()) { string separator; - separator.assign(gc->str_separator()->ptr(), gc->str_separator()->length()); + separator.assign(gc->get_separator()->ptr(), gc->get_separator()->length()); (dynamic_cast(ac))->separator(separator); } } @@ -4564,18 +4572,29 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) break; } - case Item::INT_ITEM: - case Item::STRING_ITEM: - case Item::REAL_ITEM: - case Item::DECIMAL_ITEM: + case Item::CONST_ITEM: { - // treat as count(*) - if (ac->aggOp() == AggregateColumn::COUNT) - ac->aggOp(AggregateColumn::COUNT_ASTERISK); + switch(sfitemp->cmp_type()) + { + case INT_RESULT: + case STRING_RESULT: + case REAL_RESULT: + case DECIMAL_RESULT: + { + // treat as count(*) + if (ac->aggOp() == AggregateColumn::COUNT) + ac->aggOp(AggregateColumn::COUNT_ASTERISK); - parm.reset(buildReturnedColumn(sfitemp, gwi, gwi.fatalParseError)); - ac->constCol(parm); - bIsConst = true; + parm.reset(buildReturnedColumn(sfitemp, gwi, gwi.fatalParseError)); + ac->constCol(parm); + bIsConst = true; + break; + } + default: + { + gwi.fatalParseError = true; + } + } break; } @@ -4659,7 +4678,6 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) default: { gwi.fatalParseError = true; - //gwi.parseErrorText = "Non-supported Item in Aggregate function"; } } @@ -4922,7 +4940,7 @@ void addIntervalArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) if (funcName == "date_add_interval") interval_type = ((Item_date_add_interval*)ifp)->int_type; else if (funcName == "timestampdiff") - interval_type = ((Item_func_timestamp_diff*)ifp)->int_type; + interval_type = ((Item_func_timestamp_diff*)ifp)->get_int_type(); else if (funcName == "extract") interval_type = ((Item_extract*)ifp)->int_type; @@ -4959,7 +4977,7 @@ void castCharArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) Item_char_typecast* idai = (Item_char_typecast*)ifp; SPTP sptp; - sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->castLength()))); + sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->get_cast_length()))); (dynamic_cast(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); functionParms.push_back(sptp); } @@ -5058,67 +5076,96 @@ void gp_walk(const Item* item, void* arg) break; } - case Item::INT_ITEM: + case Item::CONST_ITEM: { - Item_int* iip = (Item_int*)item; - gwip->rcWorkStack.push(buildReturnedColumn(iip, *gwip, gwip->fatalParseError)); - break; - } - - case Item::STRING_ITEM: - { - Item_string* isp = (Item_string*)item; - - if (isp) + switch(item->cmp_type()) { - if (isp->result_type() == STRING_RESULT) + case INT_RESULT: { - String val, *str = isp->val_str(&val); - string cval; - - if (str->ptr()) - { - cval.assign(str->ptr(), str->length()); - } - - gwip->rcWorkStack.push(new ConstantColumn(cval)); - (dynamic_cast(gwip->rcWorkStack.top()))->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + Item_int* iip = (Item_int*)item; + gwip->rcWorkStack.push(buildReturnedColumn(iip, *gwip, gwip->fatalParseError)); break; } - gwip->rcWorkStack.push(buildReturnedColumn(isp, *gwip, gwip->fatalParseError)); + case STRING_RESULT: + { + Item_string* isp = (Item_string*)item; + + if (isp) + { + if (isp->result_type() == STRING_RESULT) + { + String val, *str = isp->val_str(&val); + string cval; + + if (str->ptr()) + { + cval.assign(str->ptr(), str->length()); + } + + gwip->rcWorkStack.push(new ConstantColumn(cval)); + (dynamic_cast(gwip->rcWorkStack.top()))->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + break; + } + + gwip->rcWorkStack.push(buildReturnedColumn(isp, *gwip, gwip->fatalParseError)); + } + break; + } + + case REAL_RESULT: + { + Item_float* ifp = (Item_float*)item; + gwip->rcWorkStack.push(buildReturnedColumn(ifp, *gwip, gwip->fatalParseError)); + break; + } + + case DECIMAL_RESULT: + { + Item_decimal* idp = (Item_decimal*)item; + gwip->rcWorkStack.push(buildReturnedColumn(idp, *gwip, gwip->fatalParseError)); + break; + } + + case TIME_RESULT: + { + Item_temporal_literal* itp = (Item_temporal_literal*)item; + gwip->rcWorkStack.push(buildReturnedColumn(itp, *gwip, gwip->fatalParseError)); + break; + } + /*case Item::VARBIN_ITEM: + { + Item_hex_string* hdp = (Item_hex_string*)item; + gwip->rcWorkStack.push(buildReturnedColumn(hdp, *gwip, gwip->fatalParseError)); + break; + }*/ + default: + { + if (gwip->condPush) + { + // push noop for unhandled item + SimpleColumn* rc = new SimpleColumn("noop"); + rc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + gwip->rcWorkStack.push(rc); + break; + } + + ostringstream oss; + oss << "Unhandled Item type: " << item->type(); + gwip->parseErrorText = oss.str(); + gwip->fatalParseError = true; + break; + } } - break; } - - case Item::REAL_ITEM: - { - Item_float* ifp = (Item_float*)item; - gwip->rcWorkStack.push(buildReturnedColumn(ifp, *gwip, gwip->fatalParseError)); - break; - } - - case Item::DECIMAL_ITEM: - { - Item_decimal* idp = (Item_decimal*)item; - gwip->rcWorkStack.push(buildReturnedColumn(idp, *gwip, gwip->fatalParseError)); - break; - } - - case Item::VARBIN_ITEM: - { - Item_hex_string* hdp = (Item_hex_string*)item; - gwip->rcWorkStack.push(buildReturnedColumn(hdp, *gwip, gwip->fatalParseError)); - break; - } - case Item::NULL_ITEM: { if (gwip->condPush) { // push noop for unhandled item SimpleColumn* rc = new SimpleColumn("noop"); + rc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); gwip->rcWorkStack.push(rc); break; } @@ -5356,10 +5403,13 @@ void gp_walk(const Item* item, void* arg) } if ((it->type() == Item::FIELD_ITEM - || it->type() == Item::INT_ITEM - || it->type() == Item::DECIMAL_ITEM - || it->type() == Item::STRING_ITEM - || it->type() == Item::REAL_ITEM + || ( it->type() == Item::CONST_ITEM + && ( it->cmp_type() == INT_RESULT + || it->cmp_type() == DECIMAL_RESULT + || it->cmp_type() == STRING_RESULT + || it->cmp_type() == REAL_RESULT + ) + ) || it->type() == Item::NULL_ITEM || (it->type() == Item::FUNC_ITEM && !isPredicateFunction(it, gwip))) && !gwip->rcWorkStack.empty() @@ -5556,14 +5606,14 @@ void gp_walk(const Item* item, void* arg) gwip->hasSubSelect = true; gwip->subQuery = existsSub; gwip->ptWorkStack.push(existsSub->transform()); - current_MIGR::infinidb_vtable.isUnion = true; // only temp. bypass the 2nd phase. + MIGR::infinidb_vtable.isUnion = true; // only temp. bypass the 2nd phase. // recover original gwip->subQuery = orig; gwip->lastSub = existsSub; } else if (sub->substype() == Item_subselect::IN_SUBS) { - if (!((Item_in_subselect*)sub)->getOptimizer() && gwip->thd->derived_tables_processing) + if (!((Item_in_subselect*)sub)->optimizer && gwip->thd->derived_tables_processing) { ostringstream oss; oss << "Invalid In_optimizer: " << item->type(); @@ -5602,12 +5652,6 @@ void gp_walk(const Item* item, void* arg) break; } - case Item::DATE_ITEM: - { - Item_temporal_literal* itp = (Item_temporal_literal*)item; - gwip->rcWorkStack.push(buildReturnedColumn(itp, *gwip, gwip->fatalParseError)); - break; - } case Item::WINDOW_FUNC_ITEM: { @@ -5661,6 +5705,7 @@ void gp_walk(const Item* item, void* arg) printf("********** received TRIGGER_FIELD_ITEM *********\n"); break; + /* WIP MCOL-2178 case Item::XPATH_NODESET: printf("********** received XPATH_NODESET *********\n"); break; @@ -5672,13 +5717,14 @@ void gp_walk(const Item* item, void* arg) case Item::VIEW_FIXER_ITEM: printf("********** received VIEW_FIXER_ITEM *********\n"); break; - + */ default: { if (gwip->condPush) { // push noop for unhandled item SimpleColumn* rc = new SimpleColumn("noop"); + rc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); gwip->rcWorkStack.push(rc); break; } @@ -5771,11 +5817,16 @@ void parse_item (Item* item, vector& field_vec, // special handling for count(*). This should not be treated as constant. if (isp->argument_count() == 1 && - (sfitempp[0]->type() == Item::INT_ITEM || - sfitempp[0]->type() == Item::STRING_ITEM || - sfitempp[0]->type() == Item::REAL_ITEM || - sfitempp[0]->type() == Item::DECIMAL_ITEM)) + ( sfitempp[0]->type() == Item::CONST_ITEM && + (sfitempp[0]->cmp_type() == INT_RESULT || + sfitempp[0]->cmp_type() == STRING_RESULT || + sfitempp[0]->cmp_type() == REAL_RESULT || + sfitempp[0]->cmp_type() == DECIMAL_RESULT) + ) + ) + { field_vec.push_back((Item_field*)item); //dummy + } for (uint32_t i = 0; i < isp->argument_count(); i++) parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); @@ -6025,7 +6076,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, if (table_ptr->derived) { String str; - (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_INFINIDB_DERIVED); + (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); SELECT_LEX* select_cursor = table_ptr->derived->first_select(); FromSubQuery fromSub(gwi, select_cursor); @@ -6051,7 +6102,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } else if (table_ptr->view) { - View* view = new View(table_ptr->view->select_lex, &gwi); + View* view = new View(*table_ptr->view->first_select_lex(), &gwi); CalpontSystemCatalog::TableAliasName tn = make_aliastable(table_ptr->db.str, table_ptr->table_name.str, table_ptr->alias.str); view->viewName(tn); gwi.viewList.push_back(view); @@ -6187,7 +6238,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // MariaDB bug 624 - without the fix_fields call, delete with join may error with "No query step". //#if MYSQL_VERSION_ID < 50172 //@bug 3039. fix fields for constants - if (!icp->fixed) + if (!icp->is_fixed()) { icp->fix_fields(gwi.thd, (Item**)&icp); } @@ -6423,7 +6474,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, string fullname; String str; - ifp->print(&str, QT_INFINIDB_NO_QUOTE); + ifp->print(&str, QT_ORDINARY); fullname = str.c_ptr(); //sel_cols_in_create += fullname; @@ -6485,7 +6536,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, gwi.returnedCols.push_back(spac); gwi.selectCols.push_back('`' + escapeBackTick(spac->alias().c_str()) + '`'); String str(256); - item->print(&str, QT_INFINIDB_NO_QUOTE); + item->print(&str, QT_ORDINARY); if (sel_cols_in_create.length() != 0) sel_cols_in_create += ", "; @@ -6559,7 +6610,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, { redo = true; String str; - ifp->print(&str, QT_INFINIDB_NO_QUOTE); + ifp->print(&str, QT_ORDINARY); gwi.selectCols.push_back(string(str.c_ptr()) + " " + "`" + escapeBackTick(item->name.str) + "`"); } @@ -6574,7 +6625,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, else { String str(256); - ifp->print(&str, QT_INFINIDB_NO_QUOTE); + ifp->print(&str, QT_ORDINARY); if (sel_cols_in_create.length() != 0) sel_cols_in_create += ", "; @@ -6680,7 +6731,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, redo = true; // @bug 1706 String funcStr; - ifp->print(&funcStr, QT_INFINIDB); + ifp->print(&funcStr, QT_ORDINARY); string valStr; valStr.assign(funcStr.ptr(), funcStr.length()); gwi.selectCols.push_back(valStr + " `" + escapeBackTick(ifp->name.str) + "`"); @@ -6691,96 +6742,111 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } break; - } + } // End of FUNC_ITEM - case Item::INT_ITEM: + case Item::CONST_ITEM: { - 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 )) - { } - else + switch(item->cmp_type()) { - // do not push the dummy column (mysql added) to returnedCol - if (item->name.length && string(item->name.str) == "Not_used") - continue; + case INT_RESULT: + { + 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 )) + { } + else + { + // do not push the dummy column (mysql added) to returnedCol + if (item->name.length && string(item->name.str) == "Not_used") + continue; - // @bug3509. Constant column is sent to ExeMgr now. - SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + // @bug3509. Constant column is sent to ExeMgr now. + SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - if (item->name.length) - srcp->alias(item->name.str); + if (item->name.length) + srcp->alias(item->name.str); - gwi.returnedCols.push_back(srcp); + gwi.returnedCols.push_back(srcp); - Item_int* isp = reinterpret_cast(item); - ostringstream oss; - oss << isp->value << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; + Item_int* isp = reinterpret_cast(item); + ostringstream oss; + oss << isp->value << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; + if (sel_cols_in_create.length() != 0) + sel_cols_in_create += ", "; - sel_cols_in_create += oss.str(); - gwi.selectCols.push_back(oss.str()); + sel_cols_in_create += oss.str(); + gwi.selectCols.push_back(oss.str()); + } + + break; + } + + case STRING_RESULT: + { + 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 )) + { } + else + { + SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + gwi.returnedCols.push_back(srcp); + + if (item->name.length) + srcp->alias(item->name.str); + + Item_string* isp = reinterpret_cast(item); + String val, *str = isp->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + string name = "'" + valStr + "'" + " " + "`" + escapeBackTick(srcp->alias().c_str()) + "`"; + + if (sel_cols_in_create.length() != 0) + sel_cols_in_create += ", "; + + sel_cols_in_create += name; + gwi.selectCols.push_back(name); + } + + break; + } + + case DECIMAL_RESULT: + { + 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 )) + { } + else + { + SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + gwi.returnedCols.push_back(srcp); + + if (item->name.length) + srcp->alias(item->name.str); + + Item_decimal* isp = reinterpret_cast(item); + String val, *str = isp->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + ostringstream oss; + oss << valStr.c_str() << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; + + if (sel_cols_in_create.length() != 0) + sel_cols_in_create += ", "; + + sel_cols_in_create += oss.str(); + gwi.selectCols.push_back(oss.str()); + } + + break; + } + // WIP MCOL-2178 This switch doesn't handl + // ROW_, TIME_, REAL_RESULT and if one couldn't + // project the former two REAL is possible. + // Need to test before commit. + default: + { + //noop + } } - break; - } - - case Item::STRING_ITEM: - { - 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 )) - { } - else - { - SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - gwi.returnedCols.push_back(srcp); - - if (item->name.length) - srcp->alias(item->name.str); - - Item_string* isp = reinterpret_cast(item); - String val, *str = isp->val_str(&val); - string valStr; - valStr.assign(str->ptr(), str->length()); - string name = "'" + valStr + "'" + " " + "`" + escapeBackTick(srcp->alias().c_str()) + "`"; - - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += name; - gwi.selectCols.push_back(name); - } - - break; - } - - case Item::DECIMAL_ITEM: - { - 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 )) - { } - else - { - SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - gwi.returnedCols.push_back(srcp); - - if (item->name.length) - srcp->alias(item->name.str); - - Item_decimal* isp = reinterpret_cast(item); - String val, *str = isp->val_str(&val); - string valStr; - valStr.assign(str->ptr(), str->length()); - ostringstream oss; - oss << valStr.c_str() << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; - - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += oss.str(); - gwi.selectCols.push_back(oss.str()); - } - - break; - } + } // CONST_ITEM ends here case Item::NULL_ITEM: { @@ -6858,7 +6924,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, gwi.returnedCols.push_back(SRCP(rc)); String str; - sub->get_select_lex()->print(gwi.thd, &str, QT_INFINIDB_NO_QUOTE); + sub->get_select_lex()->print(gwi.thd, &str, QT_ORDINARY); sel_cols_in_create += "(" + string(str.c_ptr()) + ")"; if (sub->name.length) @@ -7027,7 +7093,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } String str; - funcFieldVec[i]->print(&str, QT_INFINIDB_NO_QUOTE); + funcFieldVec[i]->print(&str, QT_ORDINARY); sc->alias(string(str.c_ptr())); //sc->tableAlias(funcFieldVec[i]->table_name); sc->tableAlias(sc->tableAlias()); @@ -7068,7 +7134,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SRCP minSc; // min width projected column. for count(*) use // Group by list. not valid for union main query - if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && !unionSel) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE && !unionSel) { gwi.clauseType = GROUP_BY; Item* nonSupportItem = NULL; @@ -7240,10 +7306,13 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // @bug5638. The group by column is constant but not counter, alias has to match a column // on the select list else if (!groupcol->counter_used && - (groupItem->type() == Item::INT_ITEM || - groupItem->type() == Item::STRING_ITEM || - groupItem->type() == Item::REAL_ITEM || - groupItem->type() == Item::DECIMAL_ITEM)) + (groupItem->type() == Item::CONST_ITEM && + (groupItem->cmp_type() == INT_RESULT || + groupItem->cmp_type() == STRING_RESULT || + groupItem->cmp_type() == REAL_RESULT || + groupItem->cmp_type() == DECIMAL_RESULT) + ) + ) { ReturnedColumn* rc = 0; @@ -7345,7 +7414,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } } - if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) { SQL_I_List order_list = select_lex.order_list; ORDER* ordercol = reinterpret_cast(order_list.first); @@ -7364,8 +7433,11 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, if ((*(ordercol->item))->type() == Item::WINDOW_FUNC_ITEM) gwi.hasWindowFunc = true; // MCOL-2166 Looking for this sorting item in GROUP_BY items list. + // Shouldn't look into this if query doesn't have GROUP BY or + // aggregations if(isPushdownHand - && !sortItemIsInGrouping(*ordercol->item, select_lex.group_list.first)) + && select_lex.agg_func_used() && select_lex.group_list.first + && !sortItemIsInGrouping(*ordercol->item, select_lex.group_list.first)) { std::ostringstream ostream; std::ostringstream& osr = ostream; @@ -7404,15 +7476,28 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, Item* ord_item = *(ordercol->item); // ignore not_used column on order by. - if (ord_item->type() == Item::INT_ITEM && ord_item->full_name() && string(ord_item->full_name()) == "Not_used") - continue; - else if (ord_item->type() == Item::INT_ITEM) - rc = gwi.returnedCols[((Item_int*)ord_item)->val_int() - 1]->clone(); + if ((ord_item->type() == Item::CONST_ITEM + && ord_item->cmp_type() == INT_RESULT) + && ord_item->full_name() + && !strcmp(ord_item->full_name(), "Not_used")) + { + continue; + } + else if (ord_item->type() == Item::CONST_ITEM + && ord_item->cmp_type() == INT_RESULT) + { + // WIP MCOL-2178. We should seek smallest + // column here and not just previous. + rc = gwi.returnedCols[((Item_int*)ord_item)->val_int() - 1]->clone(); + } else if (ord_item->type() == Item::SUBSELECT_ITEM) + { gwi.fatalParseError = true; + } else + { rc = buildReturnedColumn(ord_item, gwi, gwi.fatalParseError); - + } // @bug5501 try item_ptr if item can not be fixed. For some // weird dml statement state, item can not be fixed but the // infomation is available in item_ptr. @@ -7603,7 +7688,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // @bug 3076. do not add the argument of aggregate function to the SELECT list, // instead, add the whole column String str; - ord_item->print(&str, QT_INFINIDB_NO_QUOTE); + ord_item->print(&str, QT_ORDINARY); if (sel_cols_in_create.length() != 0) sel_cols_in_create += ", "; @@ -7684,7 +7769,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } String str; - ord_item->print(&str, QT_INFINIDB); + ord_item->print(&str, QT_ORDINARY); ord_cols += str.c_ptr(); } @@ -7708,7 +7793,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } String str; - fieldVec[i]->print(&str, QT_INFINIDB_NO_QUOTE); + fieldVec[i]->print(&str, QT_ORDINARY); sc->alias(string(str.c_ptr())); SRCP srcp(sc); uint32_t j = 0; @@ -7863,7 +7948,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, continue; String str; - (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_INFINIDB_DERIVED); + (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); if (!firstTb) create_query += ", "; @@ -7925,7 +8010,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, MIGR::infinidb_vtable.create_vtable_query.free(); MIGR::infinidb_vtable.create_vtable_query.append(create_query.c_str(), create_query.length()); - MIGR::infinidb_vtable.vtable_state = THD::INFINIDB_REDO_PHASE1; // redo phase 1 + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_REDO_PHASE1; // redo phase 1 // turn off select distinct from post process unless there're post process functions // on the select list. @@ -8045,7 +8130,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, else if (ord_item->name.length) { // for union order by 1 case. For unknown reason, it doesn't show in_field_list - if (ord_item->type() == Item::INT_ITEM) + if (ord_item->type() == Item::CONST_ITEM + && ord_item->cmp_type() == INT_RESULT) { ord_cols += ord_item->name.str; } @@ -8079,7 +8165,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, else { String str; - ord_item->print(&str, QT_INFINIDB_NO_QUOTE); + ord_item->print(&str, QT_ORDINARY); ord_cols += string(str.c_ptr()); } @@ -8158,9 +8244,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // 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->offset_limit->is_fixed() && join->select_lex->select_limit && - join->select_lex->select_limit->fixed) + join->select_lex->select_limit->is_fixed()) { limitOffset = join->select_lex->offset_limit->val_int(); limitNum = join->select_lex->select_limit->val_int(); @@ -8196,7 +8282,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // 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 && - MIGR::infinidb_vtable.vtable_state != THD::INFINIDB_CREATE_VTABLE)) && + MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_CREATE_VTABLE)) && !csep->hasOrderBy()) { csep->limitStart(limitOffset); @@ -8329,7 +8415,8 @@ int cp_get_plan(THD* thd, SCSEP& csep) LEX* lex = thd->lex; idbassert(lex != 0); - SELECT_LEX select_lex = lex->select_lex; + // WIP MCOL-2178 A questionable replacement. + SELECT_LEX select_lex = *lex->first_select_lex(); gp_walk_info gwi; gwi.thd = thd; int status = getSelectPlan(gwi, select_lex, csep); @@ -8667,7 +8754,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro if (table_ptr->derived) { String str; - (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_INFINIDB_DERIVED); + (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); SELECT_LEX* select_cursor = table_ptr->derived->first_select(); FromSubQuery fromSub(gwi, select_cursor); @@ -8693,7 +8780,8 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro } else if (table_ptr->view) { - View* view = new View(table_ptr->view->select_lex, &gwi); + // WIP MCOL-2178 A questionable replacement. + View* view = new View(*table_ptr->view->first_select_lex(), &gwi); CalpontSystemCatalog::TableAliasName tn = make_aliastable(table_ptr->db.str, table_ptr->table_name.str, table_ptr->alias.str); view->viewName(tn); gwi.viewList.push_back(view); @@ -8763,7 +8851,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // MariaDB bug 624 - without the fix_fields call, delete with join may error with "No query step". //#if MYSQL_VERSION_ID < 50172 //@bug 3039. fix fields for constants - if (!icp->fixed) + if (!icp->is_fixed()) { icp->fix_fields(gwi.thd, (Item**)&icp); } @@ -8948,7 +9036,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro string fullname; String str; - ifp->print(&str, QT_INFINIDB_NO_QUOTE); + ifp->print(&str, QT_ORDINARY); fullname = str.c_ptr(); //sel_cols_in_create += fullname; @@ -9023,7 +9111,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro gwi.selectCols.push_back('`' + escapeBackTick(spac->alias().c_str()) + '`'); String str(256); - item->print(&str, QT_INFINIDB_NO_QUOTE); + item->print(&str, QT_ORDINARY); if (sel_cols_in_create.length() != 0) sel_cols_in_create += ", "; @@ -9097,7 +9185,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro { redo = true; String str; - ifp->print(&str, QT_INFINIDB_NO_QUOTE); + ifp->print(&str, QT_ORDINARY); gwi.selectCols.push_back(string(str.c_ptr()) + " " + "`" + escapeBackTick(item->name.str) + "`"); } @@ -9112,7 +9200,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro else { String str(256); - ifp->print(&str, QT_INFINIDB_NO_QUOTE); + ifp->print(&str, QT_ORDINARY); if (sel_cols_in_create.length() != 0) sel_cols_in_create += ", "; @@ -9221,7 +9309,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_ORDINARY); gwi.selectCols.push_back(string(funcStr.c_ptr()) + " `" + escapeBackTick(ifp->name.str) + "`"); // clear the error set by buildFunctionColumn gwi.fatalParseError = false; @@ -9232,97 +9320,110 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro break; } - case Item::INT_ITEM: + case Item::CONST_ITEM: { - 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 )) - { } - else + switch(item->cmp_type()) { - // do not push the dummy column (mysql added) to returnedCol - if (item->name.length && string(item->name.str) == "Not_used") - continue; + case INT_RESULT: + { + 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 )) + { } + else + { + // do not push the dummy column (mysql added) to returnedCol + if (item->name.length && string(item->name.str) == "Not_used") + continue; - // @bug3509. Constant column is sent to ExeMgr now. - SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + // @bug3509. Constant column is sent to ExeMgr now. + SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - if (item->name.length) - srcp->alias(item->name.str); + if (item->name.length) + srcp->alias(item->name.str); - gwi.returnedCols.push_back(srcp); + gwi.returnedCols.push_back(srcp); - Item_int* isp = reinterpret_cast(item); - ostringstream oss; - oss << isp->value << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; + Item_int* isp = reinterpret_cast(item); + ostringstream oss; + oss << isp->value << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; + if (sel_cols_in_create.length() != 0) + sel_cols_in_create += ", "; - sel_cols_in_create += oss.str(); - gwi.selectCols.push_back(oss.str()); + sel_cols_in_create += oss.str(); + gwi.selectCols.push_back(oss.str()); + } + + break; + } + + case STRING_RESULT: + { + 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 )) + { } + else + { + SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + gwi.returnedCols.push_back(srcp); + + if (item->name.length) + srcp->alias(item->name.str); + + Item_string* isp = reinterpret_cast(item); + String val, *str = isp->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + string name = "'" + valStr + "'" + " " + "`" + escapeBackTick(srcp->alias().c_str()) + "`"; + + if (sel_cols_in_create.length() != 0) + sel_cols_in_create += ", "; + + sel_cols_in_create += name; + gwi.selectCols.push_back(name); + } + + break; + } + + case DECIMAL_RESULT: + { + 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 )) + { } + else + { + SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + gwi.returnedCols.push_back(srcp); + + if (item->name.length) + srcp->alias(item->name.str); + + Item_decimal* isp = reinterpret_cast(item); + String val, *str = isp->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + ostringstream oss; + oss << valStr.c_str() << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; + + if (sel_cols_in_create.length() != 0) + sel_cols_in_create += ", "; + + sel_cols_in_create += oss.str(); + gwi.selectCols.push_back(oss.str()); + } + + break; + } + default: + // WIP MCOL-2178 Same thing as for getSelectPlan + { + // noop + } } - break; - } - - case Item::STRING_ITEM: - { - 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 )) - { } - else - { - SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - gwi.returnedCols.push_back(srcp); - - if (item->name.length) - srcp->alias(item->name.str); - - Item_string* isp = reinterpret_cast(item); - String val, *str = isp->val_str(&val); - string valStr; - valStr.assign(str->ptr(), str->length()); - string name = "'" + valStr + "'" + " " + "`" + escapeBackTick(srcp->alias().c_str()) + "`"; - - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += name; - gwi.selectCols.push_back(name); - } - - break; - } - - case Item::DECIMAL_ITEM: - { - 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 )) - { } - else - { - SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - gwi.returnedCols.push_back(srcp); - - if (item->name.length) - srcp->alias(item->name.str); - - Item_decimal* isp = reinterpret_cast(item); - String val, *str = isp->val_str(&val); - string valStr; - valStr.assign(str->ptr(), str->length()); - ostringstream oss; - oss << valStr.c_str() << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; - - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += oss.str(); - gwi.selectCols.push_back(oss.str()); - } - - break; - } + } // CONST_ITEM ends here case Item::NULL_ITEM: { + // WIP MCOL-2178 Check for NULL in projection. /*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 ) ) { } else @@ -9397,7 +9498,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro gwi.returnedCols.push_back(SRCP(rc)); String str; - sub->get_select_lex()->print(gwi.thd, &str, QT_INFINIDB_NO_QUOTE); + sub->get_select_lex()->print(gwi.thd, &str, QT_ORDINARY); sel_cols_in_create += "(" + string(str.c_ptr()) + ")"; if (sub->name.length) @@ -9565,7 +9666,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro } String str; - funcFieldVec[i]->print(&str, QT_INFINIDB_NO_QUOTE); + funcFieldVec[i]->print(&str, QT_ORDINARY); sc->alias(string(str.c_ptr())); //sc->tableAlias(funcFieldVec[i]->table_name); sc->tableAlias(sc->tableAlias()); @@ -9606,7 +9707,7 @@ 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 (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && !unionSel) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE && !unionSel) { gwi.clauseType = GROUP_BY; Item* nonSupportItem = NULL; @@ -9778,10 +9879,14 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // @bug5638. The group by column is constant but not counter, alias has to match a column // on the select list else if (!groupcol->counter_used && - (groupItem->type() == Item::INT_ITEM || - groupItem->type() == Item::STRING_ITEM || - groupItem->type() == Item::REAL_ITEM || - groupItem->type() == Item::DECIMAL_ITEM)) + (groupItem->type() == Item::CONST_ITEM && + (groupItem->cmp_type() == INT_RESULT || + groupItem->cmp_type() == STRING_RESULT || + groupItem->cmp_type() == REAL_RESULT || + groupItem->cmp_type() == DECIMAL_RESULT) + ) + ) + { ReturnedColumn* rc = 0; @@ -9885,7 +9990,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // ORDER BY processing starts here - if (MIGR::infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) { ORDER* ordercol = reinterpret_cast(gi.groupByOrder); string create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); @@ -9929,12 +10034,22 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro bool nonAggField = true; // ignore not_used column on order by. - if (ord_item->type() == Item::INT_ITEM && ord_item->full_name() && string(ord_item->full_name()) == "Not_used") + if ((ord_item->type() == Item::CONST_ITEM + && ord_item->cmp_type() == INT_RESULT) + && ord_item->full_name() + && !strcmp(ord_item->full_name(), "Not_used")) + { continue; - else if (ord_item->type() == Item::INT_ITEM) + } + else if (ord_item->type() == Item::CONST_ITEM + && ord_item->cmp_type() == INT_RESULT) + { rc = gwi.returnedCols[((Item_int*)ord_item)->val_int() - 1]->clone(); + } else if (ord_item->type() == Item::SUBSELECT_ITEM) + { gwi.fatalParseError = true; + } else if (ordercol->in_field_list && ord_item->type() == Item::FIELD_ITEM) { rc = buildReturnedColumn(ord_item, gwi, gwi.fatalParseError); @@ -10159,7 +10274,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro continue; String str; - (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_INFINIDB_DERIVED); + (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); if (!firstTb) create_query += ", "; @@ -10221,7 +10336,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro MIGR::infinidb_vtable.create_vtable_query.free(); MIGR::infinidb_vtable.create_vtable_query.append(create_query.c_str(), create_query.length()); - MIGR::infinidb_vtable.vtable_state = THD::INFINIDB_REDO_PHASE1; // redo phase 1 + MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_REDO_PHASE1; // redo phase 1 // turn off select distinct from post process unless there're post process functions // on the select list. @@ -10346,7 +10461,8 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro else if (ord_item->name.length) { // for union order by 1 case. For unknown reason, it doesn't show in_field_list - if (ord_item->type() == Item::INT_ITEM) + if (ord_item->type() == Item::CONST_ITEM + && ord_item->cmp_type() == INT_RESULT) { ord_cols += ord_item->name.str; } @@ -10380,7 +10496,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro else { String str; - ord_item->print(&str, QT_INFINIDB_NO_QUOTE); + ord_item->print(&str, QT_ORDINARY); ord_cols += string(str.c_ptr()); } diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 6790664a7..9be4eaf0a 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -752,8 +752,8 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h //float float_val = *(float*)(&value); //f2->store(float_val); - if (f2->decimals() < (uint32_t)row.getScale(s)) - // WIP MCOL-2178 + // WIP MCOL-2178 + //if (f2->decimals() < (uint32_t)row.getScale(s)) //f2->dec = (uint32_t)row.getScale(s); f2->store(dl); @@ -1320,7 +1320,6 @@ uint32_t doUpdateDelete(THD* thd) } // @bug 1127. Re-construct update stmt using lex instead of using the original query. -// string dmlStmt=""; string dmlStmt = string(idb_mysql_query_str(thd)); string schemaName; string tableName(""); @@ -1338,28 +1337,16 @@ uint32_t doUpdateDelete(THD* thd) { ColumnAssignment* columnAssignmentPtr; Item_field* item; -// TABLE_LIST* table_ptr = thd->lex->thd->lex->first_select_lex()->get_table_list(); - List_iterator_fast field_it(thd->lex->thd->lex->first_select_lex()->item_list); + List_iterator_fast field_it(thd->lex->first_select_lex()->item_list); List_iterator_fast value_it(thd->lex->value_list); -// dmlStmt += "update "; updateCP->queryType(CalpontSelectExecutionPlan::UPDATE); ci->stats.fQueryType = updateCP->queryType(); uint32_t cnt = 0; tr1::unordered_set timeStampColumnNames; -// for (; table_ptr; table_ptr= table_ptr->next_local) -// { -// dmlStmt += string(table_ptr->table_name); -// if (table_ptr->next_local) -// dmlStmt += ", "; -// } - -// dmlStmt += " set "; - while ((item = (Item_field*) field_it++)) { cnt++; -// dmlStmt += string(item->name) + "="; string tmpTableName = bestTableName(item); @@ -1411,21 +1398,41 @@ uint32_t doUpdateDelete(THD* thd) columnAssignmentPtr->fFuncScale = 0; Item* value = value_it++; - if (value->type() == Item::STRING_ITEM) + if (value->type() == Item::CONST_ITEM) { - //@Bug 2587 use val_str to replace value->name to get rid of 255 limit - String val, *str; - str = value->val_str(&val); - columnAssignmentPtr->fScalarExpression.assign(str->ptr(), str->length()); - columnAssignmentPtr->fFromCol = false; + if (value->cmp_type() == STRING_RESULT) + { + //@Bug 2587 use val_str to replace value->name to get rid of 255 limit + String val, *str; + str = value->val_str(&val); + columnAssignmentPtr->fScalarExpression.assign(str->ptr(), str->length()); + columnAssignmentPtr->fFromCol = false; + } + else if (value->cmp_type() == INT_RESULT) + { + std::ostringstream oss; + + if (value->unsigned_flag) + { + oss << value->val_uint(); + } + else + { + oss << value->val_int(); + } + + columnAssignmentPtr->fScalarExpression = oss.str(); + columnAssignmentPtr->fFromCol = false; + } } - else if ( value->type() == Item::VARBIN_ITEM ) + // WIP MCOL-2178 + /*else if ( value->type() == Item::VARBIN_ITEM ) { String val, *str; str = value->val_str(&val); columnAssignmentPtr->fScalarExpression.assign(str->ptr(), str->length()); columnAssignmentPtr->fFromCol = false; - } + }*/ else if ( value->type() == Item::FUNC_ITEM ) { //Bug 2092 handle negative values @@ -1491,23 +1498,6 @@ uint32_t doUpdateDelete(THD* thd) } } } - else if ( value->type() == Item::INT_ITEM ) - { - std::ostringstream oss; - - if (value->unsigned_flag) - { - oss << value->val_uint(); - } - else - { - oss << value->val_int(); - } - -// dmlStmt += oss.str(); - columnAssignmentPtr->fScalarExpression = oss.str(); - columnAssignmentPtr->fFromCol = false; - } else if ( value->type() == Item::FIELD_ITEM) { isFromCol = true; @@ -1590,8 +1580,6 @@ uint32_t doUpdateDelete(THD* thd) } colAssignmentListPtr->push_back ( columnAssignmentPtr ); -// if (cnt < thd->lex->thd->lex->first_select_lex()->item_list.elements) -// dmlStmt += ", "; } // Support for on update current_timestamp() for timestamp fields @@ -1620,7 +1608,6 @@ uint32_t doUpdateDelete(THD* thd) } else { -// dmlStmt = string(idb_mysql_query_str(thd)); updateCP->queryType(CalpontSelectExecutionPlan::DELETE); ci->stats.fQueryType = updateCP->queryType(); } @@ -1639,7 +1626,7 @@ uint32_t doUpdateDelete(THD* thd) } else { - first_table = (TABLE_LIST*) thd->lex->thd->lex->first_select_lex()->table_list.first; + first_table = (TABLE_LIST*) thd->lex->first_select_lex()->table_list.first; aTableName.schema = first_table->table->s->db.str; aTableName.table = first_table->table->s->table_name.str; } @@ -1690,9 +1677,9 @@ uint32_t doUpdateDelete(THD* thd) } else if ((thd->lex)->sql_command == SQLCOM_DELETE_MULTI) //@Bug 6121 error out on multi tables delete. { - if ( (thd->lex->thd->lex->first_select_lex()->join) != 0) + if ( (thd->lex->first_select_lex()->join) != 0) { - multi_delete* deleteTable = (multi_delete*)((thd->lex->thd->lex->first_select_lex()->join)->result); + multi_delete* deleteTable = (multi_delete*)((thd->lex->first_select_lex()->join)->result); first_table = (TABLE_LIST*) deleteTable->get_tables(); if (deleteTable->get_num_of_tables() == 1) @@ -1715,7 +1702,7 @@ uint32_t doUpdateDelete(THD* thd) } else { - first_table = (TABLE_LIST*) thd->lex->thd->lex->first_select_lex()->table_list.first; + first_table = (TABLE_LIST*) thd->lex->first_select_lex()->table_list.first; schemaName = first_table->table->s->db.str; tableName = first_table->table->s->table_name.str; aliasName = first_table->alias.str; @@ -1726,7 +1713,7 @@ uint32_t doUpdateDelete(THD* thd) } else { - first_table = (TABLE_LIST*) thd->lex->thd->lex->first_select_lex()->table_list.first; + first_table = (TABLE_LIST*) thd->lex->first_select_lex()->table_list.first; schemaName = first_table->table->s->db.str; tableName = first_table->table->s->table_name.str; aliasName = first_table->alias.str; @@ -1759,8 +1746,8 @@ uint32_t doUpdateDelete(THD* thd) if (( (thd->lex)->sql_command == SQLCOM_UPDATE ) || ( (thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ) { - items = (thd->lex->thd->lex->first_select_lex()->item_list); - thd->lex->thd->lex->first_select_lex()->item_list = thd->lex->value_list; + items = (thd->lex->first_select_lex()->item_list); + thd->lex->first_select_lex()->item_list = thd->lex->value_list; } select_lex = *lex->first_select_lex(); @@ -1824,7 +1811,7 @@ uint32_t doUpdateDelete(THD* thd) // @bug 4457. MySQL inconsistence! for some queries, some structures are only available // in the derived_tables_processing phase. So by pass the phase for DML only when the // execution plan can not be successfully generated. recover lex before returning; - thd->lex->thd->lex->first_select_lex()->item_list = items; + thd->lex->first_select_lex()->item_list = items; MIGR::infinidb_vtable.vtable_state = origState; return 0; } @@ -1975,7 +1962,7 @@ uint32_t doUpdateDelete(THD* thd) //cout<< "Plan is " << endl << *updateCP << endl; if (( (thd->lex)->sql_command == SQLCOM_UPDATE ) || ( (thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ) - thd->lex->thd->lex->first_select_lex()->item_list = items; + thd->lex->first_select_lex()->item_list = items; } //cout<< "Plan is " << endl << *updateCP << endl; @@ -3253,7 +3240,7 @@ int ha_calpont_impl_delete_table(const char* name) } else { - TABLE_LIST* first_table = (TABLE_LIST*) thd->lex->thd->lex->first_select_lex()->table_list.first; + TABLE_LIST* first_table = (TABLE_LIST*) thd->lex->first_select_lex()->table_list.first; dbName = const_cast(first_table->db.str); } @@ -4280,7 +4267,6 @@ int ha_calpont_impl_close_connection (handlerton* hton, THD* thd) int ha_calpont_impl_rename_table(const char* from, const char* to) { IDEBUG( cout << "ha_calpont_impl_rename_table: " << from << " => " << to << endl ); - THD* thd = current_thd; if (get_fe_conn_info_ptr() == NULL) set_fe_conn_info_ptr((void*)new cal_connection_info()); diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp index 6b7f0ff89..489751795 100644 --- a/dbcon/mysql/ha_mcs_pushdown.cpp +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -129,11 +129,11 @@ create_calpont_group_by_handler(THD* thd, Query* query) SELECT_LEX *select_lex = query->from->select_lex; // Create a handler if query is valid. See comments for details. - if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE + if //( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE // WIP MCOL-2178 //&& ( MIGR::infinidb_vtable_mode == 0 // || MIGR::infinidb_vtable_mode == 2 ) - && ( query->group_by || select_lex->with_sum_func ) ) + ( query->group_by || select_lex->with_sum_func ) //) { bool unsupported_feature = false; // revisit SELECT_LEX for all units @@ -214,12 +214,12 @@ create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived) SELECT_LEX_UNIT *unit= derived->derived; - if ( MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE ) + /* //if ( MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE ) // WIP MCOL-2178 // && MIGR::infinidb_vtable_mode != 0 ) { return 0; - } + }*/ for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) { @@ -472,13 +472,15 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) ha_columnstore_select_handler* handler = NULL; handlerton *ht= 0; + /* // Return if vtable enabled. - if ( MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE ) + //if ( MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE ) // WIP MCOL-2178 // && MIGR::infinidb_vtable_mode != 0 ) { return 0; - } + }*/ + for (SELECT_LEX* sl = select_lex;sl; sl= sl->next_select()) { if (!(sl->join)) diff --git a/dbcon/mysql/ha_view.cpp b/dbcon/mysql/ha_view.cpp index 761608d0e..8a6df6a0f 100644 --- a/dbcon/mysql/ha_view.cpp +++ b/dbcon/mysql/ha_view.cpp @@ -109,7 +109,9 @@ void View::transform() // for nested view, the view name is vout.vin... format CalpontSystemCatalog::TableAliasName tn = make_aliasview(table_ptr->db.str, table_ptr->table_name.str, table_ptr->alias.str, viewName); gwi.viewName = make_aliastable(table_ptr->db.str, table_ptr->table_name.str, viewName); - View* view = new View(table_ptr->view->select_lex, &gwi); + // WIP MCOL-2178 CS could mess with the SELECT_LEX unit so better + // use a copy. + View* view = new View(*table_ptr->view->first_select_lex(), &gwi); view->viewName(gwi.viewName); gwi.viewList.push_back(view); view->transform(); diff --git a/dbcon/mysql/idb_mysql.h b/dbcon/mysql/idb_mysql.h index 47dd61aff..b16301159 100644 --- a/dbcon/mysql/idb_mysql.h +++ b/dbcon/mysql/idb_mysql.h @@ -154,7 +154,8 @@ class MIGR INFINIDB_VTABLE() : cal_conn_info(NULL) {init();} void init() { - vtable_state = INFINIDB_INIT_CONNECT; + //vtable_state = INFINIDB_INIT_CONNECT; + vtable_state = INFINIDB_DISABLE_VTABLE; autoswitch = false; has_order_by = false; duplicate_field_name = false; diff --git a/dbcon/mysql/my.cnf b/dbcon/mysql/my.cnf index fb20fd8c9..12392a664 100644 --- a/dbcon/mysql/my.cnf +++ b/dbcon/mysql/my.cnf @@ -47,21 +47,21 @@ group_concat_max_len=512 sql_mode="ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" # Enable compression by default on create, set to 0 to turn off -infinidb_compression_type=2 +#columnstore_compression_type=2 # Default for string table threshhold -infinidb_stringtable_threshold=20 +#columnstore_stringtable_threshold=20 # infinidb local query flag -infinidb_local_query=0 +#columnstore_local_query=0 -infinidb_diskjoin_smallsidelimit=0 -infinidb_diskjoin_largesidelimit=0 -infinidb_diskjoin_bucketsize=100 -infinidb_um_mem_limit=0 +#columnstore_diskjoin_smallsidelimit=0 +#columnstore_diskjoin_largesidelimit=0 +#columnstore_diskjoin_bucketsize=100 +#columnstore_um_mem_limit=0 -infinidb_use_import_for_batchinsert=1 -infinidb_import_for_batchinsert_delimiter=7 +#columnstore_use_import_for_batchinsert=1 +#columnstore_import_for_batchinsert_delimiter=7 basedir = /usr/local/mariadb/columnstore/mysql/ character-sets-dir = /usr/local/mariadb/columnstore/mysql/share/charsets/ From 5409eed6f53525e55ca2290347f5cc15a6d019d2 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Mon, 25 Feb 2019 18:42:56 +0300 Subject: [PATCH 04/11] MCOL-2178 Introduced a dummy replacement for a infinidb_table. Used Item attribute getters introduced by 10.4 Make changes to support Item::CONST_ITEM introduced by 10.4 as a replacement for INT_,REAL_,STRING_ ITEM. Replaced QT_INFINIDB_DERIVED and similar flags with correponded flags for Item->print(). Replaced or commented out infinidb_ variable names with columnstore_ where applicable. Fixed an impossible precision typo. --- dbcon/mysql/ha_calpont_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 9be4eaf0a..4efe01b51 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -779,7 +779,7 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h // bug 3483, reserve enough space for the longest double value // -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and // 2.2250738585072014E-308 to 1.7976931348623157E+308. - (*f)->field_length = 310; + (*f)->field_length = 40; //double double_val = *(double*)(&value); //f2->store(double_val); From c297ceb6c1342bc489435c02bd24c0bb7705c931 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Thu, 25 Apr 2019 11:01:57 +0300 Subject: [PATCH 05/11] MCOL-2178 Connector code now uses separate hton for columnstore engine. CS now uses hton->close_connection() method to release all FEP connections from MDB to ExeMgr. Refactor fetchNextRow() to remove decimal and double precision changes. --- dbcon/mysql/ha_calpont.cpp | 32 ++++++------ dbcon/mysql/ha_calpont.h | 1 + dbcon/mysql/ha_calpont_impl.cpp | 91 +++++++++++---------------------- 3 files changed, 46 insertions(+), 78 deletions(-) diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index dfbb452ef..bb4a6b0a8 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -34,6 +34,7 @@ static int calpont_commit(handlerton* hton, THD* thd, bool all); static int calpont_rollback(handlerton* hton, THD* thd, bool all); static int calpont_close_connection ( handlerton* hton, THD* thd ); handlerton* calpont_hton; +handlerton* mcs_hton; // handlers creation function for hton. // Look into ha_mcs_pushdown.* for more details. @@ -79,6 +80,7 @@ static uchar* calpont_get_key(INFINIDB_SHARE* share, size_t* length, return (uchar*) share->table_name; } +// This one is unused int calpont_discover(handlerton* hton, THD* thd, TABLE_SHARE* share) { DBUG_ENTER("calpont_discover"); @@ -105,6 +107,7 @@ int calpont_discover(handlerton* hton, THD* thd, TABLE_SHARE* share) DBUG_RETURN(my_errno); } +// This f() is also unused int calpont_discover_existence(handlerton* hton, const char* db, const char* table_name) { @@ -127,24 +130,24 @@ static int columnstore_init_func(void* p) fprintf(stderr, "Columnstore: Started; Version: %s-%s\n", columnstore_version.c_str(), columnstore_release.c_str()); - calpont_hton = (handlerton*)p; + mcs_hton = (handlerton*)p; #ifndef _MSC_VER (void) pthread_mutex_init(&calpont_mutex, MY_MUTEX_INIT_FAST); #endif (void) my_hash_init(&calpont_open_tables, system_charset_info, 32, 0, 0, (my_hash_get_key) calpont_get_key, 0, 0); - calpont_hton->state = SHOW_OPTION_YES; - calpont_hton->create = calpont_create_handler; - calpont_hton->flags = HTON_CAN_RECREATE; -// calpont_hton->discover_table= calpont_discover; -// calpont_hton->discover_table_existence= calpont_discover_existence; - calpont_hton->commit = calpont_commit; - calpont_hton->rollback = calpont_rollback; - calpont_hton->close_connection = calpont_close_connection; - calpont_hton->create_group_by = create_calpont_group_by_handler; - calpont_hton->create_derived = create_columnstore_derived_handler; - calpont_hton->create_select = create_columnstore_select_handler; + mcs_hton->state = SHOW_OPTION_YES; + mcs_hton->create = calpont_create_handler; + mcs_hton->flags = HTON_CAN_RECREATE; +// mcs_hton->discover_table= calpont_discover; +// mcs_hton->discover_table_existence= calpont_discover_existence; + mcs_hton->commit = calpont_commit; + mcs_hton->rollback = calpont_rollback; + mcs_hton->close_connection = calpont_close_connection; + mcs_hton->create_group_by = create_calpont_group_by_handler; + mcs_hton->create_derived = create_columnstore_derived_handler; + mcs_hton->create_select = create_columnstore_select_handler; DBUG_RETURN(0); } @@ -282,10 +285,6 @@ int ha_calpont::open(const char* name, int mode, uint32_t test_if_locked) { DBUG_ENTER("ha_calpont::open"); - //if (!(share = get_share(name, table))) - // DBUG_RETURN(1); - //thr_lock_data_init(&share->lock,&lock,NULL); - int rc = ha_calpont_impl_open(name, mode, test_if_locked); DBUG_RETURN(rc); @@ -311,7 +310,6 @@ int ha_calpont::open(const char* name, int mode, uint32_t test_if_locked) int ha_calpont::close(void) { DBUG_ENTER("ha_calpont::close"); - //DBUG_RETURN(free_share(share)); int rc = ha_calpont_impl_close(); diff --git a/dbcon/mysql/ha_calpont.h b/dbcon/mysql/ha_calpont.h index 070f5380b..3d184f955 100644 --- a/dbcon/mysql/ha_calpont.h +++ b/dbcon/mysql/ha_calpont.h @@ -22,6 +22,7 @@ #include "ha_mcs_sysvars.h" extern handlerton* calpont_hton; +extern handlerton* mcs_hton; /** @brief INFINIDB_SHARE is a structure that will be shared among all open handlers. diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 4efe01b51..989d9ea6b 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -577,10 +577,6 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h * At a later date we should set this more intelligently * based on the result set. */ - /* MCOL-683: UTF-8 datetime no msecs is 57, this sometimes happens! */ -// if (((*f)->field_length > 19) && ((*f)->field_length != 57)) -// (*f)->field_length = strlen(tmp); - Field_varstring* f2 = (Field_varstring*)*f; f2->store(tmp, strlen(tmp), f2->charset()); break; @@ -742,29 +738,18 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h if (dl == std::numeric_limits::infinity()) continue; - //int64_t* icvp = (int64_t*)&dl; - //intColVal = *icvp; Field_float* f2 = (Field_float*)*f; // bug 3485, reserve enough space for the longest float value // -3.402823466E+38 to -1.175494351E-38, 0, and // 1.175494351E-38 to 3.402823466E+38. (*f)->field_length = 40; - //float float_val = *(float*)(&value); - //f2->store(float_val); - // WIP MCOL-2178 - //if (f2->decimals() < (uint32_t)row.getScale(s)) - //f2->dec = (uint32_t)row.getScale(s); - f2->store(dl); if ((*f)->null_ptr) *(*f)->null_ptr &= ~(*f)->null_bit; break; - - //storeNumericField(f, intColVal, colType); - //break; } case CalpontSystemCatalog::DOUBLE: @@ -781,30 +766,12 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h // 2.2250738585072014E-308 to 1.7976931348623157E+308. (*f)->field_length = 40; - //double double_val = *(double*)(&value); - //f2->store(double_val); - - - // WIP MCOL-2178 - /* - if ((f2->decimals() == DECIMAL_NOT_SPECIFIED && row.getScale(s) > 0) - || f2->decimals() < row.getScale(s)) - { - f2->dec = row.getScale(s); - }*/ - f2->store(dl); if ((*f)->null_ptr) *(*f)->null_ptr &= ~(*f)->null_bit; break; - - - //int64_t* icvp = (int64_t*)&dl; - //intColVal = *icvp; - //storeNumericField(f, intColVal, colType); - //break; } case CalpontSystemCatalog::LONGDOUBLE: @@ -821,12 +788,6 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h { char buf[310]; Field_new_decimal* f2 = (Field_new_decimal*)*f; - if ((f2->decimals() == DECIMAL_NOT_SPECIFIED && row.getScale(s) > 0) - || f2->decimals() < row.getScale(s)) - { - f2->dec = row.getScale(s); - } -// dl /= pow(10.0, (double)f2->dec); snprintf(buf, 310, "%.20Lg", dl); f2->store(buf, strlen(buf), f2->charset()); if ((*f)->null_ptr) @@ -842,12 +803,6 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h // 2.2250738585072014E-308 to 1.7976931348623157E+308. (*f)->field_length = 310; - if ((f2->decimals() == DECIMAL_NOT_SPECIFIED && row.getScale(s) > 0) - || f2->decimals() < row.getScale(s)) - { - f2->dec = row.getScale(s); - } - f2->store(static_cast(dl)); if ((*f)->null_ptr) *(*f)->null_ptr &= ~(*f)->null_bit; @@ -1425,7 +1380,7 @@ uint32_t doUpdateDelete(THD* thd) columnAssignmentPtr->fFromCol = false; } } - // WIP MCOL-2178 + // WIP MCOL-2178 /*else if ( value->type() == Item::VARBIN_ITEM ) { String val, *str; @@ -2368,8 +2323,15 @@ int ha_calpont_impl_rnd_init(TABLE* table) MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } - #endif + + // Set this to close all outstanding FEP connections on + // client disconnect in handlerton::closecon_handlerton(). + if ( !thd_get_ha_data(thd, mcs_hton)) + { + thd_set_ha_data(thd, mcs_hton, reinterpret_cast(0x42)); + } + // prevent "create table as select" from running on slave MIGR::infinidb_vtable.hasInfiniDBTable = true; @@ -2533,9 +2495,10 @@ int ha_calpont_impl_rnd_init(TABLE* table) } // vtable mode else + // The whole section must be useless now. { - //if (!ci->cal_conn_hndl || MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) - if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) + if ( !ci->cal_conn_hndl || + MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) { ci->stats.reset(); // reset query stats ci->stats.setStartTime(); @@ -2886,14 +2849,14 @@ int ha_calpont_impl_rnd_init(TABLE* table) return 0; error: - + // CS doesn't need to close the actual sockets + // b/c it tries to reuse it running next query. if (ci->cal_conn_hndl) { sm::sm_cleanup(ci->cal_conn_hndl); ci->cal_conn_hndl = 0; } - // do we need to close all connection handle of the table map? return ER_INTERNAL_ERROR; internal_error: @@ -3038,6 +3001,7 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) MIGR::infinidb_vtable.isNewQuery = true; + // WIP MCOL-2178 // Workaround because CS doesn't reset isUnion in a normal way. if (is_pushdown_hand) { @@ -3046,15 +3010,13 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) if (get_fe_conn_info_ptr() != NULL) ci = reinterpret_cast(get_fe_conn_info_ptr()); + // WIP MCOL-2178. Won't see this state anymore. if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY ) { MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; // flip back to normal state return rc; } -// if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1) -// return rc; - if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) return rc; @@ -3167,6 +3129,8 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) // reset expressionId just in case ci->expressionId = 0; + thd_set_ha_data(thd, mcs_hton, reinterpret_cast(ci)); + return rc; } @@ -4465,7 +4429,7 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) ci->queryState = 0; MIGR::infinidb_vtable.override_largeside_estimate = false; // MCOL-3247 Use THD::ha_data as a per-plugin per-session - // storage for cal_conn_hndl to use it later in close_connection + // storage for cal_conn_hndl to use it later in close_connection thd_set_ha_data(thd, calpont_hton, get_fe_conn_info_ptr()); } } @@ -5272,12 +5236,10 @@ int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, TABLE* * Execute the query and saves derived table query. * There is an extra handler argument so I ended up with a * new init function. The code is a copy of - * ha_calpont_impl_rnd_init() mostly. We should come up with - * a semi-universal structure that allows to save any - * extra data. + * ha_calpont_impl_rnd_init() mostly. * PARAMETERS: - * void* handler either select_ or derived_handler - * TABLE* table - table where to save the results + * mcs_handler_info* pnt to an envelope struct + * TABLE* table - dest table to put the results into * RETURN: * rc as int ***********************************************************/ @@ -5325,8 +5287,15 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } - #endif + + // Set this to close all outstanding FEP connections on + // client disconnect in handlerton::closecon_handlerton(). + if ( !thd_get_ha_data(thd, mcs_hton)) + { + thd_set_ha_data(thd, mcs_hton, reinterpret_cast(0x42)); + } + // prevent "create table as select" from running on slave MIGR::infinidb_vtable.hasInfiniDBTable = true; From b4d1cbc52928c8e36845b501d0174484940fe296 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Mon, 20 May 2019 19:10:21 +0300 Subject: [PATCH 06/11] MCOL-2178 upstream merge forces to add explicit namespaces. Add a magic value check to avoid cleanup procedures only if needed. --- dbcon/mysql/ha_calpont_impl.cpp | 4 ++-- dbcon/mysql/ha_calpont_impl_if.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 989d9ea6b..8fe27ea0d 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 InfiniDB, Inc. + /* Copyright (C) 2014 InfiniDB, Inc. Copyright (C) 2019 MariaDB Corporaton This program is free software; you can redistribute it and/or @@ -4203,7 +4203,7 @@ int ha_calpont_impl_close_connection (handlerton* hton, THD* thd) // An ugly way. I will use ha_data w/o external_lock. // This in MCOL-2178 cal_connection_info* ci = NULL; - if(thd_get_ha_data(thd, hton)) + if(thd_get_ha_data(thd, hton) != (void*)0x42) // 0x42 is the magic CS sets when setup hton { ci = reinterpret_cast(thd_get_ha_data(thd, hton)); } diff --git a/dbcon/mysql/ha_calpont_impl_if.h b/dbcon/mysql/ha_calpont_impl_if.h index 820f8d430..190ed620b 100644 --- a/dbcon/mysql/ha_calpont_impl_if.h +++ b/dbcon/mysql/ha_calpont_impl_if.h @@ -286,6 +286,7 @@ struct cal_connection_info std::stack cal_conn_hndl_st; int queryState; CalTableMap tableMap; + std::set physTablesList; sm::tableid_t currentTable; uint32_t traceFlags; std::string queryStats; @@ -337,8 +338,8 @@ const std::string infinidb_err_msg = "\nThe query includes syntax that is not su 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 cs_get_derived_plan(derived_handler* handler, THD* thd, SCSEP& csep); -int cs_get_select_plan(select_handler* handler, THD* thd, SCSEP& csep); +int cs_get_derived_plan(derived_handler* handler, THD* thd, execplan::SCSEP& csep); +int cs_get_select_plan(select_handler* handler, THD* thd, execplan::SCSEP& csep); int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, bool isUnion = false, bool isPushdownHand = 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); From 3074b6c4b31e38b75e222ce0641592e1a5bc09ec Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Thu, 30 May 2019 21:14:48 +0300 Subject: [PATCH 07/11] MCOL-2178 Functions with constant args are processed by CS now. Fix crash in ha_calpont_impl_close_connection() Fix leak in ci.tableMap. Removed extra returns in pushdown_init to avoid crashes. create_select_handler now detects INSERT..SELECT. buildConstColFromFilter now uses any kind of filter to supply relevant columns. Remove strings used by vtable redo phase. Make FromSubQuery aware of Pushdown handlers. Changed debug_walk to work around changed Item framework. Temporary disabled derived handler and unsupported features checks. --- dbcon/mysql/ha_calpont.cpp | 6 +- dbcon/mysql/ha_calpont_execplan.cpp | 781 ++++------------------------ dbcon/mysql/ha_calpont_impl.cpp | 136 ++--- dbcon/mysql/ha_from_sub.cpp | 11 +- dbcon/mysql/ha_mcs_pushdown.cpp | 74 +-- dbcon/mysql/ha_subquery.h | 8 +- 6 files changed, 172 insertions(+), 844 deletions(-) diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index bb4a6b0a8..19c37fd73 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -145,8 +145,8 @@ static int columnstore_init_func(void* p) mcs_hton->commit = calpont_commit; mcs_hton->rollback = calpont_rollback; mcs_hton->close_connection = calpont_close_connection; - mcs_hton->create_group_by = create_calpont_group_by_handler; - mcs_hton->create_derived = create_columnstore_derived_handler; + //mcs_hton->create_group_by = create_calpont_group_by_handler; + //mcs_hton->create_derived = create_columnstore_derived_handler; mcs_hton->create_select = create_columnstore_select_handler; DBUG_RETURN(0); } @@ -177,7 +177,7 @@ static int infinidb_init_func(void* p) calpont_hton->rollback = calpont_rollback; calpont_hton->close_connection = calpont_close_connection; calpont_hton->create_group_by = create_calpont_group_by_handler; - calpont_hton->create_derived = create_columnstore_derived_handler; + //calpont_hton->create_derived = create_columnstore_derived_handler; calpont_hton->create_select = create_columnstore_select_handler; DBUG_RETURN(0); diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index d97c1b303..243f2164c 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -19,7 +19,7 @@ /* * $Id: ha_calpont_execplan.cpp 9749 2013-08-15 04:00:39Z zzhu $ */ - + /** @file */ //#define DEBUG_WALK_COND #include @@ -429,40 +429,61 @@ void debug_walk(const Item* item, void* arg) '.' << ifp->field_name.str << endl; break; } - - case Item::INT_ITEM: + case Item::CONST_ITEM: { - Item_int* iip = (Item_int*)item; - cerr << "INT_ITEM: "; + switch (item->cmp_type()) + { + case INT_RESULT: + { + Item_int* iip = (Item_int*)item; + cerr << "INT_ITEM: "; - if (iip->name.length) cerr << iip->name.str << " (from name string)" << endl; - else cerr << iip->val_int() << endl; + if (iip->name.length) cerr << iip->name.str << " (from name string)" << endl; + else cerr << iip->val_int() << endl; + break; + } + case STRING_RESULT: + { + Item_string* isp = (Item_string*)item; + String val, *str = isp->val_str(&val); + string valStr; + valStr.assign(str->ptr(), str->length()); + cerr << "STRING_ITEM: >" << valStr << '<' << endl; + break; + } + case REAL_RESULT: + { + cerr << "REAL_ITEM" << endl; + break; + } + case DECIMAL_RESULT: + { + cerr << "DECIMAL_ITEM" << endl; + break; + } + case TIME_RESULT: + { + String val, *str = NULL; + Item_temporal_literal* itp = (Item_temporal_literal*)item; + str = itp->val_str(&val); + cerr << "DATE ITEM: "; + + if (str) + cerr << ": (" << str->ptr() << ')' << endl; + else + cerr << ": " << endl; + + break; + } + default: + { + cerr << ": Unknown cmp_type" << endl; + break; + } + } break; } - - case Item::STRING_ITEM: - { - Item_string* isp = (Item_string*)item; - String val, *str = isp->val_str(&val); - string valStr; - valStr.assign(str->ptr(), str->length()); - cerr << "STRING_ITEM: >" << valStr << '<' << endl; - break; - } - - case Item::REAL_ITEM: - { - cerr << "REAL_ITEM" << endl; - break; - } - - case Item::DECIMAL_ITEM: - { - cerr << "DECIMAL_ITEM" << endl; - break; - } - case Item::FUNC_ITEM: { Item_func* ifp = (Item_func*)item; @@ -514,7 +535,7 @@ void debug_walk(const Item* item, void* arg) case Item_func::BETWEEN: inp = (Item_func_opt_neg*)ifp; - if (inp->get_negated()) cerr << "not "; + if (inp->negated) cerr << "not "; cerr << "between" << " (" << ifp->functype() << ")" << endl; break; @@ -713,7 +734,8 @@ void debug_walk(const Item* item, void* arg) item_name = const_cast(isp->get_arg(0)->name.str); } else if (!item_name && isp->get_arg_count() - && isp->get_arg(0)->type() == Item::INT_ITEM) + && isp->get_arg(0)->type() == Item::CONST_ITEM + && isp->get_arg(0)->cmp_type() == INT_RESULT) { item_name = (char*)"INT||*"; } @@ -1104,21 +1126,6 @@ void debug_walk(const Item* item, void* arg) break; } - case Item::DATE_ITEM: - { - String val, *str = NULL; - Item_temporal_literal* itp = (Item_temporal_literal*)item; - str = itp->val_str(&val); - cerr << "DATE ITEM: "; - - if (str) - cerr << ": (" << str->ptr() << ')' << endl; - else - cerr << ": " << endl; - - break; - } - case Item::WINDOW_FUNC_ITEM: { Item_window_func* ifp = (Item_window_func*)item; @@ -6079,7 +6086,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); SELECT_LEX* select_cursor = table_ptr->derived->first_select(); - FromSubQuery fromSub(gwi, select_cursor); + FromSubQuery fromSub(gwi, select_cursor, isPushdownHand); string alias(table_ptr->alias.str); fromSub.alias(lower(alias)); @@ -6202,7 +6209,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, union_gwi.thd = gwi.thd; uint32_t err = 0; - if ((err = getSelectPlan(union_gwi, *sl, plan, unionSel)) != 0) + if ((err = getSelectPlan(union_gwi, *sl, plan, unionSel, isPushdownHand)) != 0) return err; unionVec.push_back(SCEP(plan)); @@ -6417,7 +6424,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, List_iterator_fast it(select_lex.item_list); Item* item; vector funcFieldVec; - string sel_cols_in_create; + string sel_cols_in_select; bool redo = false; @@ -6469,18 +6476,13 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, { boost::shared_ptr spsc(sc); - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - string fullname; String str; ifp->print(&str, QT_ORDINARY); fullname = str.c_ptr(); - //sel_cols_in_create += fullname; if (ifp->is_autogenerated_name) // no alias { - sel_cols_in_create += fullname + " `" + escapeBackTick(str.c_ptr()) + "`"; sc->alias(fullname); } else // alias @@ -6488,7 +6490,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, if (!itemAlias.empty()) sc->alias(itemAlias); - sel_cols_in_create += fullname + " `" + escapeBackTick(sc->alias().c_str()) + "`"; } if (ifp->is_autogenerated_name) @@ -6538,10 +6539,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, String str(256); item->print(&str, QT_ORDINARY); - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += string(str.c_ptr()) + " `" + escapeBackTick(spac->alias().c_str()) + "`"; break; } @@ -6587,54 +6584,21 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, if (rc) { + // MCOL-2178 CS has to process determenistic functions with constant arguments. if (!hasNonSupportItem && !nonConstFunc(ifp) && !(parseInfo & AF_BIT) && tmpVec.size() == 0) { - if (isUnion || unionSel || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT || - parseInfo & SUB_BIT || select_lex.group_list.elements != 0) - { - srcp.reset(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - gwi.returnedCols.push_back(srcp); + srcp.reset(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + gwi.returnedCols.push_back(srcp); - if (ifp->name.length) - srcp->alias(ifp->name.str); + if (ifp->name.length) + srcp->alias(ifp->name.str); - continue; - } - - 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 ) ) - { } - else - { - redo = true; - String str; - ifp->print(&str, QT_ORDINARY); - gwi.selectCols.push_back(string(str.c_ptr()) + " " + "`" + escapeBackTick(item->name.str) + "`"); - } - - break; + continue; } - //SRCP srcp(rc); gwi.returnedCols.push_back(srcp); - - 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 )) - { } - else - { - String str(256); - ifp->print(&str, QT_ORDINARY); - - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += string(str.c_ptr()) + " `" + ifp->name.str + "`"; - gwi.selectCols.push_back("`" + escapeBackTick(ifp->name.str) + "`"); - } } - else // InfiniDB Non support functions still go through post process for now + else // This was a vtable post-process block { hasNonSupportItem = false; uint32_t before_size = funcFieldVec.size(); @@ -6642,13 +6606,14 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, uint32_t after_size = funcFieldVec.size(); // group by func and func in subquery can not be post processed + // pushdown handler projection functions // @bug3881. set_user_var can not be treated as constant function // @bug5716. Try to avoid post process function for union query. if ((gwi.subQuery || select_lex.group_list.elements != 0 || - !csep->unionVec().empty() || isUnion) && + !csep->unionVec().empty() || isUnion || isPushdownHand ) && !hasNonSupportItem && (after_size - before_size) == 0 && - !(parseInfo & AGG_BIT) && !(parseInfo & SUB_BIT) && - string(ifp->func_name()) != "set_user_var") + !(parseInfo & AGG_BIT) && !(parseInfo & SUB_BIT) + ) { String val, *str = ifp->val_str(&val); string valStr; @@ -6721,23 +6686,14 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, return -1; } } - - //@Bug 3021. Bypass postprocess for update and delete. - //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 )) - //{} else { - // @bug 3881. Here is the real redo part. - redo = true; - // @bug 1706 - String funcStr; - ifp->print(&funcStr, QT_ORDINARY); - string valStr; - valStr.assign(funcStr.ptr(), funcStr.length()); - gwi.selectCols.push_back(valStr + " `" + escapeBackTick(ifp->name.str) + "`"); - // clear the error set by buildFunctionColumn - gwi.fatalParseError = false; - gwi.parseErrorText = ""; + Message::Args args; + args.add(ifp->func_name()); + gwi.parseErrorText = + IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORTED_FUNCTION, args); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; } } @@ -6770,10 +6726,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, ostringstream oss; oss << isp->value << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += oss.str(); gwi.selectCols.push_back(oss.str()); } @@ -6798,10 +6750,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, valStr.assign(str->ptr(), str->length()); string name = "'" + valStr + "'" + " " + "`" + escapeBackTick(srcp->alias().c_str()) + "`"; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += name; gwi.selectCols.push_back(name); } @@ -6827,10 +6775,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, ostringstream oss; oss << valStr.c_str() << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += oss.str(); gwi.selectCols.push_back(oss.str()); } @@ -6862,10 +6806,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, string name = string("null `") + escapeBackTick(srcp->alias().c_str()) + string("`") ; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += name; gwi.selectCols.push_back("null"); } @@ -6925,16 +6865,13 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, gwi.returnedCols.push_back(SRCP(rc)); String str; sub->get_select_lex()->print(gwi.thd, &str, QT_ORDINARY); - sel_cols_in_create += "(" + string(str.c_ptr()) + ")"; if (sub->name.length) { - sel_cols_in_create += "`" + escapeBackTick(sub->name.str) + "`"; gwi.selectCols.push_back(sub->name.str); } else { - sel_cols_in_create += "`" + escapeBackTick(str.c_ptr()) + "`"; gwi.selectCols.push_back("`" + escapeBackTick(str.c_ptr()) + "`"); } @@ -7116,21 +7053,14 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, gwi.returnedCols.push_back(srcp); gwi.columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(string(funcFieldVec[i]->field_name.str), srcp)); - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - string fullname; fullname = str.c_ptr(); - sel_cols_in_create += fullname + " `" + escapeBackTick(fullname.c_str()) + "`"; TABLE_LIST* tmp = (funcFieldVec[i]->cached_table ? funcFieldVec[i]->cached_table : 0); gwi.tableMap[make_aliastable(sc->schemaName(), sc->tableName(), sc->tableAlias(), sc->isInfiniDB())] = make_pair(1, tmp); } } - // post-process Order by list and expressions on select by redo phase1. only for vtable - // ignore ORDER BY clause for union select unit - string ord_cols = ""; // for normal select phase SRCP minSc; // min width projected column. for count(*) use // Group by list. not valid for union main query @@ -7418,13 +7348,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, { SQL_I_List order_list = select_lex.order_list; ORDER* ordercol = reinterpret_cast(order_list.first); - string create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); - string select_query(MIGR::infinidb_vtable.select_vtable_query.c_ptr()); - string lower_create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); - string lower_select_query(MIGR::infinidb_vtable.select_vtable_query.c_ptr()); - boost::algorithm::to_lower(lower_create_query); - boost::algorithm::to_lower(lower_select_query); - // check if window functions are in order by. InfiniDB process order by list if // window functions are involved, either in order by or projection. @@ -7531,7 +7454,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, else if (!isUnion) { vector fieldVec; - bool addToSel; // the following order by is just for redo phase if (!unionSel) @@ -7544,101 +7466,14 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, while (ord_item->type() == Item::REF_ITEM) ord_item = (*((Item_ref*)ord_item)->ref); - // @bug 1706. re-construct the order by item one by one - //Item* ord_item = *(ordercol->item); - if (ord_cols.length() != 0) - ord_cols += ", "; + //ReturnedColumn* rc = 0; + // check if this order by column is on the select list + //Item_func* ifp = (Item_func*)(*(ordercol->item)); + //rc = buildFunctionColumn(ifp, gwi, gwi.fatalParseError); - addToSel = true; - string fullname; - - if (ordercol->in_field_list && ordercol->counter_used) + if (ord_item->type() == Item::FUNC_ITEM) { - ostringstream oss; - oss << ordercol->counter; - ord_cols += oss.str(); - - if (ordercol->direction != ORDER::ORDER_ASC) - ord_cols += " desc"; - - continue; - } - - else if (ord_item->type() == Item::FUNC_ITEM) - { - // @bug 2621. order by alias - if (!ord_item->is_autogenerated_name && ord_item->name.length) - { - ord_cols += ord_item->name.str; - continue; - } - - // if there's group by clause or aggregate column, check to see - // if this item or the arguments is on the GB list. - ReturnedColumn* rc = 0; - // check if this order by column is on the select list - Item_func* ifp = (Item_func*)(*(ordercol->item)); - rc = buildFunctionColumn(ifp, gwi, gwi.fatalParseError); - - if (rc) - { - for (uint32_t i = 0; i < gwi.returnedCols.size(); i++) - { - if (rc && rc->operator==(gwi.returnedCols[i].get())) - { - ostringstream oss; - oss << i + 1; - ord_cols += oss.str(); - addToSel = false; - break; - } - } - } - - if (addToSel) - { - FunctionColumn* fc = dynamic_cast(rc); - - if (fc) - { - addToSel = false; - redo = true; - string ord_func = string(ifp->func_name()) + "("; - - for (uint32_t i = 0; i < fc->functionParms().size(); i++) - { - if (i != 0) - ord_func += ","; - - for (uint32_t j = 0; j < gwi.returnedCols.size(); j++) - { - if (fc->functionParms()[i]->data()->operator==(gwi.returnedCols[j].get())) - { - ord_func += "`" + escapeBackTick(gwi.returnedCols[j]->alias().c_str()) + "`"; - continue; - } - - AggregateColumn* ac = dynamic_cast(fc->functionParms()[i]->data()); - - if (ac) - { - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_ORDER_BY); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - - addToSel = true; - //continue; - - } - } - - ord_func += ")"; - - if (!addToSel) - ord_cols += ord_func; - } - } + //FunctionColumn* fc = dynamic_cast(rc); } else if (ord_item->type() == Item::SUBSELECT_ITEM) { @@ -7646,7 +7481,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, emsg, gwi); return ER_CHECK_NOT_IMPLEMENTED; } - else if (ord_item->type() == Item::SUM_FUNC_ITEM) { ReturnedColumn* ac = 0; @@ -7670,38 +7504,12 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, if (!ret) continue; - if (ac->operator==(gwi.returnedCols[i].get())) - { - ostringstream oss; - oss << i + 1; - ord_cols += oss.str(); - addToSel = false; - break; - } } if (ac || !gwi.groupByCols.empty()) { - if (addToSel) - { - redo = true; - // @bug 3076. do not add the argument of aggregate function to the SELECT list, - // instead, add the whole column - String str; - ord_item->print(&str, QT_ORDINARY); - - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += str.c_ptr(); - //gwi.selectCols.push_back(" `" + string(str.c_ptr()) + "`"); - SRCP srcp(ac); - gwi.returnedCols.push_back(srcp); - ord_cols += " `" + escapeBackTick(str.c_ptr()) + "`"; - } - - if (ordercol->direction != ORDER::ORDER_ASC) - ord_cols += " desc"; + SRCP srcp(ac); + gwi.returnedCols.push_back(srcp); continue; } @@ -7710,13 +7518,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, { 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++) { @@ -7728,26 +7529,13 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, continue; } - if (strcasecmp(fullname.c_str(), gwi.returnedCols[i]->alias().c_str()) == 0 || - strcasecmp(ord_item->name.str, gwi.returnedCols[i]->alias().c_str()) == 0) - { - ord_cols += string(" `") + escapeBackTick(gwi.returnedCols[i]->alias().c_str()) + '`'; - addToSel = false; - break; - } - if (sc && sc->sameColumn(rc)) { - ostringstream oss; - oss << i + 1; - ord_cols += oss.str(); - addToSel = false; break; } } } - if (addToSel) { // @bug 2719. Error out order by not on the distinct select list. if (select_lex.options & SELECT_DISTINCT) @@ -7768,13 +7556,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, return ER_CHECK_NOT_IMPLEMENTED; } - String str; - ord_item->print(&str, QT_ORDINARY); - ord_cols += str.c_ptr(); } - if (ordercol->direction != ORDER::ORDER_ASC) - ord_cols += " desc"; } } @@ -7811,14 +7594,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, if (j == gwi.returnedCols.size()) { - string fullname; - - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - fullname = str.c_ptr(); - sel_cols_in_create += fullname + " `" + escapeBackTick(fullname.c_str()) + "`"; - gwi.returnedCols.push_back(srcp); gwi.columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(string(fieldVec[i]->field_name.str), srcp)); TABLE_LIST* tmp = (fieldVec[i]->cached_table ? fieldVec[i]->cached_table : 0); @@ -7910,230 +7685,22 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, std::ostringstream vtb; vtb << "infinidb_vtable.$vtable_" << gwi.thd->thread_id; - // re-construct the select query and redo phase 1 - if (redo) - { - // select now() from region case. returnedCols should have minSc. - if (sel_cols_in_create.length() == 0) - { - SimpleColumn* sc = dynamic_cast(gwi.returnedCols[0].get()); - - if (sc) - sel_cols_in_create = dynamic_cast(gwi.returnedCols[0].get())->columnName(); - else - sel_cols_in_create = gwi.returnedCols[0]->alias(); - } - - // select * from derived table case - if (gwi.selectCols.empty()) - sel_cols_in_create = " * "; - - create_query = "create temporary table " + vtb.str() + " engine = aria as select " + sel_cols_in_create + " from "; - TABLE_LIST* table_ptr = select_lex.get_table_list(); - - bool firstTb = true; - - // put all tables, derived tables and views on the list - //TABLE_LIST* table_ptr = select_lex.get_table_list(); - set aliasSet; // to avoid duplicate table alias - - for (; table_ptr; table_ptr = table_ptr->next_global) - { - if (string(table_ptr->table_name.str).find("$vtable") != string::npos) - continue; - - if (table_ptr->derived) - { - if (aliasSet.find(table_ptr->alias.str) != aliasSet.end()) - continue; - - String str; - (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); - - if (!firstTb) - create_query += ", "; - - create_query += "(" + string(str.c_ptr()) + ") " + string(table_ptr->alias.str); - firstTb = false; - aliasSet.insert(table_ptr->alias.str); - } - else if (table_ptr->view) - { - if (aliasSet.find(table_ptr->alias.str) != aliasSet.end()) - continue; - - if (!firstTb) - create_query += ", "; - - create_query += string(table_ptr->db.str) + "." + string(table_ptr->table_name.str) + - string(" `") + escapeBackTick(table_ptr->alias.str) + string("`"); - aliasSet.insert(table_ptr->alias.str); - firstTb = false; - } - else - { - // table referenced by view is represented by viewAlias_tableAlias. - // consistent with item.cc field print. - if (table_ptr->referencing_view) - { - if (aliasSet.find(string(table_ptr->referencing_view->alias.str) + "_" + - string(table_ptr->alias.str)) != aliasSet.end()) - continue; - - if (!firstTb) - create_query += ", "; - - create_query += string(table_ptr->db.str) + "." + string(table_ptr->table_name.str) + string(" "); - create_query += string(" `") + - escapeBackTick(table_ptr->referencing_view->alias.str) + "_" + - escapeBackTick(table_ptr->alias.str) + string("`"); - aliasSet.insert(string(table_ptr->referencing_view->alias.str) + "_" + - string(table_ptr->alias.str)); - } - else - { - if (aliasSet.find(table_ptr->alias.str) != aliasSet.end()) - continue; - - if (!firstTb) - create_query += ", "; - - create_query += string(table_ptr->db.str) + "." + string(table_ptr->table_name.str) + string(" "); - create_query += string("`") + escapeBackTick(table_ptr->alias.str) + string("`"); - aliasSet.insert(table_ptr->alias.str); - } - - firstTb = false; - } - } - - - MIGR::infinidb_vtable.create_vtable_query.free(); - MIGR::infinidb_vtable.create_vtable_query.append(create_query.c_str(), create_query.length()); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_REDO_PHASE1; // redo phase 1 - - // turn off select distinct from post process unless there're post process functions - // on the select list. - string sel_query = "select "; - - if (/*join->select_options*/select_lex.options & SELECT_DISTINCT && redo) - sel_query = "select distinct "; - else - sel_query = "select "; - - // select * from derived table... - if (gwi.selectCols.size() == 0) - sel_query += " * "; - - for (uint32_t i = 0; i < gwi.selectCols.size(); i++) - { - sel_query += gwi.selectCols[i]; - - if ( i + 1 != gwi.selectCols.size()) - sel_query += ", "; - } - - select_query.replace(lower_select_query.find("select *"), string("select *").length(), sel_query); - } - else - { - // remove order by clause in case this phase has been executed before. - // need a better fix later, like skip all the other non-optimized phase. - size_t pos = lower_select_query.find("order by"); - - if (pos != string::npos) - select_query.replace(pos, lower_select_query.length() - pos, ""); - - //select_query = "select * from " + vtb.str(); + { if (unionSel) order_list = select_lex.master_unit()->global_parameters()->order_list; ordercol = reinterpret_cast(order_list.first); - ord_cols = ""; for (; ordercol; ordercol = ordercol->next) { Item* ord_item = *(ordercol->item); - - // @bug 1706. re-construct the order by item one by one, because the ord_cols constucted so far - // is for REDO phase. - if (ord_cols.length() != 0) - ord_cols += ", "; - - if (ordercol->in_field_list && ordercol->counter_used) - { - ostringstream oss; - oss << ordercol->counter; - ord_cols += oss.str(); - } - else if (ord_item->type() == Item::NULL_ITEM) - { - // MCOL-793 Do nothing for an ORDER BY NULL - } - else if (ord_item->type() == Item::SUM_FUNC_ITEM) - { - Item_sum* ifp = (Item_sum*)(*(ordercol->item)); - ReturnedColumn* fc = buildAggregateColumn(ifp, gwi); - - for (uint32_t i = 0; i < gwi.returnedCols.size(); i++) - { - if (fc->operator==(gwi.returnedCols[i].get())) - { - ostringstream oss; - oss << i + 1; - ord_cols += oss.str(); - break; - } - } - - //continue; - } - // @bug 3518. if order by clause = selected column, use position. - else if (ord_item->name.length && ord_item->type() == Item::FIELD_ITEM) - { - Item_field* field = reinterpret_cast(ord_item); - string fullname; - - if (field->db_name) - fullname += string(field->db_name) + "."; - - if (field->table_name) - fullname += string(field->table_name) + "."; - - if (field->field_name.length) - fullname += string(field->field_name.str); - - uint32_t i = 0; - - for (i = 0; i < gwi.returnedCols.size(); i++) - { - SimpleColumn* sc = dynamic_cast(gwi.returnedCols[i].get()); - - if (sc && ((Item_field*)ord_item)->cached_table && - (strcasecmp(getViewName(((Item_field*)ord_item)->cached_table).c_str(), sc->viewName().c_str()) != 0)) - continue; - - if (strcasecmp(fullname.c_str(), gwi.returnedCols[i]->alias().c_str()) == 0 || - strcasecmp(ord_item->name.str, gwi.returnedCols[i]->alias().c_str()) == 0) - { - ostringstream oss; - oss << i + 1; - ord_cols += oss.str(); - break; - } - } - - if (i == gwi.returnedCols.size()) - ord_cols += string(" `") + escapeBackTick(ord_item->name.str) + '`'; - } - - else if (ord_item->name.length) + + if (ord_item->name.length) { // for union order by 1 case. For unknown reason, it doesn't show in_field_list if (ord_item->type() == Item::CONST_ITEM && ord_item->cmp_type() == INT_RESULT) { - ord_cols += ord_item->name.str; } else if (ord_item->type() == Item::SUBSELECT_ITEM) { @@ -8143,7 +7710,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } else { - ord_cols += string(" `") + escapeBackTick(ord_item->name.str) + '`'; } } else if (ord_item->type() == Item::FUNC_ITEM) @@ -8157,7 +7723,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, { ostringstream oss; oss << i + 1; - ord_cols += oss.str(); break; } } @@ -8166,25 +7731,19 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, { String str; ord_item->print(&str, QT_ORDINARY); - ord_cols += string(str.c_ptr()); } - if (ordercol->direction != ORDER::ORDER_ASC) - ord_cols += " desc"; } } - if (ord_cols.length() > 0) // has order by + if ( gwi.orderByCols.size() ) // has order by { - MIGR::infinidb_vtable.has_order_by = true; csep->hasOrderBy(true); // To activate LimitedOrderBy if(isPushdownHand) { csep->specHandlerProcessed(true); } - ord_cols = " order by " + ord_cols; - select_query += ord_cols; } } @@ -8208,14 +7767,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, 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(); - } } } // union with explicit select at the top level @@ -8294,12 +7845,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, csep->limitStart(limitOffset); csep->limitNum(limitNum); } - else - { - ostringstream limit; - limit << " limit " << limitOffset << ", " << limitNum; - select_query += limit.str(); - } } // Pushdown queries with ORDER BY w/o explicit limit else if (isPushdownHand && csep->hasOrderBy()) @@ -8308,9 +7853,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, csep->limitNum((uint64_t) - 2); } - MIGR::infinidb_vtable.select_vtable_query.free(); - MIGR::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()) @@ -8641,9 +8183,10 @@ ConstantColumn* buildConstColFromFilter(SimpleColumn* originalSC, continue; op = simpFilter->op(); + execplan::ReturnedColumn* rc = dynamic_cast(simpleCol); - if ( originalSC->sameColumn(dynamic_cast(simpleCol)) - && op.get()->op() == OP_EQ && constCol) + // The filter could have any kind of op + if ( originalSC->sameColumn(rc) ) { #ifdef DEBUG_WALK_COND cerr << "buildConstColFromFilter() replaced " << endl; @@ -8757,7 +8300,8 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); SELECT_LEX* select_cursor = table_ptr->derived->first_select(); - FromSubQuery fromSub(gwi, select_cursor); + // Use Pushdown handler for subquery processing + FromSubQuery fromSub(gwi, select_cursor, true); string alias(table_ptr->alias.str); fromSub.alias(lower(alias)); @@ -8970,8 +8514,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro List_iterator_fast it(*gi.groupByFields); Item* item; vector funcFieldVec; - string sel_cols_in_create; - string sel_cols_in_select; bool redo = false; // empty rcWorkStack and ptWorkStack. They should all be empty by now. @@ -9031,18 +8573,13 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro boost::shared_ptr spcc(constCol); boost::shared_ptr spsc(sc); - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - string fullname; String str; ifp->print(&str, QT_ORDINARY); fullname = str.c_ptr(); - //sel_cols_in_create += fullname; if (ifp->is_autogenerated_name) // no alias { - sel_cols_in_create += fullname + " `" + escapeBackTick(str.c_ptr()) + "`"; sc->alias(fullname); } else // alias @@ -9050,7 +8587,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro if (!itemAlias.empty()) sc->alias(itemAlias); - sel_cols_in_create += fullname + " `" + escapeBackTick(sc->alias().c_str()) + "`"; } if (ifp->is_autogenerated_name) @@ -9113,10 +8649,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro String str(256); item->print(&str, QT_ORDINARY); - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += string(str.c_ptr()) + " `" + escapeBackTick(spac->alias().c_str()) + "`"; break; } @@ -9202,10 +8734,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro String str(256); ifp->print(&str, QT_ORDINARY); - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += string(str.c_ptr()) + " `" + ifp->name.str + "`"; gwi.selectCols.push_back("`" + escapeBackTick(ifp->name.str) + "`"); } } @@ -9346,10 +8874,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro ostringstream oss; oss << isp->value << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += oss.str(); gwi.selectCols.push_back(oss.str()); } @@ -9374,10 +8898,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro valStr.assign(str->ptr(), str->length()); string name = "'" + valStr + "'" + " " + "`" + escapeBackTick(srcp->alias().c_str()) + "`"; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += name; gwi.selectCols.push_back(name); } @@ -9403,10 +8923,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro ostringstream oss; oss << valStr.c_str() << " `" << escapeBackTick(srcp->alias().c_str()) << "`"; - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - - sel_cols_in_create += oss.str(); gwi.selectCols.push_back(oss.str()); } @@ -9497,19 +9013,13 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro rc->alias(sub->name.str); gwi.returnedCols.push_back(SRCP(rc)); - String str; - sub->get_select_lex()->print(gwi.thd, &str, QT_ORDINARY); - sel_cols_in_create += "(" + string(str.c_ptr()) + ")"; if (sub->name.length) { - sel_cols_in_create += "`" + escapeBackTick(sub->name.str) + "`"; gwi.selectCols.push_back(sub->name.str); } else { - sel_cols_in_create += "`" + escapeBackTick(str.c_ptr()) + "`"; - gwi.selectCols.push_back("`" + escapeBackTick(str.c_ptr()) + "`"); } break; @@ -9689,12 +9199,8 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro gwi.returnedCols.push_back(srcp); gwi.columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(string(funcFieldVec[i]->field_name.str), srcp)); - if (sel_cols_in_create.length() != 0) - sel_cols_in_create += ", "; - string fullname; fullname = str.c_ptr(); - sel_cols_in_create += fullname + " `" + escapeBackTick(fullname.c_str()) + "`"; TABLE_LIST* tmp = (funcFieldVec[i]->cached_table ? funcFieldVec[i]->cached_table : 0); gwi.tableMap[make_aliastable(sc->schemaName(), sc->tableName(), sc->tableAlias(), sc->isInfiniDB())] = make_pair(1, tmp); @@ -9993,12 +9499,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) { ORDER* ordercol = reinterpret_cast(gi.groupByOrder); - string create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); - string select_query(MIGR::infinidb_vtable.select_vtable_query.c_ptr()); - string lower_create_query(MIGR::infinidb_vtable.create_vtable_query.c_ptr()); - string lower_select_query(MIGR::infinidb_vtable.select_vtable_query.c_ptr()); - boost::algorithm::to_lower(lower_create_query); - boost::algorithm::to_lower(lower_select_query); // check if window functions are in order by. InfiniDB process order by list if @@ -10235,30 +9735,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro std::ostringstream vtb; vtb << "infinidb_vtable.$vtable_" << gwi.thd->thread_id; - //vtb << "$vtable_" << gwi.thd->thread_id; // re-construct the select query and redo phase 1 if (redo) { - // select now() from region case. returnedCols should have minSc. - if (sel_cols_in_create.length() == 0) - { - SimpleColumn* sc = dynamic_cast(gwi.returnedCols[0].get()); - - if (sc) - sel_cols_in_create = dynamic_cast(gwi.returnedCols[0].get())->columnName(); - else - sel_cols_in_create = gwi.returnedCols[0]->alias(); - } - - // select * from derived table case - if (gwi.selectCols.empty()) - sel_cols_in_create = " * "; - - create_query = "create temporary table " + vtb.str() + " engine = aria as select " + sel_cols_in_create + " from "; TABLE_LIST* table_ptr = gi.groupByTables; - bool firstTb = true; - // put all tables, derived tables and views on the list //TABLE_LIST* table_ptr = select_lex.get_table_list(); set aliasSet; // to avoid duplicate table alias @@ -10273,14 +9754,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro if (aliasSet.find(table_ptr->alias.str) != aliasSet.end()) continue; - String str; - (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); - - if (!firstTb) - create_query += ", "; - - create_query += "(" + string(str.c_ptr()) + ") " + string(table_ptr->alias.str); - firstTb = false; aliasSet.insert(table_ptr->alias.str); } else if (table_ptr->view) @@ -10288,13 +9761,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro if (aliasSet.find(table_ptr->alias.str) != aliasSet.end()) continue; - if (!firstTb) - create_query += ", "; - - create_query += string(table_ptr->db.str) + "." + string(table_ptr->table_name.str) + - string(" `") + escapeBackTick(table_ptr->alias.str) + string("`"); aliasSet.insert(table_ptr->alias.str); - firstTb = false; } else { @@ -10306,13 +9773,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro string(table_ptr->alias.str)) != aliasSet.end()) continue; - if (!firstTb) - create_query += ", "; - - create_query += string(table_ptr->db.str) + "." + string(table_ptr->table_name.str) + string(" "); - create_query += string(" `") + - escapeBackTick(table_ptr->referencing_view->alias.str) + "_" + - escapeBackTick(table_ptr->alias.str) + string("`"); aliasSet.insert(string(table_ptr->referencing_view->alias.str) + "_" + string(table_ptr->alias.str)); } @@ -10321,83 +9781,31 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro if (aliasSet.find(table_ptr->alias.str) != aliasSet.end()) continue; - if (!firstTb) - create_query += ", "; - - create_query += string(table_ptr->db.str) + "." + string(table_ptr->table_name.str) + string(" "); - create_query += string("`") + escapeBackTick(table_ptr->alias.str) + string("`"); aliasSet.insert(table_ptr->alias.str); } - firstTb = false; } } - - MIGR::infinidb_vtable.create_vtable_query.free(); - MIGR::infinidb_vtable.create_vtable_query.append(create_query.c_str(), create_query.length()); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_REDO_PHASE1; // redo phase 1 - - // turn off select distinct from post process unless there're post process functions - // on the select list. - string sel_query = "select "; - - if (gi.groupByDistinct && redo) - sel_query = "select distinct "; - else - sel_query = "select "; - - // select * from derived table... - if (gwi.selectCols.size() == 0) - sel_query += " * "; - - for (uint32_t i = 0; i < gwi.selectCols.size(); i++) - { - sel_query += gwi.selectCols[i]; - - if ( i + 1 != gwi.selectCols.size()) - sel_query += ", "; - } - - //select_query.replace(lower_select_query.find("select *"), string("select *").length(), sel_query); } else { // remove order by clause in case this phase has been executed before. // need a better fix later, like skip all the other non-optimized phase. - size_t pos = lower_select_query.find("order by"); - if (pos != string::npos) - select_query.replace(pos, lower_select_query.length() - pos, ""); - - //select_query = "select * from " + vtb.str(); // MCOL-1052 if (unionSel) { ordercol = reinterpret_cast(gi.groupByOrder); - //order_list = gi.groupByOrder; } else ordercol = 0; - ord_cols = ""; - for (; ordercol; ordercol = ordercol->next) { Item* ord_item = *(ordercol->item); - // @bug 1706. re-construct the order by item one by one, because the ord_cols constucted so far - // is for REDO phase. - if (ord_cols.length() != 0) - ord_cols += ", "; - - if (ordercol->in_field_list && ordercol->counter_used) - { - ostringstream oss; - oss << ordercol->counter; - ord_cols += oss.str(); - } - else if (ord_item->type() == Item::NULL_ITEM) + if (ord_item->type() == Item::NULL_ITEM) { // MCOL-793 Do nothing for an ORDER BY NULL } @@ -10507,7 +9915,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro if ( gwi.orderByCols.size() ) // has order by { - MIGR::infinidb_vtable.has_order_by = true; csep->hasOrderBy(true); csep->specHandlerProcessed(true); } @@ -10534,10 +9941,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro csep->limitStart(((Item_int*)gi.groupByTables->select_lex->offset_limit)->val_int()); } - // WIP MCOL-2178 - //MIGR::infinidb_vtable.select_vtable_query.free(); - //MIGR::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()) diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 8fe27ea0d..fb4e6bffa 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -1515,7 +1515,6 @@ uint32_t doUpdateDelete(THD* thd) setError(thd, ER_INTERNAL_ERROR, logging::IDBErrorInfo::instance()->errorMsg(ERR_WF_UPDATE)); return ER_CHECK_NOT_IMPLEMENTED; - //return 0; } else { @@ -1594,7 +1593,6 @@ uint32_t doUpdateDelete(THD* thd) } catch (IDBExcept& ie) { -// setError(thd, ER_UNKNOWN_TABLE, ie.what()); setError(thd, ER_INTERNAL_ERROR, ie.what()); return ER_INTERNAL_ERROR; } @@ -1710,7 +1708,7 @@ uint32_t doUpdateDelete(THD* thd) //@Bug 2808 Error out on order by or limit clause //@bug5096. support dml limit. - if (/*( thd->lex->first_select_lex()->explicit_limit ) || */( thd->lex->first_select_lex()->order_list.elements != 0 ) ) + if (( thd->lex->first_select_lex()->order_list.elements != 0 ) ) { string emsg("DML Statement with order by clause is not currently supported."); thd->raise_error_printf(ER_INTERNAL_ERROR, emsg.c_str()); @@ -2348,20 +2346,10 @@ int ha_calpont_impl_rnd_init(TABLE* table) 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 (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE && - string(table->s->table_name.str).find("$vtable") != 0) - return 0; - // return error is error status is already set if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) return ER_INTERNAL_ERROR; - // by pass the extra union trips. return 0 - if (MIGR::infinidb_vtable.isUnion && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) - return 0; - // @bug 2232. Basic SP support. Error out non support sp cases. // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) @@ -2371,11 +2359,6 @@ int ha_calpont_impl_rnd_init(TABLE* table) return ER_INTERNAL_ERROR; } - // mysql reads table twice for order by - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1 || - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY) - return 0; - if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) return 0; @@ -2392,12 +2375,6 @@ int ha_calpont_impl_rnd_init(TABLE* table) idbassert(ci != 0); - // MySQL sometimes calls rnd_init multiple times, plan should only be - // generated and sent once. - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE && - !MIGR::infinidb_vtable.isNewQuery) - return 0; - if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) { force_close_fep_conn(thd, ci); @@ -2491,7 +2468,13 @@ int ha_calpont_impl_rnd_init(TABLE* table) // 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)); + } + else + { + ti.csep->data(""); + } } // vtable mode else @@ -2595,6 +2578,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) return 0; // @bug 2547. don't need to send the plan if it's impossible where for all unions. + // WIP MCOL-2178 This singleton attribute could be a problem if (MIGR::infinidb_vtable.impossibleWhereOnUnion) return 0; @@ -3115,10 +3099,6 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) ti.tpl_ctx = 0; - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE && - MIGR::infinidb_vtable.has_order_by) - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ORDER_BY; - ci->tableMap[table] = ti; // push warnings from CREATE phase @@ -4158,15 +4138,6 @@ int ha_calpont_impl_commit (handlerton* hton, THD* thd, bool all) int ha_calpont_impl_rollback (handlerton* hton, THD* thd, bool all) { - // @bug 1738. no need to rollback for select. This is to avoid concurrent session - // conflict because DML is not thread safe. - //comment out for bug 3874. Select should never come to rollback. If there is no active transaction, - //rollback in DMLProc is not doing anything anyway - //if (!(current_thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) - //{ - // return 0; - //} - if (get_fe_conn_info_ptr() == NULL) set_fe_conn_info_ptr((void*)new cal_connection_info()); @@ -4176,7 +4147,6 @@ int ha_calpont_impl_rollback (handlerton* hton, THD* thd, bool all) { ci->dmlProc = new MessageQueueClient("DMLProc"); - //cout << "rollback starts a client " << ci->dmlProc << " for session " << thd->thread_id << endl; } int rc = ha_calpont_impl_rollback_(hton, thd, all, *ci); @@ -4225,6 +4195,8 @@ int ha_calpont_impl_close_connection (handlerton* hton, THD* thd) ci->cal_conn_hndl = 0; } + thd_set_ha_data(thd, hton, NULL); + return rc; } @@ -4357,12 +4329,6 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) string alias; alias.assign(table->alias.ptr(), table->alias.length()); IDEBUG( cout << "external_lock for " << alias << endl ); - idbassert((MIGR::infinidb_vtable.vtable_state >= MIGR::INFINIDB_INIT_CONNECT && - MIGR::infinidb_vtable.vtable_state <= MIGR::INFINIDB_REDO_QUERY) || - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR); - - if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT ) - return 0; if (get_fe_conn_info_ptr() == NULL) set_fe_conn_info_ptr((void*)new cal_connection_info()); @@ -4371,18 +4337,15 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) { + ci->physTablesList.clear(); + ci->tableMap.clear(); force_close_fep_conn(thd, ci); return 0; } - CalTableMap::iterator mapiter = ci->tableMap.find(table); -#ifdef _MSC_VER - //FIXME: fix this! (must be related to F_UNLCK define in winport) - if (mapiter != ci->tableMap.end() && lock_type == 0) // make sure it's the release lock (2nd) call -#else + CalTableMap::iterator mapiter = ci->tableMap.find(table); if (mapiter != ci->tableMap.end() && lock_type == 2) // make sure it's the release lock (2nd) call -#endif { // table mode if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) @@ -4411,11 +4374,26 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) { push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, infinidb_autoswitch_warning.c_str()); } + // MCOL-2178 Check for tableMap size to set this only once. ci->queryState = 0; } - else // vtable mode + ci->tableMap.erase(table); + } + else + { + if (lock_type == 0) { - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE) + ci->physTablesList.insert(table); + } + else if (lock_type == 2) + { + std::set::iterator iter = ci->physTablesList.find(table); + if ( iter != ci->physTablesList.end() ) + { + ci->physTablesList.erase(table); + } + + if ( iter != ci->physTablesList.end() && ci->physTablesList.empty() ) { if (!ci->cal_conn_hndl) return 0; @@ -4430,11 +4408,11 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) MIGR::infinidb_vtable.override_largeside_estimate = false; // MCOL-3247 Use THD::ha_data as a per-plugin per-session // storage for cal_conn_hndl to use it later in close_connection - thd_set_ha_data(thd, calpont_hton, get_fe_conn_info_ptr()); + thd_set_ha_data(thd, mcs_hton, get_fe_conn_info_ptr()); + ci->tableMap.clear(); } - } - ci->tableMap.erase(table); + } } return 0; @@ -4495,11 +4473,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) return ER_INTERNAL_ERROR; - // MCOL-1052 - // by pass the extra union trips. return 0 - //if (MIGR::infinidb_vtable.isUnion && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) - // return 0; - // @bug 2232. Basic SP support. Error out non support sp cases. // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) @@ -4521,12 +4494,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE idbassert(ci != 0); - // MySQL sometimes calls rnd_init multiple times, plan should only be - // generated and sent once. - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE && - !MIGR::infinidb_vtable.isNewQuery) - return 0; - if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) { force_close_fep_conn(thd, ci); @@ -4660,6 +4627,7 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE // send plan whenever group_init is called int status = cp_get_group_plan(thd, csep, gi); + // WIP MCOL-2178 This could be a problem if (status > 0) goto internal_error; else if (status < 0) @@ -5271,7 +5239,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) //check whether the system is ready to process statement. #ifndef _MSC_VER static DBRM dbrm(true); - bool bSystemQueryReady = dbrm.getSystemQueryReady(); + int bSystemQueryReady = dbrm.getSystemQueryReady(); if (bSystemQueryReady == 0) { @@ -5299,18 +5267,6 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) // prevent "create table as select" from running on slave MIGR::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; - // return error is error status is already set if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) return ER_INTERNAL_ERROR; @@ -5327,10 +5283,14 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) // mysql reads table twice for order by if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1 || MIGR::infinidb_vtable.vtable_state == MIGR::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)) @@ -5347,12 +5307,6 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) idbassert(ci != 0); - // MySQL sometimes calls rnd_init multiple times, plan should only be - // generated and sent once. - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE && - !MIGR::infinidb_vtable.isNewQuery) - return 0; - if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) { if (ci->cal_conn_hndl) @@ -5495,17 +5449,19 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) dh = reinterpret_cast(handler_info->hndl_ptr); status = cs_get_derived_plan(dh, thd, csep); } + + std::cout << "pushdown_init get_plan status " << status << std::endl; - // WIP MCOL-2121 Find a way to return an actual error - // It either ends up with 42 or other error status - if (status > 0) + // Return an error to avoid MDB crash later in end_statement + if (status != 0) goto internal_error; - else if (status < 0) - return 0; + std::cout << "pushdown_init impossibleWhereOnUnion " << status << std::endl; // @bug 2547. don't need to send the plan if it's impossible where for all unions. if (MIGR::infinidb_vtable.impossibleWhereOnUnion) + { return 0; + } string query; query.assign(idb_mysql_query_str(thd)); diff --git a/dbcon/mysql/ha_from_sub.cpp b/dbcon/mysql/ha_from_sub.cpp index 94f4e1d18..2c2a12ec5 100644 --- a/dbcon/mysql/ha_from_sub.cpp +++ b/dbcon/mysql/ha_from_sub.cpp @@ -322,9 +322,12 @@ ParseTree* setDerivedFilter(THD* thd, ParseTree*& n, FromSubQuery::FromSubQuery(gp_walk_info& gwip) : SubQuery(gwip) {} -FromSubQuery::FromSubQuery(gp_walk_info& gwip, SELECT_LEX* sub) : - SubQuery(gwip), - fFromSub(sub) +FromSubQuery::FromSubQuery(gp_walk_info& gwip, + SELECT_LEX* sub, + bool isPushdownHandler) : + SubQuery(gwip), + fFromSub(sub), + fPushdownHand(isPushdownHandler) {} FromSubQuery::~FromSubQuery() @@ -345,7 +348,7 @@ SCSEP FromSubQuery::transform() gwi.viewName = fGwip.viewName; csep->derivedTbAlias(fAlias); // always lower case - if (getSelectPlan(gwi, *fFromSub, csep) != 0) + if (getSelectPlan(gwi, *fFromSub, csep, fPushdownHand) != 0) { fGwip.fatalParseError = true; diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp index 489751795..93a3fee23 100644 --- a/dbcon/mysql/ha_mcs_pushdown.cpp +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -210,33 +210,9 @@ static derived_handler* create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived) { ha_columnstore_derived_handler* handler = NULL; - handlerton *ht= 0; SELECT_LEX_UNIT *unit= derived->derived; - /* //if ( MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE ) -// WIP MCOL-2178 -// && MIGR::infinidb_vtable_mode != 0 ) - { - return 0; - }*/ - - for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) - { - if (!(sl->join)) - return 0; - for (TABLE_LIST *tbl= sl->join->tables_list; tbl; tbl= tbl->next_local) - { - if (!tbl->table) - return 0; - // Same handlerton type check. - if (!ht) - ht= tbl->table->file->partition_ht(); - else if (ht != tbl->table->file->partition_ht()) - return 0; - } - } - bool unsupported_feature = false; { SELECT_LEX select_lex = *unit->first_select(); @@ -253,7 +229,7 @@ create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived) if ( icp ) { - icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); + //icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); } } @@ -470,36 +446,21 @@ static select_handler* create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) { ha_columnstore_select_handler* handler = NULL; - handlerton *ht= 0; - - /* - // Return if vtable enabled. - //if ( MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE ) -// WIP MCOL-2178 -// && MIGR::infinidb_vtable_mode != 0 ) - { - return 0; - }*/ - - for (SELECT_LEX* sl = select_lex;sl; sl= sl->next_select()) - { - if (!(sl->join)) - return 0; - for (TABLE_LIST *tbl= sl->join->tables_list; tbl; tbl= tbl->next_local) - { - if (!tbl->table) - return 0; - // Same handlerton type check. - if (!ht) - ht= tbl->table->file->partition_ht(); - else if (ht != tbl->table->file->partition_ht()) - return 0; - } - } bool unsupported_feature = false; + // Select_handler use the short-cut that effectively disables + // INSERT..SELECT and LDI + if ( (thd->lex)->sql_command == SQLCOM_INSERT_SELECT + || (thd->lex)->sql_command == SQLCOM_CREATE_TABLE ) + + { + unsupported_feature = true; + } + // Impossible HAVING or WHERE - if ( ( select_lex->having && select_lex->having_value == Item::COND_FALSE ) + // WIP replace with function call + if ( unsupported_feature + || ( select_lex->having && select_lex->having_value == Item::COND_FALSE ) || ( select_lex->cond_count > 0 && select_lex->cond_value == Item::COND_FALSE ) ) { @@ -521,7 +482,7 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) if ( where_icp ) { - where_icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); + //where_icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); } // Looking for JOIN with ON expression through @@ -532,7 +493,7 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) if(table_ptr->on_expr) { on_icp = reinterpret_cast(table_ptr->on_expr); - on_icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); + //on_icp->traverse_cond(check_walk, &unsupported_feature, Item::POSTFIX); } } @@ -543,7 +504,7 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) unsupported_feature = true; } } - + if (!unsupported_feature) { handler = new ha_columnstore_select_handler(thd, select_lex); @@ -571,7 +532,8 @@ ha_columnstore_select_handler::ha_columnstore_select_handler(THD *thd, * select_handler constructor ***********************************************************/ ha_columnstore_select_handler::~ha_columnstore_select_handler() -{} +{ +} /*@brief Initiate the query for select_handler */ /*********************************************************** diff --git a/dbcon/mysql/ha_subquery.h b/dbcon/mysql/ha_subquery.h index b008b4fcd..b201e2fe3 100644 --- a/dbcon/mysql/ha_subquery.h +++ b/dbcon/mysql/ha_subquery.h @@ -45,7 +45,10 @@ namespace cal_impl_if class SubQuery { public: - SubQuery(gp_walk_info& gwip) : fGwip(gwip), fCorrelated(false) {} + SubQuery(gp_walk_info& gwip) : + fGwip(gwip), + fCorrelated(false) + {} virtual ~SubQuery() {} virtual gp_walk_info& gwip() const { @@ -178,7 +181,7 @@ class FromSubQuery : public SubQuery { public: FromSubQuery(gp_walk_info&); - FromSubQuery(gp_walk_info&, SELECT_LEX* fromSub); + FromSubQuery(gp_walk_info&, SELECT_LEX* fromSub, bool isPushdownHand=false); ~FromSubQuery(); const SELECT_LEX* fromSub() const { @@ -200,6 +203,7 @@ public: private: SELECT_LEX* fFromSub; std::string fAlias; + bool fPushdownHand; }; class SelectSubQuery : public SubQuery From a9c72675ba703662c76e7de109491e6e580631dd Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Tue, 11 Jun 2019 00:36:16 +0300 Subject: [PATCH 08/11] MCOL-2178 Fixed MDB crash with setError() operating with empty gwi. FromSubQuery() is no pushdown aware. Actualize OUTER_JOIN_DEBUG section in ha_calpont_execplan.cpp to be used with 10.4. Enabled derivedTableOptimization() for select handler. --- dbcon/ddlpackage/CMakeLists.txt | 3 - dbcon/mysql/ha_calpont_execplan.cpp | 88 +++++++++++++++-------------- dbcon/mysql/ha_calpont_impl.cpp | 2 +- 3 files changed, 46 insertions(+), 47 deletions(-) diff --git a/dbcon/ddlpackage/CMakeLists.txt b/dbcon/ddlpackage/CMakeLists.txt index 084aeeac0..8bdc68b1e 100644 --- a/dbcon/ddlpackage/CMakeLists.txt +++ b/dbcon/ddlpackage/CMakeLists.txt @@ -11,9 +11,6 @@ ADD_CUSTOM_COMMAND( set_source_files_properties(ddl-scan.cpp PROPERTIES COMPILE_FLAGS -Wno-sign-compare) -# Parser puts extra info to stderr. -MY_CHECK_AND_SET_COMPILER_FLAG("-DYYDEBUG=1" DEBUG) - ########### next target ############### ADD_LIBRARY(ddlpackage SHARED diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 243f2164c..3526a2175 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -5399,7 +5399,7 @@ void gp_walk(const Item* item, void* arg) { vector fieldVec; uint16_t parseInfo = 0; - parse_item(it, fieldVec, gwip->fatalParseError, parseInfo); + parse_item(it, fieldVec, gwip->fatalParseError, parseInfo, gwip); if (parseInfo & CORRELATED) { @@ -5794,7 +5794,6 @@ void parse_item (Item* item, vector& field_vec, for (uint32_t i = 0; i < isp->argument_count(); i++) parse_item(isp->arguments()[i], field_vec, hasNonSupportItem, parseInfo, gwi); -// parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); break; } @@ -5805,7 +5804,7 @@ void parse_item (Item* item, vector& field_vec, Item* cond_item; while ((cond_item = it++)) - parse_item(cond_item, field_vec, hasNonSupportItem, parseInfo); + parse_item(cond_item, field_vec, hasNonSupportItem, parseInfo, gwi); break; } @@ -6086,7 +6085,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); SELECT_LEX* select_cursor = table_ptr->derived->first_select(); - FromSubQuery fromSub(gwi, select_cursor, isPushdownHand); + FromSubQuery fromSub(gwi, select_cursor, false, isPushdownHand); string alias(table_ptr->alias.str); fromSub.alias(lower(alias)); @@ -6289,62 +6288,63 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, #ifdef OUTER_JOIN_DEBUG List* tables = &(select_lex.top_join_list); List_iterator_fast ti(*tables); - //TABLE_LIST *inner; - //TABLE_LIST **table= (TABLE_LIST **)gwi.thd->alloc(sizeof(TABLE_LIST*) * tables->elements); - //for (TABLE_LIST **t= table + (tables->elements - 1); t >= table; t--) - // *t= ti++; - //DBUG_ASSERT(tables->elements >= 1); + TABLE_LIST **table= (TABLE_LIST **)gwi.thd->alloc(sizeof(TABLE_LIST*) * tables->elements); + for (TABLE_LIST **t= table + (tables->elements - 1); t >= table; t--) + *t= ti++; - //TABLE_LIST **end= table + tables->elements; - //for (TABLE_LIST **tbl= table; tbl < end; tbl++) - TABLE_LIST* curr; + DBUG_ASSERT(tables->elements >= 1); - while ((curr = ti++)) + TABLE_LIST **end= table + tables->elements; + for (TABLE_LIST **tbl= table; tbl < end; tbl++) { - TABLE_LIST* curr = *tbl; + TABLE_LIST* curr; - if (curr->table_name) - cerr << curr->table_name << " "; - else - cerr << curr->alias << endl; - - if (curr->outer_join) - cerr << " is inner table" << endl; - else if (curr->straight) - cerr << "straight_join" << endl; - else - cerr << "join" << endl; - - if (curr->nested_join) + while ((curr = ti++)) { - List* inners = &(curr->nested_join->join_list); - List_iterator_fast li(*inners); - TABLE_LIST** inner = (TABLE_LIST**)gwi.thd->alloc(sizeof(TABLE_LIST*) * inners->elements); + TABLE_LIST* curr = *tbl; - for (TABLE_LIST** t = inner + (inners->elements - 1); t >= inner; t--) - *t = li++; + if (curr->table_name.length) + cerr << curr->table_name.str << " "; + else + cerr << curr->alias.str << endl; - TABLE_LIST** end1 = inner + inners->elements; + if (curr->outer_join) + cerr << " is inner table" << endl; + else if (curr->straight) + cerr << "straight_join" << endl; + else + cerr << "join" << endl; - for (TABLE_LIST** tb = inner; tb < end1; tb++) + if (curr->nested_join) { - TABLE_LIST* curr1 = *tb; - cerr << curr1->alias << endl; + List* inners = &(curr->nested_join->join_list); + List_iterator_fast li(*inners); + TABLE_LIST** inner = (TABLE_LIST**)gwi.thd->alloc(sizeof(TABLE_LIST*) * inners->elements); - if (curr1->sj_on_expr) + for (TABLE_LIST** t = inner + (inners->elements - 1); t >= inner; t--) + *t = li++; + + TABLE_LIST** end1 = inner + inners->elements; + + for (TABLE_LIST** tb = inner; tb < end1; tb++) { - curr1->sj_on_expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); + TABLE_LIST* curr1 = *tb; + cerr << curr1->alias.str << endl; + + if (curr1->sj_on_expr) + { + curr1->sj_on_expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); + } } } - } - if (curr->sj_on_expr) - { - curr->sj_on_expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); + if (curr->sj_on_expr) + { + curr->sj_on_expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); + } } } - #endif uint32_t failed = buildOuterJoin(gwi, select_lex); @@ -8137,6 +8137,8 @@ int cs_get_select_plan(select_handler* handler, THD* thd, SCSEP& csep) cerr << *csep << endl ; cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; #endif + // Derived table projection and filter optimization. + derivedTableOptimization(csep); return 0; } diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index fb4e6bffa..c7c15ec8e 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -1757,7 +1757,7 @@ uint32_t doUpdateDelete(THD* thd) gwi.clauseType = WHERE; - if (getSelectPlan(gwi, select_lex, updateCP) != 0) //@Bug 3030 Modify the error message for unsupported functions + if (getSelectPlan(gwi, select_lex, updateCP, false, true) != 0) //@Bug 3030 Modify the error message for unsupported functions { if (MIGR::infinidb_vtable.isUpdateWithDerive) { From 7d5275e1bd70fd278d8b44553bd4a42259906c01 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Mon, 15 Jul 2019 21:58:45 +0300 Subject: [PATCH 09/11] MCOL-2178 CS now doesn't initiate a scan when MDB explicitly set scan to false in rnd_init(). sortItemIsInGroupRec() now has a base case for Item_Field and this prevents unbound recursion. Fixes fromSub() call with incorrect number of arguments. CS now doesn't ask for statistics unless a user explicitly asks for it using calsettrace(). --- dbcon/mysql/ha_calpont.cpp | 6 ++- dbcon/mysql/ha_calpont_execplan.cpp | 6 ++- dbcon/mysql/ha_calpont_impl.cpp | 10 +++- dbcon/mysql/sm.cpp | 84 +++++++++++++++-------------- dbcon/mysql/sm.h | 2 +- 5 files changed, 62 insertions(+), 46 deletions(-) diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index 19c37fd73..50b69c297 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -527,7 +527,11 @@ int ha_calpont::rnd_init(bool scan) { DBUG_ENTER("ha_calpont::rnd_init"); - int rc = ha_calpont_impl_rnd_init(table); + int rc = 0; + if(scan) + { + rc = ha_calpont_impl_rnd_init(table); + } DBUG_RETURN(rc); } diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 3526a2175..e5c58cdcb 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -273,6 +273,10 @@ bool sortItemIsInGroupRec(Item* sort_item, Item* group_item) Item_ref* ifp_sort_ref = reinterpret_cast(sort_item); found = sortItemIsInGroupRec(*ifp_sort_ref->ref, group_item); } + else if (!found && sort_item->type() == Item::FIELD_ITEM) + { + return found; + } // seeking for a group_item match for (uint32_t i = 0; !found && i < ifp_sort->argument_count(); i++) @@ -6085,7 +6089,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, (table_ptr->derived->first_select())->print(gwi.thd, &str, QT_ORDINARY); SELECT_LEX* select_cursor = table_ptr->derived->first_select(); - FromSubQuery fromSub(gwi, select_cursor, false, isPushdownHand); + FromSubQuery fromSub(gwi, select_cursor, isPushdownHand); string alias(table_ptr->alias.str); fromSub.alias(lower(alias)); diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index c7c15ec8e..83cddcb4c 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -3062,7 +3062,10 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) try { - sm::tpl_close(ti.tpl_ctx, &hndl, ci->stats); + { + bool ask_4_stats = (ci->traceFlags) ? true : false; + sm::tpl_close(ti.tpl_ctx, &hndl, ci->stats, ask_4_stats); + } // set conn hndl back. could be changed in tpl_close if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) @@ -5124,7 +5127,10 @@ int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, TABLE* { if(hndl) { - sm::tpl_close(ti.tpl_ctx, &hndl, ci->stats, clearScanCtx); + { + bool ask_4_stats = (ci->traceFlags) ? true : false; + sm::tpl_close(ti.tpl_ctx, &hndl, ci->stats, ask_4_stats, clearScanCtx); + } // Normaly stats variables are set in external_lock method but we set it here // since they we pretend we are in vtable_disabled mode and the stats vars won't be set. // We sum the stats up here since server could run a number of diff --git a/dbcon/mysql/sm.cpp b/dbcon/mysql/sm.cpp index 5df01dda6..8dc5c0414 100644 --- a/dbcon/mysql/sm.cpp +++ b/dbcon/mysql/sm.cpp @@ -373,17 +373,16 @@ status_t tpl_close ( cpsm_tplh_t* ntplh, cpsm_conhdl_t** conn_hdl, QueryStats& stats, + bool ask_4_stats, bool clear_scan_ctx) { cpsm_conhdl_t* hndl = *conn_hdl; -#if IDB_SM_DEBUG SMDEBUGLOG << "tpl_close: hndl" << hndl << " ntplh " << ntplh; if (ntplh) SMDEBUGLOG << " tableid: " << ntplh->tableid; SMDEBUGLOG << endl; -#endif delete ntplh; // determine end of result set and end of statement execution @@ -391,57 +390,60 @@ tpl_close ( cpsm_tplh_t* ntplh, { // Get the query stats ByteStream bs; - ByteStream::quadbyte qb = 3; - bs << qb; - hndl->write(bs); - + // Ask for a stats only if a user explicitly asks + if(ask_4_stats) + { + ByteStream::quadbyte qb = 3; + bs << qb; + hndl->write(bs); + } // MCOL-1601 Dispose of unused empty RowGroup if (clear_scan_ctx) { + std::cout << "tpl_close() clear_scan_ctx read" << std::endl; bs = hndl->exeMgr->read(); } -#if IDB_SM_DEBUG SMDEBUGLOG << "tpl_close hndl->exeMgr: " << hndl->exeMgr << endl; -#endif //keep reading until we get a string - //TODO: really need to fix this! Why is ExeMgr sending other stuff? - for (int tries = 0; tries < 10; tries++) + // Ask for a stats only if a user explicitly asks + if(ask_4_stats) { - bs = hndl->exeMgr->read(); + for (int tries = 0; tries < 10; tries++) + { + bs = hndl->exeMgr->read(); - if (bs.length() == 0) break; + if (bs.length() == 0) break; - try - { - bs >> hndl->queryStats; - bs >> hndl->extendedStats; - bs >> hndl->miniStats; - stats.unserialize(bs); - stats.setEndTime(); - stats.insert(); - break; + try + { + bs >> hndl->queryStats; + bs >> hndl->extendedStats; + bs >> hndl->miniStats; + stats.unserialize(bs); + stats.setEndTime(); + stats.insert(); + break; + } + catch (IDBExcept&) + { + // @bug4732 + end_query(hndl); + throw; + } + catch (...) + { + // querystats messed up. close connection. + // no need to throw for querystats protocol error, like for tablemode. + SMDEBUGLOG << "tpl_close() exception whilst getting stats" << endl; + end_query(hndl); + sm_cleanup(hndl); + *conn_hdl = 0; + return STATUS_OK; + //throw runtime_error(string("tbl_close catch exception: ") + e.what()); + } } - catch (IDBExcept&) - { - // @bug4732 - end_query(hndl); - throw; - } - catch (...) - { - // querystats messed up. close connection. - // no need to throw for querystats protocol error, like for tablemode. -#if IDB_SM_DEBUG - SMDEBUGLOG << "tpl_close() exception whilst getting stats" << endl; -#endif - end_query(hndl); - sm_cleanup(hndl); - *conn_hdl = 0; - return STATUS_OK; - //throw runtime_error(string("tbl_close catch exception: ") + e.what()); - } - } + } //stats end_query(hndl); } diff --git a/dbcon/mysql/sm.h b/dbcon/mysql/sm.h index dafa64419..32cb1aa18 100644 --- a/dbcon/mysql/sm.h +++ b/dbcon/mysql/sm.h @@ -282,7 +282,7 @@ extern status_t tpl_open(tableid_t, cpsm_tplh_t*, cpsm_conhdl_t*); extern status_t tpl_scan_open(tableid_t, sp_cpsm_tplsch_t&, cpsm_conhdl_t*); extern status_t tpl_scan_fetch(sp_cpsm_tplsch_t&, cpsm_conhdl_t*, int* k = 0); extern status_t tpl_scan_close(sp_cpsm_tplsch_t&); -extern status_t tpl_close(cpsm_tplh_t*, cpsm_conhdl_t**, querystats::QueryStats& stats, bool clear_scan_ctx = false); +extern status_t tpl_close(cpsm_tplh_t*, cpsm_conhdl_t**, querystats::QueryStats& stats, bool ask_4_stats, bool clear_scan_ctx = false); } From d62b66ecf7676fdbde33cb9dbaa02333cdaf5057 Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Fri, 26 Jul 2019 23:39:51 +0300 Subject: [PATCH 10/11] parse_item() in execplan code now always get an actual GWI structure to avoid accedental crashes. Add check for Conversion of Big IN Predicates Into Subqueries optimization conditions. Enabled derivedTableOptimization() for group by and derived handlers. Disabled Conversion of Big IN Predicates Into Subqueries optimization. Disabled most of optimizer_flags for now. RowGroup + operator now correctly sets useStringTable flag that instructs code to check StringStore instead of plain data buffer. --- dbcon/mysql/ha_calpont.cpp | 2 +- dbcon/mysql/ha_calpont_execplan.cpp | 67 +++++++++++++++++++++-------- dbcon/mysql/ha_calpont_impl.cpp | 32 ++++++-------- dbcon/mysql/ha_mcs_pushdown.cpp | 24 +++++++++++ dbcon/mysql/ha_mcs_pushdown.h | 3 ++ dbcon/mysql/ha_mcs_sysvars.cpp | 30 +++++++++++-- dbcon/mysql/ha_mcs_sysvars.h | 4 +- utils/rowgroup/rowgroup.cpp | 1 + 8 files changed, 119 insertions(+), 44 deletions(-) diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index 50b69c297..0d73b1667 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -146,7 +146,7 @@ static int columnstore_init_func(void* p) mcs_hton->rollback = calpont_rollback; mcs_hton->close_connection = calpont_close_connection; //mcs_hton->create_group_by = create_calpont_group_by_handler; - //mcs_hton->create_derived = create_columnstore_derived_handler; + mcs_hton->create_derived = create_columnstore_derived_handler; mcs_hton->create_select = create_columnstore_select_handler; DBUG_RETURN(0); } diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index e5c58cdcb..c0c777627 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -1143,6 +1143,12 @@ void debug_walk(const Item* item, void* arg) break; } + case Item::TYPE_HOLDER: + { + cerr << "TYPE_HOLDER item with cmp_type " << item->cmp_type() << endl; + break; + } + default: { cerr << "UNKNOWN_ITEM type " << item->type() << endl; @@ -3120,7 +3126,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp vector tmpVec; //bool hasAggColumn = false; uint16_t parseInfo = 0; - parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo); + parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo, &gwi); if (parseInfo & SUB_BIT) { @@ -3616,7 +3622,7 @@ ReturnedColumn* buildFunctionColumn( // try to identify const F&E. fall to primitive if parms are constant F&E. vector tmpVec; uint16_t parseInfo = 0; - parse_item(ifp->arguments()[i], tmpVec, gwi.fatalParseError, parseInfo); + parse_item(ifp->arguments()[i], tmpVec, gwi.fatalParseError, parseInfo, &gwi); if (!gwi.fatalParseError && !(parseInfo & AF_BIT) && tmpVec.size() == 0) continue; @@ -4625,7 +4631,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) // check count(1+1) case vector tmpVec; uint16_t parseInfo = 0; - parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo); + parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo, &gwi); if (parseInfo & SUB_BIT) { @@ -5238,7 +5244,7 @@ void gp_walk(const Item* item, void* arg) // try to evaluate const F&E vector tmpVec; uint16_t parseInfo = 0; - parse_item(ifp, tmpVec, gwip->fatalParseError, parseInfo); + parse_item(ifp, tmpVec, gwip->fatalParseError, parseInfo, gwip); // table mode takes only one table filter if (gwip->condPush) @@ -5704,10 +5710,6 @@ void gp_walk(const Item* item, void* arg) printf("********** received INSERT_VALUE_ITEM *********\n"); break; - case Item::Item::TYPE_HOLDER: - printf("********** received TYPE_HOLDER *********\n"); - break; - case Item::PARAM_ITEM: printf("********** received PARAM_ITEM *********\n"); break; @@ -5729,6 +5731,9 @@ void gp_walk(const Item* item, void* arg) printf("********** received VIEW_FIXER_ITEM *********\n"); break; */ + case Item::TYPE_HOLDER: + std::cerr << "********** received TYPE_HOLDER *********" << std::endl; + break; default: { if (gwip->condPush) @@ -5779,7 +5784,7 @@ void parse_item (Item* item, vector& field_vec, Item** sfitempp = isp->arguments(); for (uint32_t i = 0; i < isp->argument_count(); i++) - parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); + parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo, gwi); break; } @@ -5839,7 +5844,7 @@ void parse_item (Item* item, vector& field_vec, } for (uint32_t i = 0; i < isp->argument_count(); i++) - parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); + parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo, gwi); break; } @@ -5867,14 +5872,14 @@ void parse_item (Item* item, vector& field_vec, Item** sfitempp = isp->arguments(); for (uint32_t i = 0; i < isp->argument_count(); i++) - parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); + parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo, gwi); break; } else if ((*(ref->ref))->type() == Item::CACHE_ITEM) { Item_cache* isp = reinterpret_cast(*(ref->ref)); - parse_item(isp->get_example(), field_vec, hasNonSupportItem, parseInfo); + parse_item(isp->get_example(), field_vec, hasNonSupportItem, parseInfo, gwi); break; } else if ((*(ref->ref))->type() == Item::REF_ITEM) @@ -5913,7 +5918,7 @@ void parse_item (Item* item, vector& field_vec, Item_row* row = (Item_row*)item; for (uint32_t i = 0; i < row->cols(); i++) - parse_item(row->element_index(i), field_vec, hasNonSupportItem, parseInfo); + parse_item(row->element_index(i), field_vec, hasNonSupportItem, parseInfo, gwi); break; } @@ -5921,7 +5926,11 @@ void parse_item (Item* item, vector& field_vec, case Item::EXPR_CACHE_ITEM: { // item is a Item_cache_wrapper. Shouldn't get here. - printf("EXPR_CACHE_ITEM in parse_item\n"); + // WIP Why + IDEBUG(std::cerr << "EXPR_CACHE_ITEM in parse_item\n" << std::endl); + gwi->fatalParseError = true; + // DRRTUY The questionable error text. I've seen + // ERR_CORRELATED_SUB_OR string parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SUB_QUERY_TYPE); setError(gwi->thd, ER_CHECK_NOT_IMPLEMENTED, parseErrorText); break; @@ -6570,7 +6579,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, uint16_t parseInfo = 0; vector tmpVec; bool hasNonSupportItem = false; - parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo); + parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo, &gwi); if (ifp->with_subquery() || string(ifp->func_name()) == string("") || @@ -6606,7 +6615,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, { hasNonSupportItem = false; uint32_t before_size = funcFieldVec.size(); - parse_item(ifp, funcFieldVec, hasNonSupportItem, parseInfo); + 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 @@ -6915,6 +6924,23 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, gwi.returnedCols.push_back(srcp); break; } + case Item::TYPE_HOLDER: + { + if(!gwi.tbList.size()) + { + gwi.parseErrorText = "subquery with VALUES"; + gwi.fatalParseError = true; + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + else + { + std::cerr << "********** received TYPE_HOLDER *********" << std::endl; + + } + break; + } + default: { @@ -7551,7 +7577,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, bool hasNonSupportItem = false; uint16_t parseInfo = 0; - parse_item(ord_item, fieldVec, hasNonSupportItem, parseInfo); + parse_item(ord_item, fieldVec, hasNonSupportItem, parseInfo, &gwi); if (hasNonSupportItem) { @@ -8099,6 +8125,8 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi) return ER_INTERNAL_ERROR; else if (status < 0) return status; + // Derived table projection and filter optimization. + derivedTableOptimization(csep); return 0; } @@ -8120,7 +8148,8 @@ int cs_get_derived_plan(derived_handler* handler, THD* thd, SCSEP& csep) cerr << *csep << endl ; cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; #endif - + // Derived table projection and filter optimization. + derivedTableOptimization(csep); return 0; } @@ -8682,7 +8711,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro uint16_t parseInfo = 0; vector tmpVec; bool hasNonSupportItem = false; - parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo); + parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo, &gwi); if (ifp->with_subquery() || string(ifp->func_name()) == string("") || diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 83cddcb4c..b67c7cb57 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -1380,15 +1380,7 @@ uint32_t doUpdateDelete(THD* thd) columnAssignmentPtr->fFromCol = false; } } - // WIP MCOL-2178 - /*else if ( value->type() == Item::VARBIN_ITEM ) - { - String val, *str; - str = value->val_str(&val); - columnAssignmentPtr->fScalarExpression.assign(str->ptr(), str->length()); - columnAssignmentPtr->fFromCol = false; - }*/ - else if ( value->type() == Item::FUNC_ITEM ) + else if ( value->type() == Item::FUNC_ITEM ) { //Bug 2092 handle negative values Item_func* ifp = (Item_func*)value; @@ -2994,13 +2986,6 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) if (get_fe_conn_info_ptr() != NULL) ci = reinterpret_cast(get_fe_conn_info_ptr()); - // WIP MCOL-2178. Won't see this state anymore. - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY ) - { - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; // flip back to normal state - return rc; - } - if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) return rc; @@ -4387,6 +4372,8 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) if (lock_type == 0) { ci->physTablesList.insert(table); + // MCOL-2178 Disable Conversion of Big IN Predicates Into Subqueries + thd->variables.in_subquery_conversion_threshold=~0; } else if (lock_type == 2) { @@ -4413,6 +4400,9 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) // storage for cal_conn_hndl to use it later in close_connection thd_set_ha_data(thd, mcs_hton, get_fe_conn_info_ptr()); ci->tableMap.clear(); + // MCOL-2178 Enable Conversion of Big IN Predicates Into Subqueries + thd->variables.in_subquery_conversion_threshold = IN_SUBQUERY_CONVERSION_THRESHOLD; + restore_optimizer_flags(thd); } } @@ -5286,6 +5276,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) return ER_INTERNAL_ERROR; } + // WIP MCOL-2178 Remove this. // mysql reads table twice for order by if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1 || MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY) @@ -5413,6 +5404,9 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) hndl = ci->cal_conn_hndl; + // WIP MCOL-2178 + std::cout << idb_mysql_query_str(thd) << std::endl; + if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) { if (!csep) @@ -5455,13 +5449,15 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) dh = reinterpret_cast(handler_info->hndl_ptr); status = cs_get_derived_plan(dh, thd, csep); } - + + // WIP MCOL-2178 Remove this std::cout << "pushdown_init get_plan status " << status << std::endl; // Return an error to avoid MDB crash later in end_statement if (status != 0) goto internal_error; + // WIP MCOL-2178 Remove this std::cout << "pushdown_init impossibleWhereOnUnion " << status << std::endl; // @bug 2547. don't need to send the plan if it's impossible where for all unions. if (MIGR::infinidb_vtable.impossibleWhereOnUnion) @@ -5731,7 +5727,7 @@ error: ci->cal_conn_hndl = 0; } - // do we need to close all connection handle of the table map? + // do we need to close all connection handle of the table map return ER_INTERNAL_ERROR; internal_error: diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp index 93a3fee23..d6c81fc07 100644 --- a/dbcon/mysql/ha_mcs_pushdown.cpp +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -17,6 +17,29 @@ // ha_calpont.cpp includes this file. +void mutate_optimizer_flags(THD *thd_) +{ + // MCOL-2178 Disable all optimizer flags as it was in the fork. + // CS restores it later in SH::scan_end() and in case of an error + // in SH::scan_init() + set_original_optimizer_flags(thd_->variables.optimizer_switch, thd_); + thd_->variables.optimizer_switch = OPTIMIZER_SWITCH_IN_TO_EXISTS | + OPTIMIZER_SWITCH_EXISTS_TO_IN | + OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED; +} + +void restore_optimizer_flags(THD *thd_) +{ + // MCOL-2178 restore original optimizer flags after SH, DH + ulonglong orig_flags = get_original_optimizer_flags(thd_); + if (orig_flags) + { + thd_->variables.optimizer_switch = orig_flags; + set_original_optimizer_flags(0, thd_); + } +} + + /*@brief check_walk - It traverses filter conditions*/ /************************************************************ * DESCRIPTION: @@ -508,6 +531,7 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) if (!unsupported_feature) { handler = new ha_columnstore_select_handler(thd, select_lex); + mutate_optimizer_flags(thd); } return handler; diff --git a/dbcon/mysql/ha_mcs_pushdown.h b/dbcon/mysql/ha_mcs_pushdown.h index 2849cb530..1012cfa8c 100644 --- a/dbcon/mysql/ha_mcs_pushdown.h +++ b/dbcon/mysql/ha_mcs_pushdown.h @@ -21,6 +21,9 @@ #include "idb_mysql.h" #include "ha_calpont.h" +void mutate_optimizer_flags(THD *thd_); +void restore_optimizer_flags(THD *thd_); + enum mcs_handler_types_t { SELECT, diff --git a/dbcon/mysql/ha_mcs_sysvars.cpp b/dbcon/mysql/ha_mcs_sysvars.cpp index dc022b8f2..01b0d6832 100644 --- a/dbcon/mysql/ha_mcs_sysvars.cpp +++ b/dbcon/mysql/ha_mcs_sysvars.cpp @@ -58,6 +58,21 @@ static MYSQL_THDVAR_ULONGLONG( 1 ); +// optimizer flags vault +static MYSQL_THDVAR_ULONGLONG( + original_optimizer_flags, + PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT, + "Vault for original optimizer flags. For internal usage.", + NULL, + NULL, + 0, + 0, + ~0U, + 1 +); + + + // legacy system variables static MYSQL_THDVAR_ULONG( decimal_scale, @@ -240,6 +255,7 @@ st_mysql_sys_var* mcs_system_variables[] = { MYSQL_SYSVAR(compression_type), MYSQL_SYSVAR(fe_conn_info_ptr), + MYSQL_SYSVAR(original_optimizer_flags), MYSQL_SYSVAR(decimal_scale), MYSQL_SYSVAR(use_decimal_scale), MYSQL_SYSVAR(ordered_only), @@ -275,14 +291,20 @@ void set_fe_conn_info_ptr(void* ptr, THD* thd) THDVAR(current_thd, fe_conn_info_ptr) = (uint64_t)(ptr); } -bool get_use_legacy_sysvars(THD* thd) +ulonglong get_original_optimizer_flags(THD* thd) { - return ( thd == NULL ) ? false : THDVAR(thd, use_legacy_sysvars); + return ( current_thd == NULL && thd == NULL ) ? NULL : + THDVAR(current_thd, original_optimizer_flags); } -void set_use_legacy_sysvars(THD* thd, bool value) +void set_original_optimizer_flags(ulonglong ptr, THD* thd) { - THDVAR(thd, use_legacy_sysvars) = value; + if ( current_thd == NULL && thd == NULL) + { + return; + } + + THDVAR(current_thd, original_optimizer_flags) = (uint64_t)(ptr); } void set_compression_type(THD* thd, ulong value) diff --git a/dbcon/mysql/ha_mcs_sysvars.h b/dbcon/mysql/ha_mcs_sysvars.h index eae31b0ea..3eea2e2ec 100644 --- a/dbcon/mysql/ha_mcs_sysvars.h +++ b/dbcon/mysql/ha_mcs_sysvars.h @@ -40,8 +40,8 @@ void set_compression_type(THD* thd, ulong value); void* get_fe_conn_info_ptr(THD* thd = NULL); void set_fe_conn_info_ptr(void* ptr, THD* thd = NULL); -bool get_use_legacy_sysvars(THD* thd); -void set_use_legacy_sysvars(THD* thd, bool value); +ulonglong get_original_optimizer_flags(THD* thd = NULL); +void set_original_optimizer_flags(ulonglong ptr, THD* thd = NULL); bool get_use_decimal_scale(THD* thd); void set_use_decimal_scale(THD* thd, bool value); diff --git a/utils/rowgroup/rowgroup.cpp b/utils/rowgroup/rowgroup.cpp index e16f12c30..27d530343 100644 --- a/utils/rowgroup/rowgroup.cpp +++ b/utils/rowgroup/rowgroup.cpp @@ -1591,6 +1591,7 @@ RowGroup& RowGroup::operator+=(const RowGroup& rhs) } hasLongStringField = rhs.hasLongStringField || hasLongStringField; + useStringTable = rhs.useStringTable || useStringTable; offsets = (useStringTable ? &stOffsets[0] : &oldOffsets[0]); return *this; From 1c460f3ba51ce7b5e81dbfdd38d5c011dd4b9b1b Mon Sep 17 00:00:00 2001 From: Gagan Goel Date: Sun, 4 Aug 2019 21:50:50 -0400 Subject: [PATCH 11/11] MCOL-2178 Cleanup of MIGR:: singleton from the plugin code. Disable SP execution by the smart handlers for now. Add session variables to Enable/Disable select/derived/group_by handlers. Defaulted to Enable. --- dbcon/mysql/ha_calpont.cpp | 2 - dbcon/mysql/ha_calpont_ddl.cpp | 16 - dbcon/mysql/ha_calpont_dml.cpp | 4 - dbcon/mysql/ha_calpont_execplan.cpp | 68 ++- dbcon/mysql/ha_calpont_impl.cpp | 691 ++++++---------------------- dbcon/mysql/ha_calpont_impl_if.h | 12 +- dbcon/mysql/ha_mcs_pushdown.cpp | 84 ++-- dbcon/mysql/ha_mcs_sysvars.cpp | 57 +++ dbcon/mysql/ha_mcs_sysvars.h | 9 + dbcon/mysql/ha_view.cpp | 3 +- dbcon/mysql/idb_mysql.h | 64 --- 11 files changed, 284 insertions(+), 726 deletions(-) diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index 0d73b1667..525ac62b7 100644 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -23,8 +23,6 @@ #include "ha_calpont_impl.h" #include "ha_mcs_pushdown.h" -MIGR::INFINIDB_VTABLE MIGR::infinidb_vtable; - static handler* calpont_create_handler(handlerton* hton, TABLE_SHARE* table, MEM_ROOT* mem_root); diff --git a/dbcon/mysql/ha_calpont_ddl.cpp b/dbcon/mysql/ha_calpont_ddl.cpp index 3c411e529..05fb71203 100644 --- a/dbcon/mysql/ha_calpont_ddl.cpp +++ b/dbcon/mysql/ha_calpont_ddl.cpp @@ -2306,17 +2306,6 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* bool schemaSyncOnly = false; bool isCreate = true; - // relate to bug 1793. Make sure this is not for a select statement because - if (db == "calpontsys" && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT - && tbl != "systable" - && tbl != "syscolumn" && tbl != "sysindex" - && tbl != "sysconstraint" && tbl != "sysindexcol" - && tbl != "sysconstraintcol" ) - { - setError(thd, ER_INTERNAL_ERROR, "Cannot create non-system Calpont tables in calpontsys database"); - return 1; - } - regex pat("[[:space:]]*SCHEMA[[:space:]]+SYNC[[:space:]]+ONLY", regex_constants::extended); if (regex_search(tablecomment, pat)) @@ -2336,11 +2325,6 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* #endif return 0; } - - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ALTER_VTABLE) //check if it is select - { - return 0; - } } else { diff --git a/dbcon/mysql/ha_calpont_dml.cpp b/dbcon/mysql/ha_calpont_dml.cpp index 9372491e2..d98322ab3 100644 --- a/dbcon/mysql/ha_calpont_dml.cpp +++ b/dbcon/mysql/ha_calpont_dml.cpp @@ -2117,10 +2117,6 @@ int ha_calpont_impl_commit_ (handlerton* hton, THD* thd, bool all, cal_connectio { int rc = 0; - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ALTER_VTABLE || - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE ) - return rc; - if (thd->slave_thread && !ci.replicationEnabled) return 0; diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index c0c777627..3767a3a8d 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -1321,8 +1321,9 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) { if (gwi.thd->derived_tables_processing) { - MIGR::infinidb_vtable.isUnion = false; - MIGR::infinidb_vtable.isUpdateWithDerive = true; +// TODO MCOL-2178 isUnion member only assigned, never used +// MIGR::infinidb_vtable.isUnion = false; + gwi.cs_vtable_is_update_with_derive = true; return -1; } } @@ -2645,8 +2646,6 @@ void setError(THD* thd, uint32_t errcode, string errmsg) } thd->raise_error_printf(errcode, errmsg.c_str()); - MIGR::infinidb_vtable.isNewQuery = true; - MIGR::infinidb_vtable.override_largeside_estimate = false; // reset expressionID if (get_fe_conn_info_ptr() == NULL) @@ -5623,7 +5622,8 @@ void gp_walk(const Item* item, void* arg) gwip->hasSubSelect = true; gwip->subQuery = existsSub; gwip->ptWorkStack.push(existsSub->transform()); - MIGR::infinidb_vtable.isUnion = true; // only temp. bypass the 2nd phase. +// TODO MCOL-2178 isUnion member only assigned, never used +// MIGR::infinidb_vtable.isUnion = true; // only temp. bypass the 2nd phase. // recover original gwip->subQuery = orig; gwip->lastSub = existsSub; @@ -5983,7 +5983,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) || ((gwi.thd->lex)->sql_command == SQLCOM_DELETE_MULTI ) ) && gwi.thd->derived_tables_processing) { - MIGR::infinidb_vtable.isUnion = false; +// TODO MCOL-2178 isUnion member only assigned, never used +// MIGR::infinidb_vtable.isUnion = false; return -1; } @@ -6031,7 +6032,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // @bug 2123. Override large table estimate if infinidb_ordered hint was used. // @bug 2404. Always override if the infinidb_ordered_only variable is turned on. - if (MIGR::infinidb_vtable.override_largeside_estimate || get_ordered_only(gwi.thd)) + if (get_ordered_only(gwi.thd)) csep->overrideLargeSideEstimate(true); // @bug 5741. Set a flag when in Local PM only query mode @@ -6117,7 +6118,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, gwi.tbList.push_back(tn); CalpontSystemCatalog::TableAliasName tan = make_aliastable("", alias, alias); gwi.tableMap[tan] = make_pair(0, table_ptr); - MIGR::infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init +// TODO MCOL-2178 isUnion member only assigned, never used +// MIGR::infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init } else if (table_ptr->view) { @@ -6188,7 +6190,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // is_unit_op() give a segv for derived_handler's SELECT_LEX if (!isUnion && select_lex.master_unit()->is_unit_op()) { - MIGR::infinidb_vtable.isUnion = true; +// TODO MCOL-2178 isUnion member only assigned, never used +// MIGR::infinidb_vtable.isUnion = true; CalpontSelectExecutionPlan::SelectList unionVec; SELECT_LEX* select_cursor = select_lex.master_unit()->first_select(); unionSel = true; @@ -6247,7 +6250,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, csep->distinctUnionNum(distUnionNum); if (unionVec.empty()) - MIGR::infinidb_vtable.impossibleWhereOnUnion = true; + gwi.cs_vtable_impossible_where_on_union = true; } gwi.clauseType = WHERE; @@ -6280,8 +6283,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // processing. if (gwi.thd->derived_tables_processing) { - MIGR::infinidb_vtable.isUnion = false; - MIGR::infinidb_vtable.isUpdateWithDerive = true; +// TODO MCOL-2178 isUnion member only assigned, never used +// MIGR::infinidb_vtable.isUnion = false; + gwi.cs_vtable_is_update_with_derive = true; return -1; } @@ -7094,7 +7098,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SRCP minSc; // min width projected column. for count(*) use // Group by list. not valid for union main query - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE && !unionSel) + if (!unionSel) { gwi.clauseType = GROUP_BY; Item* nonSupportItem = NULL; @@ -7374,7 +7378,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, } } - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) { SQL_I_List order_list = select_lex.order_list; ORDER* ordercol = reinterpret_cast(order_list.first); @@ -7861,10 +7864,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, // 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 && - MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_CREATE_VTABLE)) && - !csep->hasOrderBy()) + if (gwi.thd->variables.select_limit == (uint64_t) - 1 && + !csep->hasOrderBy()) { csep->limitStart(limitOffset); csep->limitNum(limitNum); @@ -7977,7 +7978,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, csep->derivedTableList(gwi.derivedTbList); csep->selectSubList(selectSubList); csep->subSelectList(gwi.subselectList); - MIGR::infinidb_vtable.duplicate_field_name = false; clearStacks(gwi); return 0; } @@ -7987,10 +7987,11 @@ int cp_get_plan(THD* thd, SCSEP& csep) LEX* lex = thd->lex; idbassert(lex != 0); - // WIP MCOL-2178 A questionable replacement. - SELECT_LEX select_lex = *lex->first_select_lex(); gp_walk_info gwi; gwi.thd = thd; + + // WIP MCOL-2178 A questionable replacement. + SELECT_LEX select_lex = *lex->first_select_lex(); int status = getSelectPlan(gwi, select_lex, csep); if (status > 0) @@ -8126,16 +8127,14 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi) else if (status < 0) return status; // Derived table projection and filter optimization. - derivedTableOptimization(csep); + derivedTableOptimization(thd, csep); return 0; } -int cs_get_derived_plan(derived_handler* handler, THD* thd, SCSEP& csep) +int cs_get_derived_plan(derived_handler* handler, THD* thd, SCSEP& csep, gp_walk_info& gwi) { SELECT_LEX select_lex = *handler->select; - gp_walk_info gwi; - gwi.thd = thd; int status = getSelectPlan(gwi, select_lex, csep, false, true); if (status > 0) @@ -8149,15 +8148,13 @@ int cs_get_derived_plan(derived_handler* handler, THD* thd, SCSEP& csep) cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; #endif // Derived table projection and filter optimization. - derivedTableOptimization(csep); + derivedTableOptimization(thd, csep); return 0; } -int cs_get_select_plan(select_handler* handler, THD* thd, SCSEP& csep) +int cs_get_select_plan(select_handler* handler, THD* thd, SCSEP& csep, gp_walk_info& gwi) { SELECT_LEX select_lex = *handler->select; - gp_walk_info gwi; - gwi.thd = thd; int status = getSelectPlan(gwi, select_lex, csep, false, true); if (status > 0) @@ -8171,7 +8168,7 @@ int cs_get_select_plan(select_handler* handler, THD* thd, SCSEP& csep) cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; #endif // Derived table projection and filter optimization. - derivedTableOptimization(csep); + derivedTableOptimization(thd, csep); return 0; } @@ -8268,7 +8265,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // @bug 2123. Override large table estimate if infinidb_ordered hint was used. // @bug 2404. Always override if the infinidb_ordered_only variable is turned on. - if (MIGR::infinidb_vtable.override_largeside_estimate || get_ordered_only(gwi.thd)) + if (get_ordered_only(gwi.thd)) csep->overrideLargeSideEstimate(true); // @bug 5741. Set a flag when in Local PM only query mode @@ -8355,6 +8352,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro gwi.tbList.push_back(tn); CalpontSystemCatalog::TableAliasName tan = make_aliastable("", alias, alias); gwi.tableMap[tan] = make_pair(0, table_ptr); +// TODO MCOL-2178 isUnion member only assigned, never used // MIGR::infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init } else if (table_ptr->view) @@ -8453,8 +8451,8 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // processing. if (gwi.thd->derived_tables_processing) { - MIGR::infinidb_vtable.isUnion = false; - MIGR::infinidb_vtable.isUpdateWithDerive = true; +// TODO MCOL-2178 isUnion member only assigned, never used +// MIGR::infinidb_vtable.isUnion = false; return -1; } @@ -9248,7 +9246,7 @@ 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 (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE && !unionSel) + if (!unionSel) { gwi.clauseType = GROUP_BY; Item* nonSupportItem = NULL; @@ -9531,7 +9529,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro // ORDER BY processing starts here - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) { ORDER* ordercol = reinterpret_cast(gi.groupByOrder); @@ -10071,7 +10068,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro csep->derivedTableList(gwi.derivedTbList); csep->selectSubList(selectSubList); csep->subSelectList(gwi.subselectList); - MIGR::infinidb_vtable.duplicate_field_name = false; clearStacks(gwi); return 0; } diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index b67c7cb57..36f152578 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -1176,7 +1176,7 @@ vector getOnUpdateTimestampColumns(string& schema, string& tableName, in return returnVal; } -uint32_t doUpdateDelete(THD* thd) +uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi) { if (get_fe_conn_info_ptr() == NULL) set_fe_conn_info_ptr((void*)new cal_connection_info()); @@ -1193,7 +1193,6 @@ uint32_t doUpdateDelete(THD* thd) //@Bug 4387. Check BRM status before start statement. boost::scoped_ptr dbrmp(new DBRM()); int rc = dbrmp->isReadWrite(); - MIGR::infinidb_vtable.isInfiniDBDML = true; if (rc != 0 ) { @@ -1709,13 +1708,8 @@ uint32_t doUpdateDelete(THD* thd) return 0; } - //MIGR::infinidb_vtable.isInfiniDBDML = true; - MIGR::infinidb_state origState = MIGR::infinidb_vtable.vtable_state; //if (( (thd->lex)->sql_command == SQLCOM_UPDATE ) || ( (thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ) { - gp_walk_info gwi; - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; - gwi.thd = thd; //updateCP->subType (CalpontSelectExecutionPlan::SINGLEROW_SUBS); //set scalar updateCP->subType (CalpontSelectExecutionPlan::SELECT_SUBS); //@Bug 2975. @@ -1751,13 +1745,12 @@ uint32_t doUpdateDelete(THD* thd) if (getSelectPlan(gwi, select_lex, updateCP, false, true) != 0) //@Bug 3030 Modify the error message for unsupported functions { - if (MIGR::infinidb_vtable.isUpdateWithDerive) + if (gwi.cs_vtable_is_update_with_derive) { // @bug 4457. MySQL inconsistence! for some queries, some structures are only available // in the derived_tables_processing phase. So by pass the phase for DML only when the // execution plan can not be successfully generated. recover lex before returning; thd->lex->first_select_lex()->item_list = items; - MIGR::infinidb_vtable.vtable_state = origState; return 0; } @@ -1923,8 +1916,6 @@ uint32_t doUpdateDelete(THD* thd) boost::shared_ptr plan = pDMLPackage->get_ExecutionPlan(); updateCP->rmParms(ci->rmParms); updateCP->serialize(*plan); - // recover original vtable state - MIGR::infinidb_vtable.vtable_state = origState; //cout << "plan has bytes " << plan->length() << endl; pDMLPackage->write(bytestream); @@ -2294,6 +2285,9 @@ int ha_calpont_impl_rnd_init(TABLE* table) IDEBUG( cout << "rnd_init for table " << table->s->table_name.str << endl ); THD* thd = current_thd; + gp_walk_info gwi; + gwi.thd = thd; + //check whether the system is ready to process statement. #ifndef _MSC_VER static DBRM dbrm(true); @@ -2303,14 +2297,12 @@ int ha_calpont_impl_rnd_init(TABLE* table) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "The system is not yet ready to accept queries"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } else if (bSystemQueryReady < 0) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "DBRM is not responding. Cannot accept queries"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } #endif @@ -2322,9 +2314,6 @@ int ha_calpont_impl_rnd_init(TABLE* table) thd_set_ha_data(thd, mcs_hton, reinterpret_cast(0x42)); } - // prevent "create table as select" from running on slave - MIGR::infinidb_vtable.hasInfiniDBTable = true; - cal_connection_info* ci = reinterpret_cast(get_fe_conn_info_ptr()); if (thd->slave_thread && !ci->replicationEnabled && ( @@ -2338,25 +2327,12 @@ int ha_calpont_impl_rnd_init(TABLE* table) thd->lex->sql_command == SQLCOM_LOAD)) return 0; - // return error is error status is already set - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) - return ER_INTERNAL_ERROR; - - // @bug 2232. Basic SP support. Error out non support sp cases. - // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) - { - setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; - return ER_INTERNAL_ERROR; - } - 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); + return doUpdateDelete(thd, gwi); uint32_t sessionID = tid2sid(thd->thread_id); boost::shared_ptr csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID); @@ -2378,24 +2354,12 @@ int ha_calpont_impl_rnd_init(TABLE* 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 (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE || - (thd->slave_thread && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT)) - { - ci->traceFlags |= CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_DISABLE_VTABLE; - } - else - { - ci->traceFlags = (ci->traceFlags | CalpontSelectExecutionPlan::TRACE_TUPLE_OFF)^ - CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; - } + // update traceFlags according to the autoswitch state. + ci->traceFlags |= CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; bool localQuery = get_local_query(thd); // table mode - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) { ti = ci->tableMap[table]; @@ -2468,154 +2432,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) ti.csep->data(""); } } - // vtable mode - else - // The whole section must be useless now. - { - if ( !ci->cal_conn_hndl || - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) - { - ci->stats.reset(); // reset query stats - ci->stats.setStartTime(); - if (thd->main_security_ctx.user) - { - ci->stats.fUser = thd->main_security_ctx.user; - } - else - { - ci->stats.fUser = ""; - } - if (thd->main_security_ctx.host) - ci->stats.fHost = thd->main_security_ctx.host; - else if (thd->main_security_ctx.host_or_ip) - ci->stats.fHost = thd->main_security_ctx.host_or_ip; - else - ci->stats.fHost = "unknown"; - - try - { - ci->stats.userPriority(ci->stats.fHost, ci->stats.fUser); - } - catch (std::exception& e) - { - string msg = string("Columnstore User Priority - ") + e.what(); - ci->warningMsg = msg; - } - - // if the previous query has error, re-establish the connection - if (ci->queryState != 0) - { - sm::sm_cleanup(ci->cal_conn_hndl); - ci->cal_conn_hndl = 0; - } - } - - sm::sm_init(sessionID, &ci->cal_conn_hndl, localQuery); - idbassert(ci->cal_conn_hndl != 0); - ci->cal_conn_hndl->csc = csc; - idbassert(ci->cal_conn_hndl->exeMgr != 0); - - try - { - ci->cal_conn_hndl->connect(); - } - catch (...) - { - setError(thd, ER_INTERNAL_ERROR, IDBErrorInfo::instance()->errorMsg(ERR_LOST_CONN_EXEMGR)); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - goto error; - } - - hndl = ci->cal_conn_hndl; - - if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) - { - //CalpontSelectExecutionPlan csep; - if (!csep) - 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(); - - csep->txnID(txnID.id); - csep->verID(verID); - csep->sessionID(sessionID); - - if (thd->db.length) - csep->schemaName(thd->db.str); - - csep->traceFlags(ci->traceFlags); - - if (MIGR::infinidb_vtable.isInsertSelect) - csep->queryType(CalpontSelectExecutionPlan::INSERT_SELECT); - - //get plan - int status = cp_get_plan(thd, csep); - - //if (cp_get_plan(thd, csep) != 0) - if (status > 0) - goto internal_error; - else if (status < 0) - return 0; - - // @bug 2547. don't need to send the plan if it's impossible where for all unions. - // WIP MCOL-2178 This singleton attribute could be a problem - if (MIGR::infinidb_vtable.impossibleWhereOnUnion) - return 0; - - string query; - query.assign(MIGR::infinidb_vtable.original_query.ptr(), - MIGR::infinidb_vtable.original_query.length()); - csep->data(query); - - try - { - csep->priority( ci->stats.userPriority(ci->stats.fHost, ci->stats.fUser)); - } - catch (std::exception& e) - { - string msg = string("Columnstore User Priority - ") + e.what(); - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, msg.c_str()); - } - -#ifdef PLAN_HEX_FILE - // plan serialization - string tmpDir = aTmpDir + "/li1-plan.hex"; - - ifstream ifs(tmpDir.c_str()); - ByteStream bs1; - ifs >> bs1; - ifs.close(); - csep->unserialize(bs1); -#endif - - if (ci->traceFlags & 1) - { - cerr << "---------------- EXECUTION PLAN ----------------" << endl; - cerr << *csep << endl ; - cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; - } - else - { - IDEBUG( cout << "---------------- EXECUTION PLAN ----------------" << endl ); - IDEBUG( cerr << *csep << endl ); - IDEBUG( cout << "-------------- EXECUTION PLAN END --------------\n" << endl ); - } - } - }// end of execution plan generation - - if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) { ByteStream msg; ByteStream emsgBs; @@ -2690,14 +2507,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) ci->rmParms.clear(); - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) - { - ci->tableMap[table] = ti; - } - else - { - ci->queryState = 1; - } + ci->tableMap[table] = ti; break; } @@ -2710,10 +2520,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) idbassert(hndl != 0); hndl->csc = csc; - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) - ti.conn_hndl = hndl; - else - ci->cal_conn_hndl = hndl; + ti.conn_hndl = hndl; try { @@ -2731,92 +2538,81 @@ int ha_calpont_impl_rnd_init(TABLE* table) } } - // set query state to be in_process. Sometimes mysql calls rnd_init multiple - // times, this makes sure plan only being generated and sent once. It will be - // reset when query finishes in sm::end_query - MIGR::infinidb_vtable.isNewQuery = false; - // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; ti.msTablePtr = table; - if ((MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE) || - (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) || - (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_QUERY)) + if (ti.tpl_ctx == 0) { - if (ti.tpl_ctx == 0) + ti.tpl_ctx = new sm::cpsm_tplh_t(); + ti.tpl_scan_ctx = sm::sp_cpsm_tplsch_t(new sm::cpsm_tplsch_t()); + } + + // make sure rowgroup is null so the new meta data can be taken. This is for some case mysql + // call rnd_init for a table more than once. + ti.tpl_scan_ctx->rowGroup = NULL; + + try + { + tableid = execplan::IDB_VTABLE_ID; + } + catch (...) + { + string emsg = "No table ID found for table " + string(table->s->table_name.str); + setError(thd, ER_INTERNAL_ERROR, emsg); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto internal_error; + } + + try + { + sm::tpl_open(tableid, ti.tpl_ctx, hndl); + sm::tpl_scan_open(tableid, ti.tpl_scan_ctx, hndl); + } + catch (std::exception& e) + { + string emsg = "table can not be opened: " + string(e.what()); + setError(thd, ER_INTERNAL_ERROR, emsg); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto internal_error; + } + catch (...) + { + string emsg = "table can not be opened"; + setError(thd, ER_INTERNAL_ERROR, emsg); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto internal_error; + } + + ti.tpl_scan_ctx->traceFlags = ci->traceFlags; + + if ((ti.tpl_scan_ctx->ctp).size() == 0) + { + uint32_t num_attr = table->s->fields; + + for (uint32_t i = 0; i < num_attr; i++) { - ti.tpl_ctx = new sm::cpsm_tplh_t(); - ti.tpl_scan_ctx = sm::sp_cpsm_tplsch_t(new sm::cpsm_tplsch_t()); + CalpontSystemCatalog::ColType ctype; + ti.tpl_scan_ctx->ctp.push_back(ctype); } - // make sure rowgroup is null so the new meta data can be taken. This is for some case mysql - // call rnd_init for a table more than once. - ti.tpl_scan_ctx->rowGroup = NULL; + // populate coltypes here for table mode because tableband gives treeoid for dictionary column + { + CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(make_table(table->s->db.str, table->s->table_name.str), true); - try - { - tableid = execplan::IDB_VTABLE_ID; - } - catch (...) - { - string emsg = "No table ID found for table " + string(table->s->table_name.str); - setError(thd, ER_INTERNAL_ERROR, emsg); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - goto internal_error; - } - - try - { - sm::tpl_open(tableid, ti.tpl_ctx, hndl); - sm::tpl_scan_open(tableid, ti.tpl_scan_ctx, hndl); - } - catch (std::exception& e) - { - string emsg = "table can not be opened: " + string(e.what()); - setError(thd, ER_INTERNAL_ERROR, emsg); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - goto internal_error; - } - catch (...) - { - string emsg = "table can not be opened"; - setError(thd, ER_INTERNAL_ERROR, emsg); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - goto internal_error; - } - - ti.tpl_scan_ctx->traceFlags = ci->traceFlags; - - if ((ti.tpl_scan_ctx->ctp).size() == 0) - { - uint32_t num_attr = table->s->fields; - - for (uint32_t i = 0; i < num_attr; i++) + if (oidlist.size() != num_attr) { - CalpontSystemCatalog::ColType ctype; - ti.tpl_scan_ctx->ctp.push_back(ctype); + string emsg = "Size mismatch probably caused by front end out of sync"; + setError(thd, ER_INTERNAL_ERROR, emsg); + CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); + goto internal_error; } - // populate coltypes here for table mode because tableband gives treeoid for dictionary column - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) + for (unsigned int j = 0; j < oidlist.size(); j++) { - CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(make_table(table->s->db.str, table->s->table_name.str), true); - - if (oidlist.size() != num_attr) - { - string emsg = "Size mismatch probably caused by front end out of sync"; - setError(thd, ER_INTERNAL_ERROR, emsg); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - goto internal_error; - } - - for (unsigned int j = 0; j < oidlist.size(); j++) - { - CalpontSystemCatalog::ColType ctype = csc->colType(oidlist[j].objnum); - ti.tpl_scan_ctx->ctp[ctype.colPosition] = ctype; - ti.tpl_scan_ctx->ctp[ctype.colPosition].colPosition = -1; - } + CalpontSystemCatalog::ColType ctype = csc->colType(oidlist[j].objnum); + ti.tpl_scan_ctx->ctp[ctype.colPosition] = ctype; + ti.tpl_scan_ctx->ctp[ctype.colPosition].colPosition = -1; } } } @@ -2863,30 +2659,14 @@ int ha_calpont_impl_rnd_next(uchar* buf, TABLE* table) thd->lex->sql_command == SQLCOM_LOAD)) return 0; - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) - return ER_INTERNAL_ERROR; - - // @bug 3005 - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE && - string(table->s->table_name.str).find("$vtable") != 0) - return HA_ERR_END_OF_FILE; - 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 HA_ERR_END_OF_FILE; // @bug 2547 - if (MIGR::infinidb_vtable.impossibleWhereOnUnion) - return HA_ERR_END_OF_FILE; - - // @bug 2232. Basic SP support - // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) - { - setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; - return ER_INTERNAL_ERROR; - } +// TODO MCOL-2178 This variable can never be true in the scope of this function +// if (MIGR::infinidb_vtable.impossibleWhereOnUnion) +// return HA_ERR_END_OF_FILE; if (get_fe_conn_info_ptr() == NULL) set_fe_conn_info_ptr((void*)new cal_connection_info()); @@ -2975,14 +2755,14 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) thd->lex->sql_command == SQLCOM_LOAD)) return 0; - MIGR::infinidb_vtable.isNewQuery = true; // WIP MCOL-2178 // Workaround because CS doesn't reset isUnion in a normal way. - if (is_pushdown_hand) - { - MIGR::infinidb_vtable.isUnion = false; - } +// TODO MCOL-2178 isUnion member only assigned, never used +// if (is_pushdown_hand) +// { +// MIGR::infinidb_vtable.isUnion = false; +// } if (get_fe_conn_info_ptr() != NULL) ci = reinterpret_cast(get_fe_conn_info_ptr()); @@ -3024,7 +2804,7 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) cal_table_info ti = ci->tableMap[table]; sm::cpsm_conhdl_t* hndl; - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) + if (!is_pushdown_hand) hndl = ti.conn_hndl; else hndl = ci->cal_conn_hndl; @@ -3053,7 +2833,7 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand) } // set conn hndl back. could be changed in tpl_close - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) + if (!is_pushdown_hand) ti.conn_hndl = hndl; else ci->cal_conn_hndl = hndl; @@ -3112,8 +2892,7 @@ int ha_calpont_impl_create(const char* name, TABLE* table_arg, HA_CREATE_INFO* c cal_connection_info* ci = reinterpret_cast(get_fe_conn_info_ptr()); // @bug1940 Do nothing for select query. Support of set default engine to IDB. - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE || - string(name).find("@0024vtable") != string::npos) + if (string(name).find("@0024vtable") != string::npos) return 0; //@Bug 1948. Mysql calls create table to create a new table with new signature. @@ -3313,14 +3092,11 @@ void ha_calpont_impl_start_bulk_insert(ha_rows rows, TABLE* table) if (ci->alterTableState > 0) return; - if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_ALTER_VTABLE) - MIGR::infinidb_vtable.isInfiniDBDML = true; - if (thd->slave_thread && !ci->replicationEnabled) return; //@bug 5660. Error out DDL/DML on slave node, or on local query node - if (ci->isSlaveNode && MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_ALTER_VTABLE) + if (ci->isSlaveNode) { string emsg = logging::IDBErrorInfo::instance()->errorMsg(ERR_DML_DDL_SLAVE); setError(current_thd, ER_CHECK_NOT_IMPLEMENTED, emsg); @@ -4088,12 +3864,6 @@ int ha_calpont_impl_end_bulk_insert(bool abort, TABLE* table) int ha_calpont_impl_commit (handlerton* hton, THD* thd, bool all) { - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE || - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ALTER_VTABLE || - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DROP_VTABLE || - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1) - return 0; - if (get_fe_conn_info_ptr() == NULL) set_fe_conn_info_ptr((void*)new cal_connection_info()); @@ -4210,8 +3980,6 @@ int ha_calpont_impl_rename_table(const char* from, const char* to) IDEBUG( cout << "ha_calpont_impl_rename_table: was in state ALTER_SECOND_RENAME, now in NOT_ALTER" << endl ); return 0; } - else if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ALTER_VTABLE ) - return 0; int rc = ha_calpont_impl_rename_table_(from, to, *ci); return rc; @@ -4227,12 +3995,6 @@ COND* ha_calpont_impl_cond_push(COND* cond, TABLE* table) { THD* thd = current_thd; - if (thd->slave_thread && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT) - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_DISABLE_VTABLE; - - if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_DISABLE_VTABLE) - return cond; - if (((thd->lex)->sql_command == SQLCOM_UPDATE) || ((thd->lex)->sql_command == SQLCOM_UPDATE_MULTI) || ((thd->lex)->sql_command == SQLCOM_DELETE) || @@ -4336,35 +4098,26 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) if (mapiter != ci->tableMap.end() && lock_type == 2) // make sure it's the release lock (2nd) call { // table mode - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) + if (mapiter->second.conn_hndl) { - if (mapiter->second.conn_hndl) - { - if (ci->traceFlags & 1) - push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 9999, mapiter->second.conn_hndl->queryStats.c_str()); + if (ci->traceFlags & 1) + push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 9999, mapiter->second.conn_hndl->queryStats.c_str()); - ci->queryStats = mapiter->second.conn_hndl->queryStats; - ci->extendedStats = mapiter->second.conn_hndl->extendedStats; - ci->miniStats = mapiter->second.conn_hndl->miniStats; - sm::sm_cleanup(mapiter->second.conn_hndl); - mapiter->second.conn_hndl = 0; - } - - if (mapiter->second.condInfo) - { - delete mapiter->second.condInfo; - mapiter->second.condInfo = 0; - } - - // only push this warning for once - if (ci->tableMap.size() == 1 && - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE && MIGR::infinidb_vtable.autoswitch) - { - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, infinidb_autoswitch_warning.c_str()); - } - // MCOL-2178 Check for tableMap size to set this only once. - ci->queryState = 0; + ci->queryStats = mapiter->second.conn_hndl->queryStats; + ci->extendedStats = mapiter->second.conn_hndl->extendedStats; + ci->miniStats = mapiter->second.conn_hndl->miniStats; + sm::sm_cleanup(mapiter->second.conn_hndl); + mapiter->second.conn_hndl = 0; } + + if (mapiter->second.condInfo) + { + delete mapiter->second.condInfo; + mapiter->second.condInfo = 0; + } + + // MCOL-2178 Check for tableMap size to set this only once. + ci->queryState = 0; ci->tableMap.erase(table); } else @@ -4395,7 +4148,6 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type) ci->extendedStats = ci->cal_conn_hndl->extendedStats; ci->miniStats = ci->cal_conn_hndl->miniStats; ci->queryState = 0; - MIGR::infinidb_vtable.override_largeside_estimate = false; // MCOL-3247 Use THD::ha_data as a per-plugin per-session // storage for cal_conn_hndl to use it later in close_connection thd_set_ha_data(thd, mcs_hton, get_fe_conn_info_ptr()); @@ -4447,33 +4199,16 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE { // Still not ready setError(thd, ER_INTERNAL_ERROR, "The system is not yet ready to accept queries"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } else if (bSystemQueryReady < 0) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "DBRM is not responding. Cannot accept queries"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } #endif - // prevent "create table as select" from running on slave - MIGR::infinidb_vtable.hasInfiniDBTable = true; - - // return error if error status has been already set - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) - return ER_INTERNAL_ERROR; - - // @bug 2232. Basic SP support. Error out non support sp cases. - // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) - { - setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; - return ER_INTERNAL_ERROR; - } uint32_t sessionID = tid2sid(thd->thread_id); boost::shared_ptr csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID); @@ -4627,8 +4362,10 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE return 0; // @bug 2547. don't need to send the plan if it's impossible where for all unions. - if (MIGR::infinidb_vtable.impossibleWhereOnUnion) - return 0; +// TODO MCOL-2178 commenting the below out since cp_get_group_plan does not modify this variable +// which has a default value of false +// if (MIGR::infinidb_vtable.impossibleWhereOnUnion) +// return 0; string query; // Set the query text only once if the server executes @@ -4748,14 +4485,7 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE ci->rmParms.clear(); - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) - { - ci->tableMap[table] = ti; - } - else - { - ci->queryState = 1; - } + ci->queryState = 1; break; } @@ -4768,15 +4498,9 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE idbassert(hndl != 0); hndl->csc = csc; - // The next section is useless - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) - ti.conn_hndl = hndl; - else - { - ci->cal_conn_hndl = hndl; - ci->cal_conn_hndl_st.pop(); - ci->cal_conn_hndl_st.push(ci->cal_conn_hndl); - } + ci->cal_conn_hndl = hndl; + ci->cal_conn_hndl_st.pop(); + ci->cal_conn_hndl_st.push(ci->cal_conn_hndl); try { hndl->connect(); @@ -4796,18 +4520,11 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE // set query state to be in_process. Sometimes mysql calls rnd_init multiple // times, this makes sure plan only being generated and sent once. It will be // reset when query finishes in sm::end_query - MIGR::infinidb_vtable.isNewQuery = false; // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; ti.msTablePtr = table; - // MCOL-1052 - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; - - if ((MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_SELECT_VTABLE) || - (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) || - (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_QUERY)) { // MCOL-1601 Using stacks of ExeMgr conn hndls, table and scan contexts. ti.tpl_ctx = new sm::cpsm_tplh_t(); @@ -4862,27 +4579,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE CalpontSystemCatalog::ColType ctype; ti.tpl_scan_ctx->ctp.push_back(ctype); } - - // populate coltypes here for table mode because tableband gives treeoid for dictionary column - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) - { - CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(make_table(table->s->db.str, table->s->table_name.str), true); - - if (oidlist.size() != num_attr) - { - string emsg = "Size mismatch probably caused by front end out of sync"; - setError(thd, ER_INTERNAL_ERROR, emsg); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - goto internal_error; - } - - for (unsigned int j = 0; j < oidlist.size(); j++) - { - CalpontSystemCatalog::ColType ctype = csc->colType(oidlist[j].objnum); - ti.tpl_scan_ctx->ctp[ctype.colPosition] = ctype; - ti.tpl_scan_ctx->ctp[ctype.colPosition].colPosition = -1; - } - } } } @@ -4931,26 +4627,15 @@ int ha_calpont_impl_group_by_next(ha_calpont_group_by_handler* group_hand, TABLE { THD* thd = current_thd; - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) - return ER_INTERNAL_ERROR; - 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 HA_ERR_END_OF_FILE; // @bug 2547 - if (MIGR::infinidb_vtable.impossibleWhereOnUnion) - return HA_ERR_END_OF_FILE; +// TODO MCOL-2178 +// if (MIGR::infinidb_vtable.impossibleWhereOnUnion) +// return HA_ERR_END_OF_FILE; - // @bug 2232. Basic SP support - // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - /*if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) - { - setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; - return ER_INTERNAL_ERROR; - } - */ if (get_fe_conn_info_ptr() == NULL) set_fe_conn_info_ptr((void*)new cal_connection_info()); @@ -5043,8 +4728,8 @@ int ha_calpont_impl_group_by_end(ha_calpont_group_by_handler* group_hand, TABLE* thd->lex->sql_command == SQLCOM_LOAD)) return 0; - MIGR::infinidb_vtable.isNewQuery = true; - MIGR::infinidb_vtable.isUnion = false; +// TODO MCOL-2178 isUnion member only assigned, never used +// MIGR::infinidb_vtable.isUnion = false; if (get_fe_conn_info_ptr() != NULL) ci = reinterpret_cast(get_fe_conn_info_ptr()); @@ -5232,6 +4917,9 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) IDEBUG( cout << "pushdown_init for table " << endl ); THD* thd = current_thd; + gp_walk_info gwi; + gwi.thd = thd; + //check whether the system is ready to process statement. #ifndef _MSC_VER static DBRM dbrm(true); @@ -5241,14 +4929,12 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "The system is not yet ready to accept queries"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } else if (bSystemQueryReady < 0) { // Still not ready setError(thd, ER_INTERNAL_ERROR, "DBRM is not responding. Cannot accept queries"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; return ER_INTERNAL_ERROR; } #endif @@ -5260,30 +4946,6 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) thd_set_ha_data(thd, mcs_hton, reinterpret_cast(0x42)); } - // prevent "create table as select" from running on slave - MIGR::infinidb_vtable.hasInfiniDBTable = true; - - // return error is error status is already set - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ERROR) - return ER_INTERNAL_ERROR; - - // @bug 2232. Basic SP support. Error out non support sp cases. - // @bug 3939. Only error out for sp with select. Let pass for alter table in sp. - if (MIGR::infinidb_vtable.call_sp && (thd->lex)->sql_command != SQLCOM_ALTER_TABLE) - { - setError(thd, ER_CHECK_NOT_IMPLEMENTED, "This stored procedure syntax is not supported by Columnstore in this version"); - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_ERROR; - return ER_INTERNAL_ERROR; - } - - // WIP MCOL-2178 Remove this. - // mysql reads table twice for order by - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1 || - MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY) - { - return 0; - } - if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) { return 0; @@ -5291,7 +4953,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) //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); + return doUpdateDelete(thd, gwi); uint32_t sessionID = tid2sid(thd->thread_id); boost::shared_ptr csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID); @@ -5337,53 +4999,39 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) select_handler* sh = NULL; derived_handler* dh = NULL; - // update traceFlags according to the autoswitch state. replication query - // on slave are in table mode (create table as...) - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE || - (thd->slave_thread && MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_INIT)) - { - ci->traceFlags |= CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_DISABLE_VTABLE; - } - else - { - ci->traceFlags = (ci->traceFlags | CalpontSelectExecutionPlan::TRACE_TUPLE_OFF)^ - CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; - } + // update traceFlags according to the autoswitch state. + ci->traceFlags = (ci->traceFlags | CalpontSelectExecutionPlan::TRACE_TUPLE_OFF)^ + CalpontSelectExecutionPlan::TRACE_TUPLE_OFF; bool localQuery = (get_local_query(thd) > 0 ? true : false); { - //if (!ci->cal_conn_hndl || MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) - if ( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_CREATE_VTABLE) + ci->stats.reset(); // reset query stats + ci->stats.setStartTime(); + ci->stats.fUser = thd->main_security_ctx.user; + + if (thd->main_security_ctx.host) + ci->stats.fHost = thd->main_security_ctx.host; + else if (thd->main_security_ctx.host_or_ip) + ci->stats.fHost = thd->main_security_ctx.host_or_ip; + else + ci->stats.fHost = "unknown"; + + try { - ci->stats.reset(); // reset query stats - ci->stats.setStartTime(); - ci->stats.fUser = thd->main_security_ctx.user; + ci->stats.userPriority(ci->stats.fHost, ci->stats.fUser); + } + catch (std::exception& e) + { + string msg = string("Columnstore User Priority - ") + e.what(); + ci->warningMsg = msg; + } - if (thd->main_security_ctx.host) - ci->stats.fHost = thd->main_security_ctx.host; - else if (thd->main_security_ctx.host_or_ip) - ci->stats.fHost = thd->main_security_ctx.host_or_ip; - else - ci->stats.fHost = "unknown"; - - try - { - ci->stats.userPriority(ci->stats.fHost, ci->stats.fUser); - } - catch (std::exception& e) - { - string msg = string("Columnstore User Priority - ") + e.what(); - ci->warningMsg = msg; - } - - // if the previous query has error, re-establish the connection - if (ci->queryState != 0) - { - sm::sm_cleanup(ci->cal_conn_hndl); - ci->cal_conn_hndl = 0; - } + // if the previous query has error, re-establish the connection + if (ci->queryState != 0) + { + sm::sm_cleanup(ci->cal_conn_hndl); + ci->cal_conn_hndl = 0; } sm::sm_init(sessionID, &ci->cal_conn_hndl, localQuery); @@ -5407,7 +5055,6 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) // WIP MCOL-2178 std::cout << idb_mysql_query_str(thd) << std::endl; - if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) { if (!csep) csep.reset(new CalpontSelectExecutionPlan()); @@ -5434,20 +5081,17 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) csep->traceFlags(ci->traceFlags); - if (MIGR::infinidb_vtable.isInsertSelect) - csep->queryType(CalpontSelectExecutionPlan::INSERT_SELECT); - // cast the handler and get a plan. int status = 42; if (handler_info->hndl_type == mcs_handler_types_t::SELECT) { sh = reinterpret_cast(handler_info->hndl_ptr); - status = cs_get_select_plan(sh, thd, csep); + status = cs_get_select_plan(sh, thd, csep, gwi); } else if (handler_info->hndl_type == DERIVED) { dh = reinterpret_cast(handler_info->hndl_ptr); - status = cs_get_derived_plan(dh, thd, csep); + status = cs_get_derived_plan(dh, thd, csep, gwi); } // WIP MCOL-2178 Remove this @@ -5460,15 +5104,13 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) // WIP MCOL-2178 Remove this std::cout << "pushdown_init impossibleWhereOnUnion " << status << std::endl; // @bug 2547. don't need to send the plan if it's impossible where for all unions. - if (MIGR::infinidb_vtable.impossibleWhereOnUnion) + if (gwi.cs_vtable_impossible_where_on_union) { return 0; } string query; query.assign(idb_mysql_query_str(thd)); - //query.assign(MIGR::infinidb_vtable.original_query.ptr(), - // MIGR::infinidb_vtable.original_query.length()); csep->data(query); try @@ -5505,7 +5147,6 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) } }// end of execution plan generation - if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) { ByteStream msg; ByteStream emsgBs; @@ -5580,14 +5221,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) ci->rmParms.clear(); - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) - { - ci->tableMap[table] = ti; - } - else - { - ci->queryState = 1; - } + ci->queryState = 1; break; } @@ -5600,10 +5234,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) idbassert(hndl != 0); hndl->csc = csc; - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) - ti.conn_hndl = hndl; - else - ci->cal_conn_hndl = hndl; + ci->cal_conn_hndl = hndl; try { @@ -5624,7 +5255,6 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) // set query state to be in_process. Sometimes mysql calls rnd_init multiple // times, this makes sure plan only being generated and sent once. It will be // reset when query finishes in sm::end_query - MIGR::infinidb_vtable.isNewQuery = false; // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; @@ -5692,27 +5322,6 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) CalpontSystemCatalog::ColType ctype; ti.tpl_scan_ctx->ctp.push_back(ctype); } - - // populate coltypes here for table mode because tableband gives treeoid for dictionary column - if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE) - { - CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(make_table(table->s->db.str, table->s->table_name.str), true); - - if (oidlist.size() != num_attr) - { - string emsg = "Size mismatch probably caused by front end out of sync"; - setError(thd, ER_INTERNAL_ERROR, emsg); - CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID); - goto internal_error; - } - - for (unsigned int j = 0; j < oidlist.size(); j++) - { - CalpontSystemCatalog::ColType ctype = csc->colType(oidlist[j].objnum); - ti.tpl_scan_ctx->ctp[ctype.colPosition] = ctype; - ti.tpl_scan_ctx->ctp[ctype.colPosition].colPosition = -1; - } - } } } diff --git a/dbcon/mysql/ha_calpont_impl_if.h b/dbcon/mysql/ha_calpont_impl_if.h index 190ed620b..791aa999b 100644 --- a/dbcon/mysql/ha_calpont_impl_if.h +++ b/dbcon/mysql/ha_calpont_impl_if.h @@ -150,6 +150,8 @@ struct gp_walk_info // Kludge for MCOL-1472 bool inCaseStmt; + bool cs_vtable_is_update_with_derive; + bool cs_vtable_impossible_where_on_union; gp_walk_info() : sessionid(0), fatalParseError(false), @@ -166,8 +168,10 @@ struct gp_walk_info lastSub(0), derivedTbCnt(0), recursionLevel(-1), - recursionHWM(0), - inCaseStmt(false) + recursionHWM(0), + inCaseStmt(false), + cs_vtable_is_update_with_derive(false), + cs_vtable_impossible_where_on_union(false) {} ~gp_walk_info() {} @@ -338,8 +342,8 @@ const std::string infinidb_err_msg = "\nThe query includes syntax that is not su 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 cs_get_derived_plan(derived_handler* handler, THD* thd, execplan::SCSEP& csep); -int cs_get_select_plan(select_handler* handler, THD* thd, execplan::SCSEP& csep); +int cs_get_derived_plan(derived_handler* handler, THD* thd, execplan::SCSEP& csep, gp_walk_info& gwi); +int cs_get_select_plan(select_handler* handler, THD* thd, execplan::SCSEP& csep, gp_walk_info& gwi); int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, bool isUnion = false, bool isPushdownHand = 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); diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp index d6c81fc07..1b2981b84 100644 --- a/dbcon/mysql/ha_mcs_pushdown.cpp +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -148,15 +148,20 @@ static group_by_handler* create_calpont_group_by_handler(THD* thd, Query* query) { ha_calpont_group_by_handler* handler = NULL; + + // MCOL-2178 Disable SP support in the group_by_handler for now + // Check the session variable value to enable/disable use of + // group_by_handler + if (!get_group_by_handler(thd) || (thd->lex)->sphead) + { + return handler; + } + // same as thd->lex->current_select SELECT_LEX *select_lex = query->from->select_lex; // Create a handler if query is valid. See comments for details. - if //( MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_DISABLE_VTABLE - // WIP MCOL-2178 - //&& ( MIGR::infinidb_vtable_mode == 0 - // || MIGR::infinidb_vtable_mode == 2 ) - ( query->group_by || select_lex->with_sum_func ) //) + if ( query->group_by || select_lex->with_sum_func ) { bool unsupported_feature = false; // revisit SELECT_LEX for all units @@ -234,6 +239,14 @@ create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived) { ha_columnstore_derived_handler* handler = NULL; + // MCOL-2178 Disable SP support in the derived_handler for now + // Check the session variable value to enable/disable use of + // derived_handler + if (!get_derived_handler(thd) || (thd->lex)->sphead) + { + return handler; + } + SELECT_LEX_UNIT *unit= derived->derived; bool unsupported_feature = false; @@ -287,8 +300,6 @@ ha_columnstore_derived_handler::~ha_columnstore_derived_handler() /*********************************************************** * DESCRIPTION: * Execute the query and saves derived table query. - * ATM this function sets vtable_state and restores it afterwards - * since it reuses existed vtable code internally. * PARAMETERS: * * RETURN: @@ -305,16 +316,10 @@ int ha_columnstore_derived_handler::init_scan() derived_query.length(0); derived->derived->print(&derived_query, QT_ORDINARY); - // Save vtable_state to restore the after we inited. - MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; - mcs_handler_info mhi = mcs_handler_info(static_cast(this), DERIVED); // this::table is the place for the result set int rc = ha_cs_impl_pushdown_init(&mhi, table); - MIGR::infinidb_vtable.vtable_state = oldState; - DBUG_RETURN(rc); } @@ -322,8 +327,6 @@ int ha_columnstore_derived_handler::init_scan() /*********************************************************** * DESCRIPTION: * Fetches next row and saves it in the temp table - * ATM this function sets vtable_state and restores it - * afterwards since it reuses existed vtable code internally. * PARAMETERS: * * RETURN: @@ -334,15 +337,8 @@ int ha_columnstore_derived_handler::next_row() { DBUG_ENTER("ha_columnstore_derived_handler::next_row"); - // Save vtable_state to restore the after we inited. - MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; - int rc = ha_calpont_impl_rnd_next(table->record[0], table); - MIGR::infinidb_vtable.vtable_state = oldState; - DBUG_RETURN(rc); } @@ -350,8 +346,6 @@ int ha_columnstore_derived_handler::next_row() /*********************************************************** * DESCRIPTION: * Finishes the scan for derived handler - * ATM this function sets vtable_state and restores it - * afterwards since it reuses existed vtable code internally. * PARAMETERS: * * RETURN: @@ -362,13 +356,8 @@ int ha_columnstore_derived_handler::end_scan() { DBUG_ENTER("ha_columnstore_derived_handler::end_scan"); - MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; - int rc = ha_calpont_impl_rnd_end(table, true); - MIGR::infinidb_vtable.vtable_state = oldState; - DBUG_RETURN(rc); } @@ -413,12 +402,7 @@ int ha_calpont_group_by_handler::init_scan() { DBUG_ENTER("ha_calpont_group_by_handler::init_scan"); - // Save vtable_state to restore the after we inited. - MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - // MCOL-1052 Should be removed after cleaning the code up. - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; int rc = ha_calpont_impl_group_by_init(this, table); - MIGR::infinidb_vtable.vtable_state = oldState; DBUG_RETURN(rc); } @@ -470,6 +454,14 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) { ha_columnstore_select_handler* handler = NULL; + // MCOL-2178 Disable SP support in the select_handler for now. + // Check the session variable value to enable/disable use of + // select_handler + if (!get_select_handler(thd) || (thd->lex)->sphead) + { + return handler; + } + bool unsupported_feature = false; // Select_handler use the short-cut that effectively disables // INSERT..SELECT and LDI @@ -563,8 +555,6 @@ ha_columnstore_select_handler::~ha_columnstore_select_handler() /*********************************************************** * DESCRIPTION: * Execute the query and saves select table query. - * ATM this function sets vtable_state and restores it afterwards - * since it reuses existed vtable code internally. * PARAMETERS: * * RETURN: @@ -581,16 +571,10 @@ int ha_columnstore_select_handler::init_scan() select_query.length(0); select->print(thd, &select_query, QT_ORDINARY); - // Save vtable_state to restore the after we inited. - MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; - mcs_handler_info mhi = mcs_handler_info(static_cast(this), SELECT); // this::table is the place for the result set int rc = ha_cs_impl_pushdown_init(&mhi, table); - MIGR::infinidb_vtable.vtable_state = oldState; - DBUG_RETURN(rc); } @@ -598,8 +582,6 @@ int ha_columnstore_select_handler::init_scan() /*********************************************************** * DESCRIPTION: * Fetches next row and saves it in the temp table - * ATM this function sets vtable_state and restores it - * afterwards since it reuses existed vtable code internally. * PARAMETERS: * * RETURN: @@ -610,15 +592,8 @@ int ha_columnstore_select_handler::next_row() { DBUG_ENTER("ha_columnstore_select_handler::next_row"); - // Save vtable_state to restore the after we inited. - MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_CREATE_VTABLE; - int rc = ha_calpont_impl_rnd_next(table->record[0], table); - MIGR::infinidb_vtable.vtable_state = oldState; - DBUG_RETURN(rc); } @@ -626,8 +601,6 @@ int ha_columnstore_select_handler::next_row() /*********************************************************** * DESCRIPTION: * Finishes the scan for select handler - * ATM this function sets vtable_state and restores it - * afterwards since it reuses existed vtable code internally. * PARAMETERS: * * RETURN: @@ -638,13 +611,8 @@ int ha_columnstore_select_handler::end_scan() { DBUG_ENTER("ha_columnstore_select_handler::end_scan"); - MIGR::infinidb_state oldState = MIGR::infinidb_vtable.vtable_state; - MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; - int rc = ha_calpont_impl_rnd_end(table, true); - MIGR::infinidb_vtable.vtable_state = oldState; - DBUG_RETURN(rc); } diff --git a/dbcon/mysql/ha_mcs_sysvars.cpp b/dbcon/mysql/ha_mcs_sysvars.cpp index 01b0d6832..2dfadcb6a 100644 --- a/dbcon/mysql/ha_mcs_sysvars.cpp +++ b/dbcon/mysql/ha_mcs_sysvars.cpp @@ -71,6 +71,33 @@ static MYSQL_THDVAR_ULONGLONG( 1 ); +static MYSQL_THDVAR_BOOL( + select_handler, + PLUGIN_VAR_NOCMDARG, + "Enable/Disable the MCS select_handler", + NULL, + NULL, + 1 +); + +static MYSQL_THDVAR_BOOL( + derived_handler, + PLUGIN_VAR_NOCMDARG, + "Enable/Disable the MCS derived_handler", + NULL, + NULL, + 1 +); + +static MYSQL_THDVAR_BOOL( + group_by_handler, + PLUGIN_VAR_NOCMDARG, + "Enable/Disable the MCS group_by_handler", + NULL, + NULL, + 1 +); + // legacy system variables @@ -256,6 +283,9 @@ st_mysql_sys_var* mcs_system_variables[] = MYSQL_SYSVAR(compression_type), MYSQL_SYSVAR(fe_conn_info_ptr), MYSQL_SYSVAR(original_optimizer_flags), + MYSQL_SYSVAR(select_handler), + MYSQL_SYSVAR(derived_handler), + MYSQL_SYSVAR(group_by_handler), MYSQL_SYSVAR(decimal_scale), MYSQL_SYSVAR(use_decimal_scale), MYSQL_SYSVAR(ordered_only), @@ -307,6 +337,33 @@ void set_original_optimizer_flags(ulonglong ptr, THD* thd) THDVAR(current_thd, original_optimizer_flags) = (uint64_t)(ptr); } +bool get_select_handler(THD* thd) +{ + return ( thd == NULL ) ? false : THDVAR(thd, select_handler); +} +void set_select_handler(THD* thd, bool value) +{ + THDVAR(thd, select_handler) = value; +} + +bool get_derived_handler(THD* thd) +{ + return ( thd == NULL ) ? false : THDVAR(thd, derived_handler); +} +void set_derived_handler(THD* thd, bool value) +{ + THDVAR(thd, derived_handler) = value; +} + +bool get_group_by_handler(THD* thd) +{ + return ( thd == NULL ) ? false : THDVAR(thd, group_by_handler); +} +void set_group_by_handler(THD* thd, bool value) +{ + THDVAR(thd, group_by_handler) = value; +} + void set_compression_type(THD* thd, ulong value) { THDVAR(thd, compression_type) = value; diff --git a/dbcon/mysql/ha_mcs_sysvars.h b/dbcon/mysql/ha_mcs_sysvars.h index 3eea2e2ec..a977842bc 100644 --- a/dbcon/mysql/ha_mcs_sysvars.h +++ b/dbcon/mysql/ha_mcs_sysvars.h @@ -43,6 +43,15 @@ void set_fe_conn_info_ptr(void* ptr, THD* thd = NULL); ulonglong get_original_optimizer_flags(THD* thd = NULL); void set_original_optimizer_flags(ulonglong ptr, THD* thd = NULL); +bool get_select_handler(THD* thd); +void set_select_handler(THD* thd, bool value); + +bool get_derived_handler(THD* thd); +void set_derived_handler(THD* thd, bool value); + +bool get_group_by_handler(THD* thd); +void set_group_by_handler(THD* thd, bool value); + bool get_use_decimal_scale(THD* thd); void set_use_decimal_scale(THD* thd, bool value); diff --git a/dbcon/mysql/ha_view.cpp b/dbcon/mysql/ha_view.cpp index 8a6df6a0f..cfcfe3970 100644 --- a/dbcon/mysql/ha_view.cpp +++ b/dbcon/mysql/ha_view.cpp @@ -102,7 +102,8 @@ void View::transform() CalpontSystemCatalog::TableAliasName tn = make_aliasview("", "", alias, viewName); gwi.tbList.push_back(tn); gwi.tableMap[tn] = make_pair(0, table_ptr); - MIGR::infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init + // TODO MCOL-2178 isUnion member only assigned, never used + // MIGR::infinidb_vtable.isUnion = true; //by-pass the 2nd pass of rnd_init } else if (table_ptr->view) { diff --git a/dbcon/mysql/idb_mysql.h b/dbcon/mysql/idb_mysql.h index b16301159..cb842d740 100644 --- a/dbcon/mysql/idb_mysql.h +++ b/dbcon/mysql/idb_mysql.h @@ -111,70 +111,6 @@ inline char* idb_mysql_query_str(THD* thd) } } -class MIGR -{ - public: - enum infinidb_state - { - INFINIDB_INIT_CONNECT = 0, // intend to use to drop leftover vtable when logon. not being used now. - INFINIDB_INIT, - INFINIDB_CREATE_VTABLE, - INFINIDB_ALTER_VTABLE, - INFINIDB_SELECT_VTABLE, - INFINIDB_DROP_VTABLE, - INFINIDB_DISABLE_VTABLE, - INFINIDB_REDO_PHASE1, // post process requires to re-create vtable - INFINIDB_ORDER_BY, // for InfiniDB handler to ignore the 2nd scan for order by - INFINIDB_REDO_QUERY, // redo query with the normal mysql path - INFINIDB_ERROR_REDO_PHASE1, - INFINIDB_ERROR = 32, - }; - struct INFINIDB_VTABLE - { - String original_query; - String create_vtable_query; - String alter_vtable_query; - String select_vtable_query; - String drop_vtable_query; - String insert_vtable_query; - infinidb_state vtable_state; // flag for InfiniDB MySQL virtual table structure - bool autoswitch; - bool has_order_by; - bool duplicate_field_name; // @bug 1928. duplicate field name in create_phase will be ingored. - bool call_sp; - bool override_largeside_estimate; - void* cal_conn_info; - bool isUnion; - bool impossibleWhereOnUnion; - bool isInsertSelect; - bool isUpdateWithDerive; - bool isInfiniDBDML; // default false - bool hasInfiniDBTable; // default false - bool isNewQuery; - INFINIDB_VTABLE() : cal_conn_info(NULL) {init();} - void init() - { - //vtable_state = INFINIDB_INIT_CONNECT; - vtable_state = INFINIDB_DISABLE_VTABLE; - autoswitch = false; - has_order_by = false; - duplicate_field_name = false; - call_sp = false; - override_largeside_estimate = false; - isUnion = false; - impossibleWhereOnUnion = false; - isUpdateWithDerive = false; - isInfiniDBDML = false; - hasInfiniDBTable = false; - isNewQuery = true; - } - }; - - static INFINIDB_VTABLE infinidb_vtable; // InfiniDB custom structure - -}; - - #endif // vim:ts=4 sw=4: