1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-29 08:21:15 +03:00

Merge pull request #1970 from tntnatbry/MCOL-4525

MCOL-4525 Implement columnstore_select_handler=AUTO.
This commit is contained in:
Roman Nozdrin
2021-06-14 10:43:34 +03:00
committed by GitHub
13 changed files with 1065 additions and 146 deletions

View File

@ -76,6 +76,7 @@ using namespace dataconvert;
#include "sm.h" #include "sm.h"
#include "ha_mcs_pushdown.h" #include "ha_mcs_pushdown.h"
#include "ha_mcs_sysvars.h"
#include "bytestream.h" #include "bytestream.h"
#include "messagequeue.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; ha_rows rowsInserted = 0;
int rc = 0; int rc = 0;
// ci->useCpimport = 2 means ALWAYS use cpimport, whether it's in a // ci->useCpimport = mcs_use_import_for_batchinsert_mode_t::ALWAYS means ALWAYS use
// transaction or not. User should use this option very carefully since // cpimport, whether it's in a transaction or not. User should use this option
// cpimport currently does not support rollbacks // very carefully since cpimport currently does not support rollbacks
if (((ci->useCpimport == 2) || if (((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ALWAYS) ||
((ci->useCpimport == 1) && (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) && ((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ON) &&
(!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) &&
(!ci->singleInsert) && (!ci->singleInsert) &&
((ci->isLoaddataInfile) || ((ci->isLoaddataInfile) ||
((thd->lex)->sql_command == SQLCOM_INSERT) || ((thd->lex)->sql_command == SQLCOM_LOAD) || ((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 || (thd->lex)->sql_command == SQLCOM_INSERT_SELECT ||
ci->isCacheInsert) && !ci->singleInsert ) 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)) 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 // For now, disable cpimport for cache inserts
if (ci->isCacheInsert) 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 // ci->useCpimport = mcs_use_import_for_batchinsert_mode_t::ALWAYS means ALWAYS use
// transaction or not. User should use this option very carefully since // cpimport, whether it's in a transaction or not. User should use this option
// cpimport currently does not support rollbacks // very carefully since cpimport currently does not support rollbacks
if ((ci->useCpimport == 2) || if ((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ALWAYS) ||
((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::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 //store table info to connection info
CalpontSystemCatalog::TableName tableName; 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 // @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 ( ( ((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) || if (((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ALWAYS) ||
((ci->useCpimport == 1) && (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) && ((ci->useCpimport == mcs_use_import_for_batchinsert_mode_t::ON) &&
(!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) &&
(!ci->singleInsert) && (!ci->singleInsert) &&
((ci->isLoaddataInfile) || ((ci->isLoaddataInfile) ||
((thd->lex)->sql_command == SQLCOM_INSERT) || ((thd->lex)->sql_command == SQLCOM_LOAD) || ((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->isCacheInsert = false;
ci->tableOid = 0; ci->tableOid = 0;
ci->rowsHaveInserted = 0; ci->rowsHaveInserted = 0;
ci->useCpimport = 1; ci->useCpimport = mcs_use_import_for_batchinsert_mode_t::ON;
return rc; return rc;
} }

View File

@ -32,6 +32,7 @@
#include <vector> #include <vector>
#include "idb_mysql.h" #include "idb_mysql.h"
#include "ha_mcs_sysvars.h"
struct st_ha_create_information; struct st_ha_create_information;
class ha_columnstore_select_handler; class ha_columnstore_select_handler;
@ -274,7 +275,7 @@ struct cal_connection_info
filePtr(0), filePtr(0),
headerLength(0), headerLength(0),
useXbit(false), useXbit(false),
useCpimport(1), useCpimport(mcs_use_import_for_batchinsert_mode_t::ON),
delimiter('\7'), delimiter('\7'),
affectedRows(0) affectedRows(0)
{ {
@ -341,7 +342,7 @@ struct cal_connection_info
FILE* filePtr; FILE* filePtr;
uint8_t headerLength; uint8_t headerLength;
bool useXbit; bool useXbit;
uint8_t useCpimport; mcs_use_import_for_batchinsert_mode_t useCpimport;
char delimiter; char delimiter;
char enclosed_by; char enclosed_by;
std::vector <execplan::CalpontSystemCatalog::ColType> columnTypes; std::vector <execplan::CalpontSystemCatalog::ColType> columnTypes;

View File

@ -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: * DESCRIPTION:
* This function traverses derived tables to unset * This function traverses SELECT_LEX::table_list recursively
* SELECT_LEX::first_cond_optimization: a marker to control * to set/unset SELECT_LEX::first_cond_optimization: a marker
* optimizations executing PS. If set it allows to apply * to control optimizations executing PS. If set it allows to
* optimizations. If unset, it disables optimizations. * apply optimizations. If unset, it disables optimizations.
* PARAMETERS: * PARAMETERS:
* select_lex - SELECT_LEX* that describes the query. * 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; for (TABLE_LIST *tl= select_lex->get_table_list(); tl; tl= tl->next_local)
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
while ((tbl= li++))
{ {
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()) if (unit)
opt_flag_unset_PS(sl); {
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) (*func)(select_lex);
{
select_lex->first_cond_optimization= false;
}
} }
/* @brief in_subselect_rewrite - Rewrites Item_in_subselect */ /* @brief in_subselect_rewrite - Rewrites Item_in_subselect */
/************************************************************ /************************************************************
* DESCRIPTION: * DESCRIPTION:

View File

@ -21,6 +21,8 @@
#include "idb_mysql.h" #include "idb_mysql.h"
bool in_subselect_rewrite(SELECT_LEX *select_lex); 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 #endif

View File

@ -21,23 +21,12 @@
void check_walk(const Item* item, void* arg); 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 (auto iter = handler->tableOuterJoinMap.begin();
for (global_list = thd_->lex->query_tables; global_list; global_list = global_list->next_global) iter != handler->tableOuterJoinMap.end(); iter++)
{ {
// MCOL-652 - doing this with derived tables can cause bad things to happen iter->first->outer_join = iter->second;
if (!global_list->derived)
{
global_list->index_hints = new (thd_->mem_root) List<Index_hint>();
global_list->index_hints->push_front(new (thd_->mem_root)
Index_hint(INDEX_HINT_USE,
INDEX_HINT_MASK_JOIN,
NULL,
0), thd_->mem_root);
}
} }
} }
@ -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 // MCOL-2178 Disable SP support in the group_by_handler for now
// Check the session variable value to enable/disable use of // Check the session variable value to enable/disable use of
// group_by_handler. There is no GBH if SH works for the query. // 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; return handler;
} }
@ -754,14 +744,14 @@ int ha_mcs_group_by_handler::end_scan()
select_handler* select_handler*
create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) 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 // Check the session variable value to enable/disable use of
// select_handler // 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))) ((thd->lex)->sphead && !get_select_handler_in_stored_procedures(thd)))
{ {
return handler; return nullptr;
} }
// Flag to indicate if this is a prepared statement // 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()) && !((select_dumpvar *)(thd->lex)->result)->var_list.is_empty()) &&
(!isPS)) (!isPS))
{ {
return handler; return nullptr;
} }
// Select_handler couldn't properly process UPSERT..SELECT // Select_handler couldn't properly process UPSERT..SELECT
if ((thd->lex)->sql_command == SQLCOM_INSERT_SELECT if ((thd->lex)->sql_command == SQLCOM_INSERT_SELECT
&& thd->lex->duplicates == DUP_UPDATE) && thd->lex->duplicates == DUP_UPDATE)
{ {
return handler; return nullptr;
} }
// Iterate and traverse through the item list and the JOIN cond // 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)) if (check_user_var(table_ptr->select_lex))
{ {
return handler; return nullptr;
} }
} }
// We apply dedicated rewrites from MDB here so MDB's data structures // 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 // becomes dirty and CS has to raise an error in case of any problem
// or unsupported feature. // 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; 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; Query_arena *arena, backup;
arena = thd->activate_stmt_arena_if_needed(&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) if (arena)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
if (select_lex->handle_derived(thd->lex, DT_MERGE)) #ifdef DEBUG_WALK_COND
if (conds)
{ {
unsupported_feature = true; conds->traverse_cond(cal_impl_if::debug_walk, NULL, Item::POSTFIX);
handler->err_msg.assign("create_columnstore_select_handler(): \ }
Internal error occured in SL::handle_derived()"); #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; // Prepare query execution
if (!unsupported_feature) // This is taken from JOIN::exec_inner()
{ if (!select_lex->outer_select() && // (1)
// Rewrite once for PS select_lex != select_lex->master_unit()->fake_select_lex) // (2)
// Refer to JOIN::optimize_inner() in sql/sql_select.cc thd->lex->set_limit_rows_examined();
// 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;
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(); return handler;
if (arena)
thd->restore_active_arena(arena, &backup);
// Unset SL::first_cond_optimization
opt_flag_unset_PS(select_lex);
} }
}
#ifdef DEBUG_WALK_COND if ((join->select_lex->options & OPTION_SCHEMA_TABLE) &&
if (conds) 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<void*>(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; 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, ha_columnstore_select_handler::ha_columnstore_select_handler(THD *thd,
SELECT_LEX* select_lex) 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; select = select_lex;
rewrite_error = false;
} }
/*********************************************************** /***********************************************************
@ -881,6 +1001,10 @@ ha_columnstore_select_handler::ha_columnstore_select_handler(THD *thd,
***********************************************************/ ***********************************************************/
ha_columnstore_select_handler::~ha_columnstore_select_handler() ha_columnstore_select_handler::~ha_columnstore_select_handler()
{ {
if (scan_initialized && !scan_ended)
{
end_scan();
}
} }
/*@brief Initiate the query for select_handler */ /*@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() int ha_columnstore_select_handler::init_scan()
{ {
DBUG_ENTER("ha_columnstore_select_handler::init_scan"); DBUG_ENTER("ha_columnstore_select_handler::init_scan");
DBUG_RETURN(pushdown_init_rc);
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<void*>(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);
} }
/*@brief Fetch next row for select_handler */ /*@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"); DBUG_ENTER("ha_columnstore_select_handler::end_scan");
scan_ended = true;
int rc = ha_mcs_impl_rnd_end(table, true); int rc = ha_mcs_impl_rnd_end(table, true);
DBUG_RETURN(rc); 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);
}

View File

@ -138,10 +138,12 @@ class ha_columnstore_select_handler: public select_handler
{ {
private: private:
COLUMNSTORE_SHARE *share; COLUMNSTORE_SHARE *share;
bool prepared;
bool scan_ended;
public: public:
bool rewrite_error; bool scan_initialized;
std::string err_msg; int pushdown_init_rc;
// MCOL-4525 Store the original TABLE_LIST::outer_join value in a hash map. // 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 // This will be used to restore to the original state later in case
// query execution fails using the select_handler. // query execution fails using the select_handler.
@ -151,6 +153,7 @@ public:
int init_scan() override; int init_scan() override;
int next_row() override; int next_row() override;
int end_scan() override; int end_scan() override;
bool prepare() override;
}; };
#endif #endif

View File

@ -71,13 +71,28 @@ static MYSQL_THDVAR_ULONGLONG(
1 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, select_handler,
PLUGIN_VAR_NOCMDARG, PLUGIN_VAR_RQCMDARG,
"Enable/Disable the MCS select_handler", "Set the MCS select_handler to Disabled, Enabled, or Automatic",
NULL, NULL, // check
NULL, NULL, // update
1 1, // default
&mcs_select_handler_mode_values_lib // values lib
); );
static MYSQL_THDVAR_BOOL( static MYSQL_THDVAR_BOOL(
@ -288,17 +303,17 @@ static MYSQL_THDVAR_ULONG(
1 // block size 1 // block size
); );
const char* mcs_use_import_for_batchinsert_values[] = { const char* mcs_use_import_for_batchinsert_mode_values[] = {
"OFF", "OFF",
"ON", "ON",
"ALWAYS", "ALWAYS",
NullS NullS
}; };
static TYPELIB mcs_use_import_for_batchinsert_values_lib = { static TYPELIB mcs_use_import_for_batchinsert_mode_values_lib = {
array_elements(mcs_use_import_for_batchinsert_values) - 1, array_elements(mcs_use_import_for_batchinsert_mode_values) - 1,
"mcs_use_import_for_batchinsert_values", "mcs_use_import_for_batchinsert_mode_values",
mcs_use_import_for_batchinsert_values, mcs_use_import_for_batchinsert_mode_values,
NULL NULL
}; };
@ -309,7 +324,7 @@ static MYSQL_THDVAR_ENUM(
NULL, // check NULL, // check
NULL, // update NULL, // update
1, // default 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( 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); 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; THDVAR(thd, select_handler) = value;
} }
@ -585,12 +601,12 @@ void set_local_query(THD* thd, ulong value)
THDVAR(thd, local_query) = 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 : return ( thd == NULL ) ? mcs_use_import_for_batchinsert_mode_t::ON :
(mcs_use_import_for_batchinsert_t) THDVAR(thd, use_import_for_batchinsert); (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; THDVAR(thd, use_import_for_batchinsert) = value;
} }

View File

@ -33,13 +33,20 @@ enum mcs_compression_type_t {
SNAPPY = 2 SNAPPY = 2
}; };
// use_import_for_batchinsert // use_import_for_batchinsert mode
enum mcs_use_import_for_batchinsert_t { enum class mcs_use_import_for_batchinsert_mode_t {
OFF = 0, OFF = 0,
ON = 1, ON = 1,
ALWAYS = 2 ALWAYS = 2
}; };
// select_handler mode
enum class mcs_select_handler_mode_t {
OFF = 0,
ON = 1,
AUTO = 2
};
// simple setters/getters // simple setters/getters
const char* get_original_query(THD* thd); const char* get_original_query(THD* thd);
void set_original_query(THD* thd, char* query); 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); ulonglong get_original_optimizer_flags(THD* thd = NULL);
void set_original_optimizer_flags(ulonglong ptr, THD* thd = NULL); void set_original_optimizer_flags(ulonglong ptr, THD* thd = NULL);
bool get_select_handler(THD* thd); mcs_select_handler_mode_t get_select_handler_mode(THD* thd);
void set_select_handler(THD* thd, bool value); void set_select_handler_mode(THD* thd, ulong value);
bool get_derived_handler(THD* thd); bool get_derived_handler(THD* thd);
void set_derived_handler(THD* thd, bool value); 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); ulong get_local_query(THD* thd);
void set_local_query(THD* thd, ulong value); void set_local_query(THD* thd, ulong 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);
void set_use_import_for_batchinsert(THD* thd, ulong value); void set_use_import_for_batchinsert_mode(THD* thd, ulong value);
ulong get_import_for_batchinsert_delimiter(THD* thd); ulong get_import_for_batchinsert_delimiter(THD* thd);
void set_import_for_batchinsert_delimiter(THD* thd, ulong value); void set_import_for_batchinsert_delimiter(THD* thd, ulong value);

View File

@ -81,6 +81,7 @@ template <class T> bool isnan(T);
#include "select_handler.h" #include "select_handler.h"
#include "rpl_rli.h" #include "rpl_rli.h"
#include "my_dbug.h" #include "my_dbug.h"
#include "sql_show.h"
// Now clean up the pollution as best we can... // Now clean up the pollution as best we can...
#include "mcsconfig_conflicting_defs_undef.h" #include "mcsconfig_conflicting_defs_undef.h"

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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