diff --git a/dbcon/mysql/ha_mcs_impl.cpp b/dbcon/mysql/ha_mcs_impl.cpp index 0f9f91e29..f69982955 100644 --- a/dbcon/mysql/ha_mcs_impl.cpp +++ b/dbcon/mysql/ha_mcs_impl.cpp @@ -76,6 +76,7 @@ using namespace dataconvert; #include "sm.h" #include "ha_mcs_pushdown.h" +#include "ha_mcs_sysvars.h" #include "bytestream.h" #include "messagequeue.h" @@ -2692,11 +2693,12 @@ int ha_mcs_impl_write_row(const uchar* buf, TABLE* table, uint64_t rows_changed) ha_rows rowsInserted = 0; int rc = 0; - // ci->useCpimport = 2 means ALWAYS use cpimport, whether it's in a - // transaction or not. User should use this option very carefully since - // cpimport currently does not support rollbacks - if (((ci->useCpimport == 2) || - ((ci->useCpimport == 1) && (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) && + // ci->useCpimport = mcs_use_import_for_batchinsert_mode_t::ALWAYS means ALWAYS use + // cpimport, whether it's in a transaction or not. User should use this option + // very carefully since cpimport currently does not support rollbacks + if (((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ALWAYS) || + ((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ON) && + (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) && (!ci->singleInsert) && ((ci->isLoaddataInfile) || ((thd->lex)->sql_command == SQLCOM_INSERT) || ((thd->lex)->sql_command == SQLCOM_LOAD) || @@ -2832,20 +2834,21 @@ void ha_mcs_impl_start_bulk_insert(ha_rows rows, TABLE* table, bool is_cache_ins (thd->lex)->sql_command == SQLCOM_INSERT_SELECT || ci->isCacheInsert) && !ci->singleInsert ) { - ci->useCpimport = get_use_import_for_batchinsert(thd); + ci->useCpimport = get_use_import_for_batchinsert_mode(thd); if (((thd->lex)->sql_command == SQLCOM_INSERT) && (rows > 0)) - ci->useCpimport = 0; + ci->useCpimport = mcs_use_import_for_batchinsert_mode_t::OFF; // For now, disable cpimport for cache inserts if (ci->isCacheInsert) - ci->useCpimport = 0; + ci->useCpimport = mcs_use_import_for_batchinsert_mode_t::OFF; - // ci->useCpimport = 2 means ALWAYS use cpimport, whether it's in a - // transaction or not. User should use this option very carefully since - // cpimport currently does not support rollbacks - if ((ci->useCpimport == 2) || - ((ci->useCpimport == 1) && (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) //If autocommit on batch insert will use cpimport to load data + // ci->useCpimport = mcs_use_import_for_batchinsert_mode_t::ALWAYS means ALWAYS use + // cpimport, whether it's in a transaction or not. User should use this option + // very carefully since cpimport currently does not support rollbacks + if ((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ALWAYS) || + ((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ON) && + (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) //If autocommit on batch insert will use cpimport to load data { //store table info to connection info CalpontSystemCatalog::TableName tableName; @@ -3315,8 +3318,9 @@ int ha_mcs_impl_end_bulk_insert(bool abort, TABLE* table) // @bug 2515. Check command intead of vtable state if ( ( ((thd->lex)->sql_command == SQLCOM_INSERT) || ((thd->lex)->sql_command == SQLCOM_LOAD) || (thd->lex)->sql_command == SQLCOM_INSERT_SELECT || ci->isCacheInsert) && !ci->singleInsert ) { - if (((ci->useCpimport == 2) || - ((ci->useCpimport == 1) && (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) && + if (((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ALWAYS) || + ((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ON) && + (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) && (!ci->singleInsert) && ((ci->isLoaddataInfile) || ((thd->lex)->sql_command == SQLCOM_INSERT) || ((thd->lex)->sql_command == SQLCOM_LOAD) || @@ -3526,7 +3530,7 @@ int ha_mcs_impl_end_bulk_insert(bool abort, TABLE* table) ci->isCacheInsert = false; ci->tableOid = 0; ci->rowsHaveInserted = 0; - ci->useCpimport = 1; + ci->useCpimport = mcs_use_import_for_batchinsert_mode_t::ON; return rc; } diff --git a/dbcon/mysql/ha_mcs_impl_if.h b/dbcon/mysql/ha_mcs_impl_if.h index 69327c004..a82324208 100644 --- a/dbcon/mysql/ha_mcs_impl_if.h +++ b/dbcon/mysql/ha_mcs_impl_if.h @@ -32,6 +32,7 @@ #include #include "idb_mysql.h" +#include "ha_mcs_sysvars.h" struct st_ha_create_information; class ha_columnstore_select_handler; @@ -274,7 +275,7 @@ struct cal_connection_info filePtr(0), headerLength(0), useXbit(false), - useCpimport(1), + useCpimport(mcs_use_import_for_batchinsert_mode_t::ON), delimiter('\7'), affectedRows(0) { @@ -341,7 +342,7 @@ struct cal_connection_info FILE* filePtr; uint8_t headerLength; bool useXbit; - uint8_t useCpimport; + mcs_use_import_for_batchinsert_mode_t useCpimport; char delimiter; char enclosed_by; std::vector columnTypes; diff --git a/dbcon/mysql/ha_mcs_opt_rewrites.cpp b/dbcon/mysql/ha_mcs_opt_rewrites.cpp index 1e41089db..5f9b6009b 100644 --- a/dbcon/mysql/ha_mcs_opt_rewrites.cpp +++ b/dbcon/mysql/ha_mcs_opt_rewrites.cpp @@ -73,38 +73,52 @@ void in_subselect_rewrite_walk(const Item* item_arg, void* arg) } } -/* @brief opt_flag_unset_PS() - Unsets first_cond_optimization */ +// Sets SELECT_LEX::first_cond_optimization +void first_cond_optimization_flag_set(SELECT_LEX* select_lex) +{ + select_lex->first_cond_optimization = true; +} + +// Unsets SELECT_LEX::first_cond_optimization +void first_cond_optimization_flag_unset(SELECT_LEX* select_lex) +{ + select_lex->first_cond_optimization = false; +} + +/* @brief first_cond_optimization_flag_toggle() - Sets/Unsets first_cond_optimization */ /************************************************************ * DESCRIPTION: -* This function traverses derived tables to unset -* SELECT_LEX::first_cond_optimization: a marker to control -* optimizations executing PS. If set it allows to apply -* optimizations. If unset, it disables optimizations. +* This function traverses SELECT_LEX::table_list recursively +* to set/unset SELECT_LEX::first_cond_optimization: a marker +* to control optimizations executing PS. If set it allows to +* apply optimizations. If unset, it disables optimizations. * PARAMETERS: * select_lex - SELECT_LEX* that describes the query. +* func - Pointer to a function which either sets/unsets +* SELECT_LEX::first_cond_optimization ***********************************************************/ -void opt_flag_unset_PS(SELECT_LEX *select_lex) +void first_cond_optimization_flag_toggle(SELECT_LEX *select_lex, void (*func)(SELECT_LEX*)) { - TABLE_LIST *tbl; - List_iterator_fast li(select_lex->leaf_tables); - - while ((tbl= li++)) + for (TABLE_LIST *tl= select_lex->get_table_list(); tl; tl= tl->next_local) { - if (tbl->is_view_or_derived()) + if (tl->is_view_or_derived()) { - SELECT_LEX_UNIT *unit= tbl->get_unit(); + SELECT_LEX_UNIT *unit= tl->get_unit(); - for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) - opt_flag_unset_PS(sl); + if (unit) + { + for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) + { + first_cond_optimization_flag_toggle(sl, func); + } + } } } - if (select_lex->first_cond_optimization) - { - select_lex->first_cond_optimization= false; - } + (*func)(select_lex); } + /* @brief in_subselect_rewrite - Rewrites Item_in_subselect */ /************************************************************ * DESCRIPTION: diff --git a/dbcon/mysql/ha_mcs_opt_rewrites.h b/dbcon/mysql/ha_mcs_opt_rewrites.h index 1b323ec5f..56ec49a06 100644 --- a/dbcon/mysql/ha_mcs_opt_rewrites.h +++ b/dbcon/mysql/ha_mcs_opt_rewrites.h @@ -21,6 +21,8 @@ #include "idb_mysql.h" bool in_subselect_rewrite(SELECT_LEX *select_lex); -void opt_flag_unset_PS(SELECT_LEX *select_lex); +void first_cond_optimization_flag_toggle(SELECT_LEX *select_lex, void (*func)(SELECT_LEX*)); +void first_cond_optimization_flag_unset(SELECT_LEX*); +void first_cond_optimization_flag_set(SELECT_LEX*); #endif diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp index d0fc84cbd..e18d44d2d 100644 --- a/dbcon/mysql/ha_mcs_pushdown.cpp +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -21,23 +21,12 @@ void check_walk(const Item* item, void* arg); -void disable_indices_for_CEJ(THD *thd_) +void restore_query_state(ha_columnstore_select_handler* handler) { - TABLE_LIST* global_list; - for (global_list = thd_->lex->query_tables; global_list; global_list = global_list->next_global) + for (auto iter = handler->tableOuterJoinMap.begin(); + iter != handler->tableOuterJoinMap.end(); iter++) { - // MCOL-652 - doing this with derived tables can cause bad things to happen - if (!global_list->derived) - { - global_list->index_hints = new (thd_->mem_root) List(); - - global_list->index_hints->push_front(new (thd_->mem_root) - Index_hint(INDEX_HINT_USE, - INDEX_HINT_MASK_JOIN, - NULL, - 0), thd_->mem_root); - - } + iter->first->outer_join = iter->second; } } @@ -407,7 +396,8 @@ create_columnstore_group_by_handler(THD* thd, Query* query) // 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. There is no GBH if SH works for the query. - if (get_select_handler(thd) || !get_group_by_handler(thd) || (thd->lex)->sphead) + if ((get_select_handler_mode(thd) == mcs_select_handler_mode_t::ON) || + !get_group_by_handler(thd) || (thd->lex)->sphead) { return handler; } @@ -754,14 +744,14 @@ int ha_mcs_group_by_handler::end_scan() select_handler* create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) { - ha_columnstore_select_handler* handler = NULL; + mcs_select_handler_mode_t select_handler_mode = get_select_handler_mode(thd); // Check the session variable value to enable/disable use of // select_handler - if (!get_select_handler(thd) || + if ((select_handler_mode == mcs_select_handler_mode_t::OFF) || ((thd->lex)->sphead && !get_select_handler_in_stored_procedures(thd))) { - return handler; + return nullptr; } // Flag to indicate if this is a prepared statement @@ -774,14 +764,14 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) !((select_dumpvar *)(thd->lex)->result)->var_list.is_empty()) && (!isPS)) { - return handler; + return nullptr; } // Select_handler couldn't properly process UPSERT..SELECT if ((thd->lex)->sql_command == SQLCOM_INSERT_SELECT && thd->lex->duplicates == DUP_UPDATE) { - return handler; + return nullptr; } // Iterate and traverse through the item list and the JOIN cond @@ -792,71 +782,198 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) { if (check_user_var(table_ptr->select_lex)) { - return handler; + return nullptr; } } // We apply dedicated rewrites from MDB here so MDB's data structures // becomes dirty and CS has to raise an error in case of any problem // or unsupported feature. - handler = new ha_columnstore_select_handler(thd, select_lex); + ha_columnstore_select_handler* handler = + new ha_columnstore_select_handler(thd, select_lex); + JOIN *join = select_lex->join; - bool unsupported_feature = false; + + if (select_lex->first_cond_optimization && + select_lex->handle_derived(thd->lex, DT_MERGE)) { + if (!thd->is_error()) + { + my_printf_error(ER_INTERNAL_ERROR, "%s", MYF(0), + "Error occured in select_lex::handle_derived()"); + } + + return handler; + } + + // This is partially taken from JOIN::optimize_inner() in sql/sql_select.cc + if (select_lex->first_cond_optimization) + { + create_explain_query_if_not_exists(thd->lex, thd->mem_root); Query_arena *arena, backup; arena = thd->activate_stmt_arena_if_needed(&backup); - disable_indices_for_CEJ(thd); + COND* conds = join->conds; + select_lex->where = conds; + + if (isPS) + { + select_lex->prep_where = conds ? conds->copy_andor_structure(thd) : 0; + } + + select_lex->update_used_tables(); if (arena) thd->restore_active_arena(arena, &backup); - if (select_lex->handle_derived(thd->lex, DT_MERGE)) +#ifdef DEBUG_WALK_COND + if (conds) { - unsupported_feature = true; - handler->err_msg.assign("create_columnstore_select_handler(): \ - Internal error occured in SL::handle_derived()"); + conds->traverse_cond(cal_impl_if::debug_walk, NULL, Item::POSTFIX); + } +#endif + } + + // Attempt to execute the query using the select handler. + // If query execution fails and columnstore_select_handler=AUTO, + // fallback to table mode. + // Skip execution for EXPLAIN queries + if (!thd->lex->describe) + { + // This is taken from JOIN::optimize() + join->fields= &select_lex->item_list; + + // Instantiate handler::table, which is the place for the result set. + if (handler->prepare()) + { + // check fallback + if (select_handler_mode == mcs_select_handler_mode_t::AUTO) // columnstore_select_handler=AUTO + { + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, + "MCS select_handler execution failed. Falling back to server execution"); + restore_query_state(handler); + delete handler; + return nullptr; + } + + // error out + if (!thd->is_error()) + { + my_printf_error(ER_INTERNAL_ERROR, "%s", MYF(0), + "Error occured in handler->prepare()"); + } + + return handler; } - COND *conds = nullptr; - if (!unsupported_feature) - { - // Rewrite once for PS - // Refer to JOIN::optimize_inner() in sql/sql_select.cc - // for details on the optimizations performed in this block. - if (select_lex->first_cond_optimization) - { - create_explain_query_if_not_exists(thd->lex, thd->mem_root); - arena = thd->activate_stmt_arena_if_needed(&backup); - select_lex->first_cond_optimization= false; - conds = join->conds; - select_lex->where = conds; + // Prepare query execution + // This is taken from JOIN::exec_inner() + if (!select_lex->outer_select() && // (1) + select_lex != select_lex->master_unit()->fake_select_lex) // (2) + thd->lex->set_limit_rows_examined(); - if (isPS) + if (!join->tables_list && (join->table_count || !select_lex->with_sum_func) && + !select_lex->have_window_funcs()) + { + if (!thd->is_error()) + { + restore_query_state(handler); + delete handler; + return nullptr; + } + + return handler; + } + + if (!join->zero_result_cause && + join->exec_const_cond && !join->exec_const_cond->val_int()) + join->zero_result_cause = "Impossible WHERE noticed after reading const tables"; + + // We've called exec_const_cond->val_int(). This may have caused an error. + if (unlikely(thd->is_error())) + { + // error out + handler->pushdown_init_rc = 1; + return handler; + } + + if (join->zero_result_cause) + { + if (join->select_lex->have_window_funcs() && join->send_row_on_empty_set()) + { + join->const_tables = join->table_count; + join->first_select = sub_select_postjoin_aggr; + } + else + { + if (!thd->is_error()) { - select_lex->prep_where = conds ? conds->copy_andor_structure(thd) : 0; + restore_query_state(handler); + delete handler; + return nullptr; } - select_lex->update_used_tables(); - - if (arena) - thd->restore_active_arena(arena, &backup); - - // Unset SL::first_cond_optimization - opt_flag_unset_PS(select_lex); + return handler; } + } -#ifdef DEBUG_WALK_COND - if (conds) + if ((join->select_lex->options & OPTION_SCHEMA_TABLE) && + get_schema_tables_result(join, PROCESSED_BY_JOIN_EXEC)) + { + if (!thd->is_error()) { - conds->traverse_cond(cal_impl_if::debug_walk, NULL, Item::POSTFIX); + my_printf_error(ER_INTERNAL_ERROR, "%s", MYF(0), + "Error occured in get_schema_tables_result()"); } -#endif + + return handler; + } + + handler->scan_initialized = true; + mcs_handler_info mhi(reinterpret_cast(handler), SELECT); + + if ((handler->pushdown_init_rc = ha_mcs_impl_pushdown_init(&mhi, handler->table))) + { + // check fallback + if (select_handler_mode == mcs_select_handler_mode_t::AUTO) + { + restore_query_state(handler); + std::ostringstream oss; + oss << "MCS select_handler execution failed"; + + if (thd->is_error()) + { + oss << " due to: "; + oss << thd->get_stmt_da()->sql_errno() << ": " ; + oss << thd->get_stmt_da()->message(); + oss << " F"; + thd->clear_error(); + } + else + { + oss << ", f"; + } + + oss << "alling back to server execution"; + thd->get_stmt_da()->clear_warning_info(thd->query_id); + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, oss.str().c_str()); + delete handler; + return nullptr; + } + + if (!thd->is_error()) + { + my_printf_error(ER_INTERNAL_ERROR, "%s", MYF(0), + "Error occured in ha_mcs_impl_pushdown_init()"); + } + } + + // Unset select_lex::first_cond_optimization + if (select_lex->first_cond_optimization) + { + first_cond_optimization_flag_toggle(select_lex, &first_cond_optimization_flag_unset); } } - // We shouldn't raise error now so set an error to raise it later in init_SH. - handler->rewrite_error = unsupported_feature; - // Return SH even if init fails return handler; } @@ -869,10 +986,13 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) ***********************************************************/ ha_columnstore_select_handler::ha_columnstore_select_handler(THD *thd, SELECT_LEX* select_lex) - : select_handler(thd, mcs_hton) + : select_handler(thd, mcs_hton), + prepared(false), + scan_ended(false), + scan_initialized(false), + pushdown_init_rc(0) { - select = select_lex; - rewrite_error = false; + select = select_lex; } /*********************************************************** @@ -881,6 +1001,10 @@ ha_columnstore_select_handler::ha_columnstore_select_handler(THD *thd, ***********************************************************/ ha_columnstore_select_handler::~ha_columnstore_select_handler() { + if (scan_initialized && !scan_ended) + { + end_scan(); + } } /*@brief Initiate the query for select_handler */ @@ -895,27 +1019,7 @@ ha_columnstore_select_handler::~ha_columnstore_select_handler() int ha_columnstore_select_handler::init_scan() { DBUG_ENTER("ha_columnstore_select_handler::init_scan"); - - int rc = 0; - - if (!rewrite_error) - { - // handler::table is the place for the result set - // Skip execution for EXPLAIN queries - if (!thd->lex->describe) - { - mcs_handler_info mhi(reinterpret_cast(this), SELECT); - rc = ha_mcs_impl_pushdown_init(&mhi, this->table); - } - } - else - { - my_printf_error(ER_INTERNAL_ERROR, "%s", MYF(0), err_msg.c_str()); - sql_print_error("%s", err_msg.c_str()); - rc = ER_INTERNAL_ERROR; - } - - DBUG_RETURN(rc); + DBUG_RETURN(pushdown_init_rc); } /*@brief Fetch next row for select_handler */ @@ -951,7 +1055,30 @@ int ha_columnstore_select_handler::end_scan() { DBUG_ENTER("ha_columnstore_select_handler::end_scan"); + scan_ended = true; + int rc = ha_mcs_impl_rnd_end(table, true); DBUG_RETURN(rc); } + +// Copy of select_handler::prepare (see sql/select_handler.cc), +// with an added if guard +bool ha_columnstore_select_handler::prepare() +{ + DBUG_ENTER("ha_columnstore_select_handler::prepare"); + + if (prepared) + DBUG_RETURN(pushdown_init_rc ? true : false); + + prepared = true; + + if ((!table && !(table = create_tmp_table(thd, select))) || + table->fill_item_list(&result_columns)) + { + pushdown_init_rc = 1; + DBUG_RETURN(true); + } + + DBUG_RETURN(false); +} diff --git a/dbcon/mysql/ha_mcs_pushdown.h b/dbcon/mysql/ha_mcs_pushdown.h index 012dac343..a5d037914 100644 --- a/dbcon/mysql/ha_mcs_pushdown.h +++ b/dbcon/mysql/ha_mcs_pushdown.h @@ -138,10 +138,12 @@ class ha_columnstore_select_handler: public select_handler { private: COLUMNSTORE_SHARE *share; + bool prepared; + bool scan_ended; public: - bool rewrite_error; - std::string err_msg; + bool scan_initialized; + int pushdown_init_rc; // MCOL-4525 Store the original TABLE_LIST::outer_join value in a hash map. // This will be used to restore to the original state later in case // query execution fails using the select_handler. @@ -151,6 +153,7 @@ public: int init_scan() override; int next_row() override; int end_scan() override; + bool prepare() override; }; #endif diff --git a/dbcon/mysql/ha_mcs_sysvars.cpp b/dbcon/mysql/ha_mcs_sysvars.cpp index a0a925e40..1909b4510 100644 --- a/dbcon/mysql/ha_mcs_sysvars.cpp +++ b/dbcon/mysql/ha_mcs_sysvars.cpp @@ -71,13 +71,28 @@ static MYSQL_THDVAR_ULONGLONG( 1 ); -static MYSQL_THDVAR_BOOL( +const char* mcs_select_handler_mode_values[] = { + "OFF", + "ON", + "AUTO", + NullS +}; + +static TYPELIB mcs_select_handler_mode_values_lib = { + array_elements(mcs_select_handler_mode_values) - 1, + "mcs_select_handler_mode_values", + mcs_select_handler_mode_values, + NULL +}; + +static MYSQL_THDVAR_ENUM( select_handler, - PLUGIN_VAR_NOCMDARG, - "Enable/Disable the MCS select_handler", - NULL, - NULL, - 1 + PLUGIN_VAR_RQCMDARG, + "Set the MCS select_handler to Disabled, Enabled, or Automatic", + NULL, // check + NULL, // update + 1, // default + &mcs_select_handler_mode_values_lib // values lib ); static MYSQL_THDVAR_BOOL( @@ -288,17 +303,17 @@ static MYSQL_THDVAR_ULONG( 1 // block size ); -const char* mcs_use_import_for_batchinsert_values[] = { +const char* mcs_use_import_for_batchinsert_mode_values[] = { "OFF", "ON", "ALWAYS", NullS }; -static TYPELIB mcs_use_import_for_batchinsert_values_lib = { - array_elements(mcs_use_import_for_batchinsert_values) - 1, - "mcs_use_import_for_batchinsert_values", - mcs_use_import_for_batchinsert_values, +static TYPELIB mcs_use_import_for_batchinsert_mode_values_lib = { + array_elements(mcs_use_import_for_batchinsert_mode_values) - 1, + "mcs_use_import_for_batchinsert_mode_values", + mcs_use_import_for_batchinsert_mode_values, NULL }; @@ -309,7 +324,7 @@ static MYSQL_THDVAR_ENUM( NULL, // check NULL, // update 1, // default - &mcs_use_import_for_batchinsert_values_lib // values lib + &mcs_use_import_for_batchinsert_mode_values_lib // values lib ); static MYSQL_THDVAR_BOOL( @@ -412,11 +427,12 @@ void set_original_optimizer_flags(ulonglong ptr, THD* thd) THDVAR(current_thd, original_optimizer_flags) = (uint64_t)(ptr); } -bool get_select_handler(THD* thd) +mcs_select_handler_mode_t get_select_handler_mode(THD* thd) { - return ( thd == NULL ) ? false : THDVAR(thd, select_handler); + return ( thd == NULL ) ? mcs_select_handler_mode_t::ON : + (mcs_select_handler_mode_t) THDVAR(thd, select_handler); } -void set_select_handler(THD* thd, bool value) +void set_select_handler_mode(THD* thd, ulong value) { THDVAR(thd, select_handler) = value; } @@ -585,12 +601,12 @@ void set_local_query(THD* thd, ulong value) THDVAR(thd, local_query) = value; } -mcs_use_import_for_batchinsert_t get_use_import_for_batchinsert(THD* thd) +mcs_use_import_for_batchinsert_mode_t get_use_import_for_batchinsert_mode(THD* thd) { - return ( thd == NULL ) ? mcs_use_import_for_batchinsert_t::ON : - (mcs_use_import_for_batchinsert_t) THDVAR(thd, use_import_for_batchinsert); + return ( thd == NULL ) ? mcs_use_import_for_batchinsert_mode_t::ON : + (mcs_use_import_for_batchinsert_mode_t) THDVAR(thd, use_import_for_batchinsert); } -void set_use_import_for_batchinsert(THD* thd, ulong value) +void set_use_import_for_batchinsert_mode(THD* thd, ulong value) { THDVAR(thd, use_import_for_batchinsert) = value; } diff --git a/dbcon/mysql/ha_mcs_sysvars.h b/dbcon/mysql/ha_mcs_sysvars.h index b8e3884b7..faeed3880 100644 --- a/dbcon/mysql/ha_mcs_sysvars.h +++ b/dbcon/mysql/ha_mcs_sysvars.h @@ -33,13 +33,20 @@ enum mcs_compression_type_t { SNAPPY = 2 }; -// use_import_for_batchinsert -enum mcs_use_import_for_batchinsert_t { +// use_import_for_batchinsert mode +enum class mcs_use_import_for_batchinsert_mode_t { OFF = 0, ON = 1, ALWAYS = 2 }; +// select_handler mode +enum class mcs_select_handler_mode_t { + OFF = 0, + ON = 1, + AUTO = 2 +}; + // simple setters/getters const char* get_original_query(THD* thd); void set_original_query(THD* thd, char* query); @@ -53,8 +60,8 @@ 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); +mcs_select_handler_mode_t get_select_handler_mode(THD* thd); +void set_select_handler_mode(THD* thd, ulong value); bool get_derived_handler(THD* thd); void set_derived_handler(THD* thd, bool value); @@ -107,8 +114,8 @@ void set_decimal_overflow_check(THD* thd, bool value); ulong get_local_query(THD* thd); void set_local_query(THD* thd, ulong value); -mcs_use_import_for_batchinsert_t get_use_import_for_batchinsert(THD* thd); -void set_use_import_for_batchinsert(THD* thd, ulong value); +mcs_use_import_for_batchinsert_mode_t get_use_import_for_batchinsert_mode(THD* thd); +void set_use_import_for_batchinsert_mode(THD* thd, ulong value); ulong get_import_for_batchinsert_delimiter(THD* thd); void set_import_for_batchinsert_delimiter(THD* thd, ulong value); diff --git a/dbcon/mysql/idb_mysql.h b/dbcon/mysql/idb_mysql.h index 921505f53..0ee6e857f 100644 --- a/dbcon/mysql/idb_mysql.h +++ b/dbcon/mysql/idb_mysql.h @@ -81,6 +81,7 @@ template bool isnan(T); #include "select_handler.h" #include "rpl_rli.h" #include "my_dbug.h" +#include "sql_show.h" // Now clean up the pollution as best we can... #include "mcsconfig_conflicting_defs_undef.h" diff --git a/mysql-test/columnstore/basic/r/mcol-424.result b/mysql-test/columnstore/basic/r/mcol-424.result new file mode 100644 index 000000000..067adeb5d --- /dev/null +++ b/mysql-test/columnstore/basic/r/mcol-424.result @@ -0,0 +1,33 @@ +# MCOL-424 +# Cross engine subquery losing where clause causing incorrect results +DROP DATABASE IF EXISTS mcol424; +CREATE DATABASE mcol424; +USE mcol424; +CREATE USER IF NOT EXISTS'cejuser'@'localhost' IDENTIFIED BY 'Vagrant1|0000001'; +GRANT ALL PRIVILEGES ON *.* TO 'cejuser'@'localhost'; +FLUSH PRIVILEGES; +CREATE TABLE `trans_test` ( +`id` int(11) DEFAULT NULL, +`member_id` int(11) DEFAULT NULL, +`name` varchar(50) DEFAULT NULL +) ENGINE=Columnstore DEFAULT CHARSET=latin1; +insert into `trans_test`(`id`,`member_id`,`name`) values (1,1,'trans 1'); +insert into `trans_test`(`id`,`member_id`,`name`) values (2,2,'trans 2'); +insert into `trans_test`(`id`,`member_id`,`name`) values (3,1,'trans 3'); +insert into `trans_test`(`id`,`member_id`,`name`) values (4,2,'trans 4'); +insert into `trans_test`(`id`,`member_id`,`name`) values (5,1,'trans 5'); +CREATE TABLE `member_test` ( +`id` int(11) NOT NULL AUTO_INCREMENT, +`name` varchar(50) NOT NULL, +PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +insert into `member_test`(`id`,`name`) values (1,'member 1'); +insert into `member_test`(`id`,`name`) values (2,'member 2'); +insert into `member_test`(`id`,`name`) values (3,'member 3'); +SELECT * FROM trans_test t WHERE t.`member_id` IN (SELECT id FROM member_test WHERE id =1); +id member_id name +1 1 trans 1 +3 1 trans 3 +5 1 trans 5 +DROP USER 'cejuser'@'localhost'; +DROP DATABASE mcol424; diff --git a/mysql-test/columnstore/basic/r/mcol-4525.result b/mysql-test/columnstore/basic/r/mcol-4525.result new file mode 100644 index 000000000..4ecfd39b4 --- /dev/null +++ b/mysql-test/columnstore/basic/r/mcol-4525.result @@ -0,0 +1,337 @@ +# MCOL-4525 +# Automatic select_handler +# columnstore_select_handler=AUTO allows query execution +# to fallback to the server, in case the execution using +# select_handler fails. +SET default_storage_engine=columnstore; +DROP DATABASE IF EXISTS mcol4525; +CREATE DATABASE mcol4525; +USE mcol4525; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1, 1), (5, 0); +SET columnstore_select_handler=ON; +SELECT a xor b FROM t1; +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +SET columnstore_select_handler=AUTO; +SELECT a xor b FROM t1; +a xor b +0 +1 +SET columnstore_select_handler=ON; +SELECT DISTINCT a FROM t1 WHERE a IN (SELECT a FROM t1) OR a IN (SELECT a FROM t1); +ERROR HY000: Internal error: IDB-3033: Correlated subquery within OR operator is currently not supported. +SET columnstore_select_handler=AUTO; +SELECT DISTINCT a FROM t1 WHERE a IN (SELECT a FROM t1) OR a IN (SELECT a FROM t1); +a +1 +5 +DROP TABLE t1; +CREATE TABLE bug4767 (c1 float, c2 double); +INSERT INTO bug4767 VALUES (1.234, 3.4556), (2.3345456, 2.3345456); +SET columnstore_select_handler=ON; +SELECT * FROM bug4767 a JOIN bug4767 b ON (a.c1=b.c2); +ERROR HY000: Internal error: IDB-1002: 'a' and 'b' have incompatible column type specified for join condition. +SET columnstore_select_handler=AUTO; +SELECT * FROM bug4767 a JOIN bug4767 b ON (a.c1=b.c2); +c1 c2 c1 c2 +DROP TABLE bug4767; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2); +CREATE TABLE t2 (b int); +INSERT INTO t2 VALUES (2); +SET columnstore_select_handler=ON; +SELECT a FROM t1 WHERE a IN (SELECT a FROM t2); +ERROR HY000: Internal error: IDB-1000: 't1' and 't2' are not joined. +SET columnstore_select_handler=AUTO; +SELECT a FROM t1 WHERE a IN (SELECT a FROM t2); +a +1 +2 +DROP TABLE t1; +DROP TABLE t2; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2), (3); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (2), (3); +CREATE TABLE t3 (a int); +INSERT INTO t3 VALUES (3); +SET columnstore_select_handler=ON; +SELECT * FROM t1 JOIN t2 ON t1.a=t2.a JOIN t3 ON t2.a=t3.a AND t3.a=t1.a; +ERROR HY000: Internal error: IDB-1003: Circular joins are not supported. +SET columnstore_select_handler=AUTO; +SELECT * FROM t1 JOIN t2 ON t1.a=t2.a JOIN t3 ON t2.a=t3.a AND t3.a=t1.a; +a a a +3 3 3 +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +CREATE TABLE l(c1 int, c2 int); +CREATE TABLE r(c1 int, c2 int); +CREATE TABLE s(c1 int, c2 int); +INSERT INTO l VALUES (1, 1); +INSERT INTO l VALUES (2, 2); +INSERT INTO r VALUES (1, 1); +INSERT INTO r VALUES (5, 5); +INSERT INTO s VALUES (1, 1); +INSERT INTO s VALUES (9, 9); +SET columnstore_select_handler=ON; +SELECT 'q1', l.c1, r.c1 FROM l LEFT JOIN r ON l.c1 = r.c1 AND l.c1 IN (SELECT c1 FROM s) ORDER BY 1, 2, 3; +ERROR HY000: Internal error: IDB-1015: Subquery on OUTER JOIN ON clause is currently not supported. +SET columnstore_select_handler=AUTO; +SELECT 'q1', l.c1, r.c1 FROM l LEFT JOIN r ON l.c1 = r.c1 AND l.c1 IN (SELECT c1 FROM s) ORDER BY 1, 2, 3; +q1 c1 c1 +q1 1 1 +q1 2 NULL +DROP TABLE l; +DROP TABLE r; +DROP TABLE s; +CREATE TABLE t1 (col1 int, col2 varchar(5), col_t1 int); +INSERT INTO t1 VALUES(10,'hello',10); +INSERT INTO t1 VALUES(20,'hello',20); +INSERT INTO t1 VALUES(30,'hello',30); +INSERT INTO t1 VALUES(10,'bye',10); +INSERT INTO t1 VALUES(10,'sam',10); +INSERT INTO t1 VALUES(10,'bob',10); +SET columnstore_select_handler=ON; +SELECT SUM(col1) AS col2 FROM t1 GROUP BY col2; +ERROR 42000: The storage engine for the table doesn't support IDB-2016: Non supported item 'col2' on the GROUP BY list. +SELECT col1 c FROM t1 ORDER BY AVG(col1); +ERROR HY000: Internal error: IDB-2021: 'c' is not in GROUP BY clause. All non-aggregate columns in the SELECT and ORDER BY clause must be included in the GROUP BY clause. +SET columnstore_select_handler=AUTO; +SELECT SUM(col1) AS col2 FROM t1 GROUP BY col2; +col2 +10 +10 +60 +10 +SELECT col1 c FROM t1 ORDER BY AVG(col1); +c +10 +DROP TABLE t1; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1); +SET columnstore_select_handler=ON; +SELECT minute(sleep(a)) FROM t1; +ERROR 42000: The storage engine for the table doesn't support IDB-1001: Function 'minute' isn't supported. +SET columnstore_select_handler=AUTO; +SELECT minute(sleep(a)) FROM t1; +minute(sleep(a)) +0 +DROP TABLE t1; +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (2), (3); +SET columnstore_select_handler=ON; +SELECT SUM(a) FROM t1 WHERE EXISTS (SELECT MAX(a) FROM t2); +ERROR HY000: Internal error: IDB-3008: Aggregate function in EXISTS subquery is currently not supported. +SELECT * FROM t1 WHERE (a,a) < (SELECT a,a FROM t2 WHERE a=2); +ERROR HY000: Internal error: IDB-3006: This operator cannot be used with lists. +SET columnstore_select_handler=AUTO; +SELECT SUM(a) FROM t1 WHERE EXISTS (SELECT MAX(a) FROM t2); +SUM(a) +3 +SELECT * FROM t1 WHERE (a,a) < (SELECT a,a FROM t2 WHERE a=2); +a +1 +DROP TABLE t1; +DROP TABLE t2; +CREATE TABLE gen (i int, i2 int); +INSERT INTO gen VALUES (1,0), (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (1,7), (1,8), (1,9); +SET columnstore_select_handler=ON; +SELECT i2, (SELECT MAX(g2.i2) FROM gen g2 WHERE g2.i = g1.i AND g2.i2 > g1.i2) sub FROM gen g1; +ERROR HY000: Internal error: IDB-3035: Not equal comparison between a column within a subquery with an aggregate result and a column outside of the subquery is not supported. +SET columnstore_select_handler=AUTO; +SELECT i2, (SELECT MAX(g2.i2) FROM gen g2 WHERE g2.i = g1.i AND g2.i2 > g1.i2) sub FROM gen g1; +i2 sub +0 9 +1 9 +2 9 +3 9 +4 9 +5 9 +6 9 +7 9 +8 9 +9 NULL +DROP TABLE gen; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (0), (1), (2), (3); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (2), (3); +CREATE VIEW v1 AS SELECT a FROM t1 WHERE a > 1; +SET columnstore_select_handler=ON; +SELECT * FROM t1 LEFT JOIN (t2 AS t, v1) ON v1.a=t1.a ORDER BY 1; +ERROR HY000: Internal error: IDB-1000: 'v1, t1' and 't' are not joined. +SET columnstore_select_handler=AUTO; +SELECT * FROM t1 LEFT JOIN (t2 AS t, v1) ON v1.a=t1.a ORDER BY 1; +a a a +0 NULL NULL +1 NULL NULL +2 2 2 +2 3 2 +3 2 3 +3 3 3 +DROP TABLE t1; +DROP TABLE t2; +DROP VIEW v1; +CREATE TABLE c1 (a int); +INSERT INTO c1 VALUES (1), (2), (3); +CREATE TABLE c2 (a int); +INSERT INTO c2 VALUES (2); +CREATE TABLE c3 (a int); +CREATE TABLE c4 (a int); +CREATE TABLE c5 (a int); +SET columnstore_select_handler=ON; +SELECT c1.a AS col1, c2.a AS col2, c1.a xor c2.a FROM +c1 LEFT JOIN +( +(c2 LEFT JOIN c3 ON c2.a=c3.a) LEFT JOIN +(c4 JOIN c5 ON c4.a=c5.a) +ON c2.a=c4.a +) +ON c1.a=c2.a WHERE c2.a < 100; +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +SET columnstore_select_handler=AUTO; +SELECT c1.a AS col1, c2.a AS col2, c1.a xor c2.a FROM +c1 LEFT JOIN +( +(c2 LEFT JOIN c3 ON c2.a=c3.a) LEFT JOIN +(c4 JOIN c5 ON c4.a=c5.a) +ON c2.a=c4.a +) +ON c1.a=c2.a WHERE c2.a < 100; +col1 col2 c1.a xor c2.a +2 2 0 +DROP TABLE c1; +DROP TABLE c2; +DROP TABLE c3; +DROP TABLE c4; +DROP TABLE c5; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2), (3), (4); +SET columnstore_select_handler=ON; +PREPARE stmt FROM "SELECT a, a xor 0 FROM t1 WHERE a > 1 AND a < 4"; +EXECUTE stmt; +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +EXECUTE stmt; +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +EXECUTE stmt; +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +EXECUTE stmt; +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +DROP PREPARE stmt; +SET columnstore_select_handler=AUTO; +PREPARE stmt FROM "SELECT a, a xor 0 FROM t1 WHERE a > 1 AND a < 4"; +EXECUTE stmt; +a a xor 0 +2 1 +3 1 +EXECUTE stmt; +a a xor 0 +2 1 +3 1 +EXECUTE stmt; +a a xor 0 +2 1 +3 1 +EXECUTE stmt; +a a xor 0 +2 1 +3 1 +EXECUTE stmt; +a a xor 0 +2 1 +3 1 +DROP PREPARE stmt; +SET columnstore_select_handler=ON; +CREATE PROCEDURE mcol4525_proc() +BEGIN +SELECT a, a xor 0 FROM t1 WHERE a > 1 AND a < 4; +END +// +CALL mcol4525_proc(); +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +CALL mcol4525_proc(); +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +CALL mcol4525_proc(); +ERROR 42000: The storage engine for the table doesn't support IDB-2030: Predicate and Logic operators can not be used where an expression is expected. +DROP PROCEDURE mcol4525_proc; +SET columnstore_select_handler=AUTO; +CREATE PROCEDURE mcol4525_proc() +BEGIN +SELECT a, a xor 0 FROM t1 WHERE a > 1 AND a < 4; +END +// +CALL mcol4525_proc(); +a a xor 0 +2 1 +3 1 +CALL mcol4525_proc(); +a a xor 0 +2 1 +3 1 +CALL mcol4525_proc(); +a a xor 0 +2 1 +3 1 +DROP PROCEDURE mcol4525_proc; +DROP TABLE t1; +CREATE TABLE `giorno` ( +`giorno` date NOT NULL DEFAULT '0000-00-00', +`giornoa` mediumint(7) DEFAULT NULL, +`mese` mediumint(6) DEFAULT NULL, +`settimana` mediumint(6) DEFAULT NULL, +`quindicina` mediumint(6) DEFAULT NULL, +`trimestre` smallint(5) DEFAULT NULL, +`quadrimestre` smallint(5) DEFAULT NULL, +`semestre` smallint(5) DEFAULT NULL, +`bimestre` smallint(5) DEFAULT NULL, +`anno` smallint(4) DEFAULT NULL, +PRIMARY KEY (`giorno`), +KEY `mese` (`mese`), +KEY `quindicina` (`quindicina`), +KEY `settimana` (`settimana`), +KEY `trimestre` (`trimestre`), +KEY `semestre` (`semestre`), +KEY `bimestre` (`bimestre`), +KEY `quadrimestre` (`quadrimestre`), +KEY `giornoa` (`giornoa`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Giorni'; +CREATE TABLE `campagna_web_codice` ( +`cwc_id` int(11) DEFAULT NULL, +`cwc_cw_id` int(11) DEFAULT NULL, +`cwc_cd_id` int(11) DEFAULT NULL, +`cwc_codice` varchar(30) DEFAULT NULL, +`cwc_va_id` int(11) DEFAULT NULL, +`cwc_prezzo` decimal(12,2) DEFAULT NULL, +`cwc_prezzoListino` decimal(12,2) DEFAULT NULL, +`cwc_prezzoSpedizione` decimal(8,2) DEFAULT NULL, +`cwc_in_id` int(11) DEFAULT NULL, +`cwc_na_id` int(11) DEFAULT NULL, +`cwc_desc` varchar(100) DEFAULT NULL, +`cwc_datainizio` date DEFAULT NULL, +`cwc_datafine` date DEFAULT NULL, +`cwc_mo_id` int(11) DEFAULT NULL, +`cwc_ma_id` int(11) DEFAULT NULL, +`cwc_pd_id` int(11) DEFAULT NULL, +`cwc_set_id` int(11) DEFAULT NULL, +`cwc_mr_id` int(11) DEFAULT NULL, +`cwc_ca_id` int(11) DEFAULT NULL, +`cwc_fa_id` int(11) DEFAULT NULL, +`cwc_ti_id` int(11) DEFAULT NULL, +`cwc_azws` varchar(255) DEFAULT NULL +) ENGINE=Columnstore DEFAULT CHARSET=utf8; +SET columnstore_select_handler=ON; +SELECT COUNT(DISTINCT cwc_id) npres,COUNT(DISTINCT cwc_cw_id) ncw,cwc_in_id insegna +FROM (giorno,campagna_web_codice) +WHERE cwc_fa_id IN (23) AND giorno BETWEEN cwc_datainizio AND cwc_datafine AND mese IN (202009) +GROUP BY insegna; +ERROR HY000: Internal error: IDB-1000: 'giorno' and 'campagna_web_codice' are not joined. +SET columnstore_select_handler=AUTO; +SELECT COUNT(DISTINCT cwc_id) npres,COUNT(DISTINCT cwc_cw_id) ncw,cwc_in_id insegna +FROM (giorno,campagna_web_codice) +WHERE cwc_fa_id IN (23) AND giorno BETWEEN cwc_datainizio AND cwc_datafine AND mese IN (202009) +GROUP BY insegna; +npres ncw insegna +DROP DATABASE mcol4525; diff --git a/mysql-test/columnstore/basic/t/mcol-424.test b/mysql-test/columnstore/basic/t/mcol-424.test new file mode 100644 index 000000000..bad2fbe52 --- /dev/null +++ b/mysql-test/columnstore/basic/t/mcol-424.test @@ -0,0 +1,62 @@ +--source ../include/have_columnstore.inc + +--echo # MCOL-424 +--echo # Cross engine subquery losing where clause causing incorrect results + +if (!$MASTER_MYPORT) +{ + # Running with --extern + let $MASTER_MYPORT=`SELECT @@port`; +} + +--disable_warnings +DROP DATABASE IF EXISTS mcol424; +--enable_warnings + +CREATE DATABASE mcol424; +USE mcol424; + +# +# Enable cross engine join +# Configure user and password in Columnstore.xml file +# +--exec $MCS_MCSSETCONFIG CrossEngineSupport User 'cejuser' +--exec $MCS_MCSSETCONFIG CrossEngineSupport Password 'Vagrant1|0000001' +--exec $MCS_MCSSETCONFIG CrossEngineSupport Port $MASTER_MYPORT + +# +# Create corresponding in the server +# +--disable_warnings +CREATE USER IF NOT EXISTS'cejuser'@'localhost' IDENTIFIED BY 'Vagrant1|0000001'; +--enable_warnings +GRANT ALL PRIVILEGES ON *.* TO 'cejuser'@'localhost'; +FLUSH PRIVILEGES; + +CREATE TABLE `trans_test` ( + `id` int(11) DEFAULT NULL, + `member_id` int(11) DEFAULT NULL, + `name` varchar(50) DEFAULT NULL +) ENGINE=Columnstore DEFAULT CHARSET=latin1; + +insert into `trans_test`(`id`,`member_id`,`name`) values (1,1,'trans 1'); +insert into `trans_test`(`id`,`member_id`,`name`) values (2,2,'trans 2'); +insert into `trans_test`(`id`,`member_id`,`name`) values (3,1,'trans 3'); +insert into `trans_test`(`id`,`member_id`,`name`) values (4,2,'trans 4'); +insert into `trans_test`(`id`,`member_id`,`name`) values (5,1,'trans 5'); + +CREATE TABLE `member_test` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +insert into `member_test`(`id`,`name`) values (1,'member 1'); +insert into `member_test`(`id`,`name`) values (2,'member 2'); +insert into `member_test`(`id`,`name`) values (3,'member 3'); + +SELECT * FROM trans_test t WHERE t.`member_id` IN (SELECT id FROM member_test WHERE id =1); + +# Clean UP +DROP USER 'cejuser'@'localhost'; +DROP DATABASE mcol424; diff --git a/mysql-test/columnstore/basic/t/mcol-4525.test b/mysql-test/columnstore/basic/t/mcol-4525.test new file mode 100644 index 000000000..ee2754b7c --- /dev/null +++ b/mysql-test/columnstore/basic/t/mcol-4525.test @@ -0,0 +1,312 @@ +--source ../include/have_columnstore.inc + +--echo # MCOL-4525 +--echo # Automatic select_handler +--echo # columnstore_select_handler=AUTO allows query execution +--echo # to fallback to the server, in case the execution using +--echo # select_handler fails. + +SET default_storage_engine=columnstore; + +--disable_warnings +DROP DATABASE IF EXISTS mcol4525; + +CREATE DATABASE mcol4525; +USE mcol4525; + +# Test case from working_tpch1/qa_fe_cnxFunctions/xor.sql.negative.sql +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1, 1), (5, 0); +SET columnstore_select_handler=ON; +--error 1178 +SELECT a xor b FROM t1; +SET columnstore_select_handler=AUTO; +SELECT a xor b FROM t1; + +# Test case from MCOL-428 +# This also tests in-to-exists predicate creation and injection +SET columnstore_select_handler=ON; +--error 1815 +SELECT DISTINCT a FROM t1 WHERE a IN (SELECT a FROM t1) OR a IN (SELECT a FROM t1); +SET columnstore_select_handler=AUTO; +SELECT DISTINCT a FROM t1 WHERE a IN (SELECT a FROM t1) OR a IN (SELECT a FROM t1); +DROP TABLE t1; + +# Test case from working_tpch1/misc/bug4767.negative.sql +CREATE TABLE bug4767 (c1 float, c2 double); +INSERT INTO bug4767 VALUES (1.234, 3.4556), (2.3345456, 2.3345456); +SET columnstore_select_handler=ON; +--error 1815 +SELECT * FROM bug4767 a JOIN bug4767 b ON (a.c1=b.c2); +SET columnstore_select_handler=AUTO; +SELECT * FROM bug4767 a JOIN bug4767 b ON (a.c1=b.c2); +DROP TABLE bug4767; + +# Test case from working_tpch1/misc/bug5126.negative.sql +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2); +CREATE TABLE t2 (b int); +INSERT INTO t2 VALUES (2); +SET columnstore_select_handler=ON; +--error 1815 +SELECT a FROM t1 WHERE a IN (SELECT a FROM t2); +SET columnstore_select_handler=AUTO; +SELECT a FROM t1 WHERE a IN (SELECT a FROM t2); +DROP TABLE t1; +DROP TABLE t2; + +# Test case for MCOL-1205 Circular Joins not supported +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2), (3); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (2), (3); +CREATE TABLE t3 (a int); +INSERT INTO t3 VALUES (3); +SET columnstore_select_handler=ON; +--error 1815 +SELECT * FROM t1 JOIN t2 ON t1.a=t2.a JOIN t3 ON t2.a=t3.a AND t3.a=t1.a; +SET columnstore_select_handler=AUTO; +SELECT * FROM t1 JOIN t2 ON t1.a=t2.a JOIN t3 ON t2.a=t3.a AND t3.a=t1.a; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +# Test case from working_tpch1_compareLogOnly/onClauseJoins/03.sql +CREATE TABLE l(c1 int, c2 int); +CREATE TABLE r(c1 int, c2 int); +CREATE TABLE s(c1 int, c2 int); +INSERT INTO l VALUES (1, 1); +INSERT INTO l VALUES (2, 2); +INSERT INTO r VALUES (1, 1); +INSERT INTO r VALUES (5, 5); +INSERT INTO s VALUES (1, 1); +INSERT INTO s VALUES (9, 9); +SET columnstore_select_handler=ON; +--error 1815 +SELECT 'q1', l.c1, r.c1 FROM l LEFT JOIN r ON l.c1 = r.c1 AND l.c1 IN (SELECT c1 FROM s) ORDER BY 1, 2, 3; +SET columnstore_select_handler=AUTO; +SELECT 'q1', l.c1, r.c1 FROM l LEFT JOIN r ON l.c1 = r.c1 AND l.c1 IN (SELECT c1 FROM s) ORDER BY 1, 2, 3; +DROP TABLE l; +DROP TABLE r; +DROP TABLE s; + +# Test case from working_tpch1_compareLogOnly/having/having_mysql.sql +CREATE TABLE t1 (col1 int, col2 varchar(5), col_t1 int); +INSERT INTO t1 VALUES(10,'hello',10); +INSERT INTO t1 VALUES(20,'hello',20); +INSERT INTO t1 VALUES(30,'hello',30); +INSERT INTO t1 VALUES(10,'bye',10); +INSERT INTO t1 VALUES(10,'sam',10); +INSERT INTO t1 VALUES(10,'bob',10); +SET columnstore_select_handler=ON; +--error 1178 +SELECT SUM(col1) AS col2 FROM t1 GROUP BY col2; +--error 1815 +SELECT col1 c FROM t1 ORDER BY AVG(col1); +SET columnstore_select_handler=AUTO; +SELECT SUM(col1) AS col2 FROM t1 GROUP BY col2; +SELECT col1 c FROM t1 ORDER BY AVG(col1); +DROP TABLE t1; + +# Test case from working_tpch1_compareLogOnly/misc/bug2891_negative.sql +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1); +SET columnstore_select_handler=ON; +--error 1178 +SELECT minute(sleep(a)) FROM t1; +SET columnstore_select_handler=AUTO; +SELECT minute(sleep(a)) FROM t1; +DROP TABLE t1; + +# Test case from working_tpch1_compareLogOnly/sub/g3_simple_semi_join.negative.sql +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (2), (3); +SET columnstore_select_handler=ON; +--error 1815 +SELECT SUM(a) FROM t1 WHERE EXISTS (SELECT MAX(a) FROM t2); +# Test case from working_tpch1_compareLogOnly/sub/g2_simple_scalar.negative.sql +--error 1815 +SELECT * FROM t1 WHERE (a,a) < (SELECT a,a FROM t2 WHERE a=2); +SET columnstore_select_handler=AUTO; +SELECT SUM(a) FROM t1 WHERE EXISTS (SELECT MAX(a) FROM t2); +SELECT * FROM t1 WHERE (a,a) < (SELECT a,a FROM t2 WHERE a=2); +DROP TABLE t1; +DROP TABLE t2; + +# Test case from working_tpch1_compareLogOnly/sub/bug3767.sql +CREATE TABLE gen (i int, i2 int); +INSERT INTO gen VALUES (1,0), (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (1,7), (1,8), (1,9); +SET columnstore_select_handler=ON; +--error 1815 +SELECT i2, (SELECT MAX(g2.i2) FROM gen g2 WHERE g2.i = g1.i AND g2.i2 > g1.i2) sub FROM gen g1; +SET columnstore_select_handler=AUTO; +SELECT i2, (SELECT MAX(g2.i2) FROM gen g2 WHERE g2.i = g1.i AND g2.i2 > g1.i2) sub FROM gen g1; +DROP TABLE gen; + +# Test case from working_tpch1_compareLogOnly/view/mts_view.30.sql +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (0), (1), (2), (3); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (2), (3); +CREATE VIEW v1 AS SELECT a FROM t1 WHERE a > 1; +SET columnstore_select_handler=ON; +--error 1815 +SELECT * FROM t1 LEFT JOIN (t2 AS t, v1) ON v1.a=t1.a ORDER BY 1; +SET columnstore_select_handler=AUTO; +SELECT * FROM t1 LEFT JOIN (t2 AS t, v1) ON v1.a=t1.a ORDER BY 1; +DROP TABLE t1; +DROP TABLE t2; +DROP VIEW v1; + +# Modified test case from MCOL-4680: +# FROM subquery containing nested joins returns an error +CREATE TABLE c1 (a int); +INSERT INTO c1 VALUES (1), (2), (3); +CREATE TABLE c2 (a int); +INSERT INTO c2 VALUES (2); +CREATE TABLE c3 (a int); +CREATE TABLE c4 (a int); +CREATE TABLE c5 (a int); +SET columnstore_select_handler=ON; +--error 1178 +SELECT c1.a AS col1, c2.a AS col2, c1.a xor c2.a FROM + c1 LEFT JOIN + ( + (c2 LEFT JOIN c3 ON c2.a=c3.a) LEFT JOIN + (c4 JOIN c5 ON c4.a=c5.a) + ON c2.a=c4.a + ) + ON c1.a=c2.a WHERE c2.a < 100; +SET columnstore_select_handler=AUTO; +SELECT c1.a AS col1, c2.a AS col2, c1.a xor c2.a FROM + c1 LEFT JOIN + ( + (c2 LEFT JOIN c3 ON c2.a=c3.a) LEFT JOIN + (c4 JOIN c5 ON c4.a=c5.a) + ON c2.a=c4.a + ) + ON c1.a=c2.a WHERE c2.a < 100; +DROP TABLE c1; +DROP TABLE c2; +DROP TABLE c3; +DROP TABLE c4; +DROP TABLE c5; + +# Test case for prepared statements +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2), (3), (4); +SET columnstore_select_handler=ON; +PREPARE stmt FROM "SELECT a, a xor 0 FROM t1 WHERE a > 1 AND a < 4"; +--error 1178 +EXECUTE stmt; +--error 1178 +EXECUTE stmt; +--error 1178 +EXECUTE stmt; +--error 1178 +EXECUTE stmt; +DROP PREPARE stmt; +SET columnstore_select_handler=AUTO; +PREPARE stmt FROM "SELECT a, a xor 0 FROM t1 WHERE a > 1 AND a < 4"; +EXECUTE stmt; +EXECUTE stmt; +EXECUTE stmt; +EXECUTE stmt; +EXECUTE stmt; +DROP PREPARE stmt; + +# Test case for stored procedures +SET columnstore_select_handler=ON; +delimiter //; +CREATE PROCEDURE mcol4525_proc() + BEGIN + SELECT a, a xor 0 FROM t1 WHERE a > 1 AND a < 4; + END +// +delimiter ;// +--error 1178 +CALL mcol4525_proc(); +--error 1178 +CALL mcol4525_proc(); +--error 1178 +CALL mcol4525_proc(); +DROP PROCEDURE mcol4525_proc; +SET columnstore_select_handler=AUTO; +delimiter //; +CREATE PROCEDURE mcol4525_proc() + BEGIN + SELECT a, a xor 0 FROM t1 WHERE a > 1 AND a < 4; + END +// +delimiter ;// +CALL mcol4525_proc(); +CALL mcol4525_proc(); +CALL mcol4525_proc(); +DROP PROCEDURE mcol4525_proc; +DROP TABLE t1; + +# Test case taken verbatim from MCOL-4525 issue description +CREATE TABLE `giorno` ( +`giorno` date NOT NULL DEFAULT '0000-00-00', +`giornoa` mediumint(7) DEFAULT NULL, +`mese` mediumint(6) DEFAULT NULL, +`settimana` mediumint(6) DEFAULT NULL, +`quindicina` mediumint(6) DEFAULT NULL, +`trimestre` smallint(5) DEFAULT NULL, +`quadrimestre` smallint(5) DEFAULT NULL, +`semestre` smallint(5) DEFAULT NULL, +`bimestre` smallint(5) DEFAULT NULL, +`anno` smallint(4) DEFAULT NULL, +PRIMARY KEY (`giorno`), +KEY `mese` (`mese`), +KEY `quindicina` (`quindicina`), +KEY `settimana` (`settimana`), +KEY `trimestre` (`trimestre`), +KEY `semestre` (`semestre`), +KEY `bimestre` (`bimestre`), +KEY `quadrimestre` (`quadrimestre`), +KEY `giornoa` (`giornoa`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Giorni'; + +CREATE TABLE `campagna_web_codice` ( +`cwc_id` int(11) DEFAULT NULL, +`cwc_cw_id` int(11) DEFAULT NULL, +`cwc_cd_id` int(11) DEFAULT NULL, +`cwc_codice` varchar(30) DEFAULT NULL, +`cwc_va_id` int(11) DEFAULT NULL, +`cwc_prezzo` decimal(12,2) DEFAULT NULL, +`cwc_prezzoListino` decimal(12,2) DEFAULT NULL, +`cwc_prezzoSpedizione` decimal(8,2) DEFAULT NULL, +`cwc_in_id` int(11) DEFAULT NULL, +`cwc_na_id` int(11) DEFAULT NULL, +`cwc_desc` varchar(100) DEFAULT NULL, +`cwc_datainizio` date DEFAULT NULL, +`cwc_datafine` date DEFAULT NULL, +`cwc_mo_id` int(11) DEFAULT NULL, +`cwc_ma_id` int(11) DEFAULT NULL, +`cwc_pd_id` int(11) DEFAULT NULL, +`cwc_set_id` int(11) DEFAULT NULL, +`cwc_mr_id` int(11) DEFAULT NULL, +`cwc_ca_id` int(11) DEFAULT NULL, +`cwc_fa_id` int(11) DEFAULT NULL, +`cwc_ti_id` int(11) DEFAULT NULL, +`cwc_azws` varchar(255) DEFAULT NULL +) ENGINE=Columnstore DEFAULT CHARSET=utf8; + +SET columnstore_select_handler=ON; +--error 1815 +SELECT COUNT(DISTINCT cwc_id) npres,COUNT(DISTINCT cwc_cw_id) ncw,cwc_in_id insegna +FROM (giorno,campagna_web_codice) +WHERE cwc_fa_id IN (23) AND giorno BETWEEN cwc_datainizio AND cwc_datafine AND mese IN (202009) +GROUP BY insegna; + +SET columnstore_select_handler=AUTO; +SELECT COUNT(DISTINCT cwc_id) npres,COUNT(DISTINCT cwc_cw_id) ncw,cwc_in_id insegna +FROM (giorno,campagna_web_codice) +WHERE cwc_fa_id IN (23) AND giorno BETWEEN cwc_datainizio AND cwc_datafine AND mese IN (202009) +GROUP BY insegna; + +DROP DATABASE mcol4525; +--enable_warnings