diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/event_data_objects.cc | 5 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_sum.cc | 7 | ||||
-rw-r--r-- | sql/mysql_priv.h | 17 | ||||
-rw-r--r-- | sql/mysqld.cc | 17 | ||||
-rw-r--r-- | sql/records.cc | 3 | ||||
-rw-r--r-- | sql/share/Makefile.am | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 | ||||
-rw-r--r-- | sql/sys_vars.cc | 39 |
9 files changed, 79 insertions, 21 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index fd9561eb132..7f4104f4a77 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -834,8 +834,9 @@ bool get_next_time(const Time_zone *time_zone, my_time_t *next, } else { - long diff_months= (long) (local_now.year - local_start.year)*12 + - (local_now.month - local_start.month); + long diff_months= ((long) local_now.year - (long) local_start.year)*12 + + ((long) local_now.month - (long) local_start.month); + /* Unlike for seconds above, the formula below returns the interval that, when added to the local_start, will give the time in the diff --git a/sql/item_func.cc b/sql/item_func.cc index 557561789b2..d0af0d5f5e9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2953,7 +2953,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, String *res= arguments[i]->val_str(&buffers[i]); if (arguments[i]->null_value) continue; - f_args.args[i]= (char*) res->c_ptr(); + f_args.args[i]= (char*) res->c_ptr_safe(); f_args.lengths[i]= res->length(); break; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index c33088e0276..a61c5d59d67 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -578,7 +578,14 @@ int Item_sum::set_aggregator(Aggregator::Aggregator_type aggregator) { if (aggr) { + /* + Dependent subselects may be executed multiple times, making + set_aggregator to be called multiple times. The aggregator type + will be the same, but it needs to be reset so that it is + reevaluated with the new dependent data. + */ DBUG_ASSERT(aggregator == aggr->Aggrtype()); + aggr->clear(); return FALSE; } switch (aggregator) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 33ca7eee89b..36d35ec8877 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -622,17 +622,19 @@ protected: #define MODE_PAD_CHAR_TO_FULL_LENGTH (ULL(1) << 31) /* @@optimizer_switch flags. These must be in sync with optimizer_switch_typelib */ -#define OPTIMIZER_SWITCH_INDEX_MERGE 1 -#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2 -#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4 -#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8 -#define OPTIMIZER_SWITCH_LAST 16 +#define OPTIMIZER_SWITCH_INDEX_MERGE (1ULL << 0) +#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION (1ULL << 1) +#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION (1ULL << 2) +#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT (1ULL << 3) +#define OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN (1ULL << 4) +#define OPTIMIZER_SWITCH_LAST (1ULL << 5) /* The following must be kept in sync with optimizer_switch_str in mysqld.cc */ #define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \ - OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT) + OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \ + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) /* @@ -2643,7 +2645,8 @@ enum options_mysqld OPT_SSL_CIPHER, OPT_SSL_KEY, OPT_UPDATE_LOG, - OPT_WANT_CORE + OPT_WANT_CORE, + OPT_ENGINE_CONDITION_PUSHDOWN }; #endif /* MYSQL_SERVER */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f07410e0d43..71d121a9ead 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7384,6 +7384,18 @@ mysqld_get_one_option(int optid, } break; #endif /* defined(ENABLED_DEBUG_SYNC) */ + case OPT_ENGINE_CONDITION_PUSHDOWN: + /* + The last of --engine-condition-pushdown and --optimizer_switch on + command line wins (see get_options(). + */ + if (global_system_variables.engine_condition_pushdown) + global_system_variables.optimizer_switch|= + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN; + else + global_system_variables.optimizer_switch&= + ~OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN; + break; } return 0; } @@ -7610,6 +7622,11 @@ static int get_options(int *argc_ptr, char ***argv_ptr) else pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */ #endif + + global_system_variables.engine_condition_pushdown= + test(global_system_variables.optimizer_switch & + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN); + return 0; } diff --git a/sql/records.cc b/sql/records.cc index 9ec19c55841..c97ffa152dc 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -270,7 +270,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, thd->variables.read_buff_size); } /* Condition pushdown to storage engine */ - if (thd->variables.engine_condition_pushdown && + if ((thd->variables.optimizer_switch & + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) && select && select->cond && (select->cond->used_tables() & table->map) && !table->file->pushed_cond) diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am index 06b349d5de2..203dbe54254 100644 --- a/sql/share/Makefile.am +++ b/sql/share/Makefile.am @@ -43,8 +43,8 @@ install-data-local: $(DESTDIR)$(pkgdatadir)/$$lang/errmsg.sys; \ done $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/charsets - $(INSTALL_DATA) $(srcdir)/errmsg-utf8.txt \ - $(DESTDIR)$(pkgdatadir)/errmsg-utf8.txt; \ + $(INSTALL_DATA) $(srcdir)/errmsg-utf8.txt \ + $(DESTDIR)$(pkgdatadir)/errmsg-utf8.txt; \ $(INSTALL_DATA) $(srcdir)/charsets/README $(DESTDIR)$(pkgdatadir)/charsets/README $(INSTALL_DATA) $(srcdir)/charsets/*.xml $(DESTDIR)$(pkgdatadir)/charsets diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5f1c5ac2a34..5647727089f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6347,7 +6347,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) /* Push condition to storage engine if this is enabled and the condition is not guarded */ tab->table->file->pushed_cond= NULL; - if (thd->variables.engine_condition_pushdown) + if (thd->variables.optimizer_switch & + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) { COND *push_cond= make_cond_for_table(tmp, current_map, current_map); @@ -16630,7 +16631,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { const COND *pushed_cond= tab->table->file->pushed_cond; - if (thd->variables.engine_condition_pushdown && pushed_cond) + if ((thd->variables.optimizer_switch & + OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) && pushed_cond) { extra.append(STRING_WITH_LEN("; Using where with pushed " "condition")); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 1bac48d053f..f3e2b5cec7c 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1253,16 +1253,28 @@ static Sys_var_ulong Sys_optimizer_search_depth( static const char *optimizer_switch_names[]= { "index_merge", "index_merge_union", "index_merge_sort_union", - "index_merge_intersection", + "index_merge_intersection", "engine_condition_pushdown", "default", NullS }; +/** propagates changes to @@engine_condition_pushdown */ +static bool fix_optimizer_switch(sys_var *self, THD *thd, + enum_var_type type) +{ + SV *sv= (type == OPT_GLOBAL) ? &global_system_variables : &thd->variables; + sv->engine_condition_pushdown= + test(sv->optimizer_switch & OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN); + return false; +} static Sys_var_flagset Sys_optimizer_switch( "optimizer_switch", "optimizer_switch=option=val[,option=val...], where option is one of " "{index_merge, index_merge_union, index_merge_sort_union, " - "index_merge_intersection} and val is one of {on, off, default}", + "index_merge_intersection, engine_condition_pushdown}" + " and val is one of {on, off, default}", SESSION_VAR(optimizer_switch), CMD_LINE(REQUIRED_ARG), - optimizer_switch_names, DEFAULT(OPTIMIZER_SWITCH_DEFAULT)); + optimizer_switch_names, DEFAULT(OPTIMIZER_SWITCH_DEFAULT), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), + ON_UPDATE(fix_optimizer_switch)); static Sys_var_charptr Sys_pid_file( "pid_file", "Pid file used by safe_mysqld", @@ -1959,11 +1971,26 @@ static Sys_var_ulong Sys_net_wait_timeout( VALID_RANGE(1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)), DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1)); +/** propagates changes to the relevant flag of @@optimizer_switch */ +static bool fix_engine_condition_pushdown(sys_var *self, THD *thd, + enum_var_type type) +{ + SV *sv= (type == OPT_GLOBAL) ? &global_system_variables : &thd->variables; + if (sv->engine_condition_pushdown) + sv->optimizer_switch|= OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN; + else + sv->optimizer_switch&= ~OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN; + return false; +} static Sys_var_mybool Sys_engine_condition_pushdown( "engine_condition_pushdown", - "Push supported query conditions to the storage engine", - SESSION_VAR(engine_condition_pushdown), CMD_LINE(OPT_ARG), - DEFAULT(TRUE)); + "Push supported query conditions to the storage engine." + " Deprecated, use --optimizer-switch instead.", + SESSION_VAR(engine_condition_pushdown), + CMD_LINE(OPT_ARG, OPT_ENGINE_CONDITION_PUSHDOWN), + DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), + ON_UPDATE(fix_engine_condition_pushdown), + DEPRECATED(70000, "'@@optimizer_switch'")); static Sys_var_plugin Sys_default_storage_engine( "default_storage_engine", "The default storage engine for new tables", |