diff options
author | Michael Widenius <monty@mysql.com> | 2009-04-25 12:04:38 +0300 |
---|---|---|
committer | Michael Widenius <monty@mysql.com> | 2009-04-25 12:04:38 +0300 |
commit | 210a412522b10115d34b431c66acf403faab7bfe (patch) | |
tree | 56c09cfd1053265897d114e4acb52d395185f27e /sql/set_var.cc | |
parent | 059b9356a19118a48fbad31be81c4859e15d3bc8 (diff) | |
parent | 4aeeb1d157a67c5359475d8941267641fb894b22 (diff) | |
download | mariadb-git-210a412522b10115d34b431c66acf403faab7bfe.tar.gz |
bzr merge from guilhem's maria tree to our local 5.1
configure.in:
Manually merged
mysql-test/lib/My/ConfigFactory.pm:
Manually merged
mysql-test/mysql-test-run.pl:
Manually merged
mysql-test/t/information_schema.test:
Manually merged
sql/handler.cc:
Manually merged
support-files/mysql.spec.sh:
Manually merged
Diffstat (limited to 'sql/set_var.cc')
-rw-r--r-- | sql/set_var.cc | 241 |
1 files changed, 164 insertions, 77 deletions
diff --git a/sql/set_var.cc b/sql/set_var.cc index c6650702cf9..c1071c90223 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -110,6 +110,7 @@ static void sys_default_init_connect(THD*, enum_var_type type); static bool sys_update_init_slave(THD*, set_var*); static void sys_default_init_slave(THD*, enum_var_type type); static bool set_option_bit(THD *thd, set_var *var); +static bool set_option_log_bin_bit(THD *thd, set_var *var); static bool set_option_autocommit(THD *thd, set_var *var); static int check_log_update(THD *thd, set_var *var); static bool set_log_update(THD *thd, set_var *var); @@ -134,8 +135,6 @@ static int check_max_delayed_threads(THD *thd, set_var *var); static void fix_thd_mem_root(THD *thd, enum_var_type type); static void fix_trans_mem_root(THD *thd, enum_var_type type); static void fix_server_id(THD *thd, enum_var_type type); -static ulonglong fix_unsigned(THD *, ulonglong, const struct my_option *); -static bool get_unsigned(THD *thd, set_var *var); bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd, const char *name, longlong val); static KEY_CACHE *create_key_cache(const char *name, uint length); @@ -295,6 +294,11 @@ static sys_var_const sys_ft_query_expansion_limit(&vars, static sys_var_const sys_ft_stopword_file(&vars, "ft_stopword_file", OPT_GLOBAL, SHOW_CHAR_PTR, (uchar*) &ft_stopword_file); + +static sys_var_const sys_ignore_builtin_innodb(&vars, "ignore_builtin_innodb", + OPT_GLOBAL, SHOW_BOOL, + (uchar*) &opt_ignore_builtin_innodb); + sys_var_str sys_init_connect(&vars, "init_connect", 0, sys_update_init_connect, sys_default_init_connect,0); @@ -746,7 +750,7 @@ static sys_var_thd_bit sys_log_update(&vars, "sql_log_update", OPTION_BIN_LOG); static sys_var_thd_bit sys_log_binlog(&vars, "sql_log_bin", check_log_update, - set_option_bit, + set_option_log_bin_bit, OPTION_BIN_LOG); static sys_var_thd_bit sys_sql_warnings(&vars, "sql_warnings", 0, set_option_bit, @@ -1397,6 +1401,19 @@ static void fix_server_id(THD *thd, enum_var_type type) } +/** + Throw warning (error in STRICT mode) if value for variable needed bounding. + Only call from check(), not update(), because an error in update() would be + bad mojo. Plug-in interface also uses this. + + @param thd thread handle + @param fixed did we have to correct the value? (throw warn/err if so) + @param unsignd is value's type unsigned? + @param name variable's name + @param val variable's value + + @retval TRUE on error, FALSE otherwise (warning or OK) + */ bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd, const char *name, longlong val) { @@ -1422,26 +1439,128 @@ bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd, return FALSE; } -static ulonglong fix_unsigned(THD *thd, ulonglong num, + +/** + check an unsigned user-supplied value for a systemvariable against bounds. + + TODO: This is a wrapper function to call clipping from within an update() + function. Calling bounds from within update() is fair game in theory, + but we can only send warnings from in there, not errors, and besides, + it violates our model of separating check from update phase. + To avoid breaking out of the server with an ASSERT() in strict mode, + we pretend we're not in strict mode when we go through here. Bug#43233 + was opened to remind us to replace this kludge with The Right Thing, + which of course is to do the check in the actual check phase, and then + throw an error or warning accordingly. + + @param thd thread handle + @param num the value to limit + @param option_limits the bounds-record, or NULL if none + */ +static void bound_unsigned(THD *thd, ulonglong *num, const struct my_option *option_limits) { - my_bool fixed= FALSE; - ulonglong out= getopt_ull_limit_value(num, option_limits, &fixed); + if (option_limits) + { + my_bool fixed = FALSE; + ulonglong unadjusted= *num; - throw_bounds_warning(thd, fixed, TRUE, option_limits->name, (longlong) num); - return out; + *num= getopt_ull_limit_value(unadjusted, option_limits, &fixed); + + if (fixed) + { + ulong ssm= thd->variables.sql_mode; + thd->variables.sql_mode&= ~MODE_STRICT_ALL_TABLES; + throw_bounds_warning(thd, fixed, TRUE, option_limits->name, unadjusted); + thd->variables.sql_mode= ssm; + } + } } -static bool get_unsigned(THD *thd, set_var *var) -{ + +/** + Get unsigned system-variable. + Negative value does not wrap around, but becomes zero. + Check user-supplied value for a systemvariable against bounds. + If we needed to adjust the value, throw a warning or error depending + on SQL-mode. + + @param thd thread handle + @param var the system-variable to get + @param user_max a limit given with --maximum-variable-name=... or 0 + @param var_type function will bound on systems where necessary. + + @retval TRUE on error, FALSE otherwise (warning or OK) + */ +static bool get_unsigned(THD *thd, set_var *var, ulonglong user_max, + ulong var_type) +{ + int warnings= 0; + ulonglong unadjusted; + const struct my_option *limits= var->var->option_limits; + struct my_option fallback; + + /* get_unsigned() */ if (var->value->unsigned_flag) var->save_result.ulonglong_value= (ulonglong) var->value->val_int(); else { longlong v= var->value->val_int(); var->save_result.ulonglong_value= (ulonglong) ((v < 0) ? 0 : v); + if (v < 0) + { + warnings++; + if (throw_bounds_warning(thd, TRUE, FALSE, var->var->name, v)) + return TRUE; /* warning was promoted to error, give up */ + } } - return 0; + + unadjusted= var->save_result.ulonglong_value; + + /* max, if any */ + + if ((user_max > 0) && (unadjusted > user_max)) + { + var->save_result.ulonglong_value= user_max; + + if ((warnings == 0) && throw_bounds_warning(thd, TRUE, TRUE, + var->var->name, + (longlong) unadjusted)) + return TRUE; + + warnings++; + } + + /* + if the sysvar doesn't have a proper bounds record but the check + function would like bounding to ULONG where its size differs from + that of ULONGLONG, we make up a bogus limits record here and let + the usual suspects handle the actual limiting. + */ + + if (!limits && var_type != GET_ULL) + { + bzero(&fallback, sizeof(fallback)); + fallback.var_type= var_type; + limits= &fallback; + } + + /* fix_unsigned() */ + if (limits) + { + my_bool fixed; + + var->save_result.ulonglong_value= getopt_ull_limit_value(var->save_result. + ulonglong_value, + limits, &fixed); + + if ((warnings == 0) && throw_bounds_warning(thd, fixed, TRUE, + var->var->name, + (longlong) unadjusted)) + return TRUE; + } + + return FALSE; } @@ -1455,29 +1574,13 @@ sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_ar bool sys_var_long_ptr_global::check(THD *thd, set_var *var) { - return get_unsigned(thd, var); + return get_unsigned(thd, var, 0, GET_ULONG); } bool sys_var_long_ptr_global::update(THD *thd, set_var *var) { - ulonglong tmp= var->save_result.ulonglong_value; pthread_mutex_lock(guard); - if (option_limits) - *value= (ulong) fix_unsigned(thd, tmp, option_limits); - else - { -#if SIZEOF_LONG < SIZEOF_LONG_LONG - /* Avoid overflows on 32 bit systems */ - if (tmp > ULONG_MAX) - { - tmp= ULONG_MAX; - throw_bounds_warning(thd, TRUE, TRUE, name, - (longlong) var->save_result.ulonglong_value); - } -#endif - *value= (ulong) tmp; - } - + *value= (ulong) var->save_result.ulonglong_value; pthread_mutex_unlock(guard); return 0; } @@ -1497,10 +1600,8 @@ bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var) { ulonglong tmp= var->save_result.ulonglong_value; pthread_mutex_lock(&LOCK_global_system_variables); - if (option_limits) - *value= (ulonglong) fix_unsigned(thd, tmp, option_limits); - else - *value= (ulonglong) tmp; + bound_unsigned(thd, &tmp, option_limits); + *value= (ulonglong) tmp; pthread_mutex_unlock(&LOCK_global_system_variables); return 0; } @@ -1549,36 +1650,18 @@ uchar *sys_var_enum_const::value_ptr(THD *thd, enum_var_type type, bool sys_var_thd_ulong::check(THD *thd, set_var *var) { - return (get_unsigned(thd, var) || - (check_func && (*check_func)(thd, var))); + if (get_unsigned(thd, var, max_system_variables.*offset, GET_ULONG)) + return TRUE; + DBUG_ASSERT(var->save_result.ulonglong_value <= ULONG_MAX); + return ((check_func && (*check_func)(thd, var))); } bool sys_var_thd_ulong::update(THD *thd, set_var *var) { - ulonglong tmp= var->save_result.ulonglong_value; - - /* Don't use bigger value than given with --maximum-variable-name=.. */ - if (tmp > max_system_variables.*offset) - { - throw_bounds_warning(thd, TRUE, TRUE, name, (longlong) tmp); - tmp= max_system_variables.*offset; - } - - if (option_limits) - tmp= fix_unsigned(thd, tmp, option_limits); -#if SIZEOF_LONG < SIZEOF_LONG_LONG - else if (tmp > ULONG_MAX) - { - tmp= ULONG_MAX; - throw_bounds_warning(thd, TRUE, TRUE, name, (longlong) var->save_result.ulonglong_value); - } -#endif - - DBUG_ASSERT(tmp <= ULONG_MAX); if (var->type == OPT_GLOBAL) - global_system_variables.*offset= (ulong) tmp; + global_system_variables.*offset= (ulong) var->save_result.ulonglong_value; else - thd->variables.*offset= (ulong) tmp; + thd->variables.*offset= (ulong) var->save_result.ulonglong_value; return 0; } @@ -1616,8 +1699,8 @@ bool sys_var_thd_ha_rows::update(THD *thd, set_var *var) if ((ha_rows) tmp > max_system_variables.*offset) tmp= max_system_variables.*offset; - if (option_limits) - tmp= (ha_rows) fix_unsigned(thd, tmp, option_limits); + bound_unsigned(thd, &tmp, option_limits); + if (var->type == OPT_GLOBAL) { /* Lock is needed to make things safe on 32 bit systems */ @@ -1658,27 +1741,21 @@ uchar *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type, bool sys_var_thd_ulonglong::check(THD *thd, set_var *var) { - return get_unsigned(thd, var); + return get_unsigned(thd, var, max_system_variables.*offset, GET_ULL); } bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) { - ulonglong tmp= var->save_result.ulonglong_value; - - if (tmp > max_system_variables.*offset) - tmp= max_system_variables.*offset; - - if (option_limits) - tmp= fix_unsigned(thd, tmp, option_limits); if (var->type == OPT_GLOBAL) { /* Lock is needed to make things safe on 32 bit systems */ pthread_mutex_lock(&LOCK_global_system_variables); - global_system_variables.*offset= (ulonglong) tmp; + global_system_variables.*offset= (ulonglong) + var->save_result.ulonglong_value; pthread_mutex_unlock(&LOCK_global_system_variables); } else - thd->variables.*offset= (ulonglong) tmp; + thd->variables.*offset= (ulonglong) var->save_result.ulonglong_value; return 0; } @@ -2309,10 +2386,10 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var) goto end; } - key_cache->param_buff_size= - (ulonglong) fix_unsigned(thd, tmp, option_limits); + bound_unsigned(thd, &tmp, option_limits); + key_cache->param_buff_size= (ulonglong) tmp; - /* If key cache didn't existed initialize it, else resize it */ + /* If key cache didn't exist initialize it, else resize it */ key_cache->in_init= 1; pthread_mutex_unlock(&LOCK_global_system_variables); @@ -2338,7 +2415,7 @@ end: */ bool sys_var_key_cache_long::update(THD *thd, set_var *var) { - ulong tmp= (ulong) var->value->val_int(); + ulonglong tmp= var->value->val_int(); LEX_STRING *base_name= &var->base; bool error= 0; @@ -2363,8 +2440,8 @@ bool sys_var_key_cache_long::update(THD *thd, set_var *var) if (key_cache->in_init) goto end; - *((ulong*) (((char*) key_cache) + offset))= - (ulong) fix_unsigned(thd, tmp, option_limits); + bound_unsigned(thd, &tmp, option_limits); + *((ulong*) (((char*) key_cache) + offset))= (ulong) tmp; /* Don't create a new key cache if it didn't exist @@ -2981,6 +3058,16 @@ static bool set_option_bit(THD *thd, set_var *var) return 0; } +/* + Functions to be only used to update thd->options OPTION_BIN_LOG bit +*/ +static bool set_option_log_bin_bit(THD *thd, set_var *var) +{ + set_option_bit(thd, var); + if (!thd->in_sub_stmt) + thd->sql_log_bin_toplevel= thd->options & OPTION_BIN_LOG; + return 0; +} static bool set_option_autocommit(THD *thd, set_var *var) { @@ -3701,7 +3788,7 @@ bool sys_var_thd_storage_engine::update(THD *thd, set_var *var) void sys_var_thd_table_type::warn_deprecated(THD *thd) { - WARN_DEPRECATED(thd, "5.2", "@@table_type", "'@@storage_engine'"); + WARN_DEPRECATED(thd, "6.0", "@@table_type", "'@@storage_engine'"); } void sys_var_thd_table_type::set_default(THD *thd, enum_var_type type) @@ -3963,7 +4050,7 @@ bool process_key_caches(process_key_cache_t func) void sys_var_trust_routine_creators::warn_deprecated(THD *thd) { - WARN_DEPRECATED(thd, "5.2", "@@log_bin_trust_routine_creators", + WARN_DEPRECATED(thd, "6.0", "@@log_bin_trust_routine_creators", "'@@log_bin_trust_function_creators'"); } |