diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index b28311aee3d..c1580390f63 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -141,7 +141,7 @@ set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; set GLOBAL myisam_max_sort_file_size=default; ---replace_result 2147483647 FILE_SIZE 2146435072 FILE_SIZE +--replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE show variables like 'myisam_max_sort_file_size'; --replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE select * from information_schema.session_variables where variable_name like 'myisam_max_sort_file_size'; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 3c0faf0c0af..7691472b76a 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -867,7 +867,7 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, bool *fix) { bool adjusted= FALSE; - ulonglong old= num, mod; + ulonglong old= num; char buf1[255], buf2[255]; if ((ulonglong) num > (ulonglong) optp->max_value && @@ -892,6 +892,8 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, num= ((ulonglong) ULONG_MAX); adjusted= TRUE; } +#else + num= min(num, LONG_MAX); #endif break; default: diff --git a/sql/set_var.cc b/sql/set_var.cc index a7fa6be974d..d78a691768e 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -122,6 +122,7 @@ 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 *thd, ulonglong num, const struct my_option *option_limits); +static bool get_unsigned(THD *thd, set_var *var); static void throw_bounds_warning(THD *thd, const char *name, ulonglong num); static KEY_CACHE *create_key_cache(const char *name, uint length); void fix_sql_mode_var(THD *thd, enum_var_type type); @@ -1124,6 +1125,18 @@ static ulonglong fix_unsigned(THD *thd, ulonglong num, return out; } +static bool get_unsigned(THD *thd, set_var *var) +{ + 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); + } + return 0; +} + sys_var_long_ptr:: sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg, @@ -1135,9 +1148,7 @@ 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) { - longlong v= var->value->val_int(); - var->save_result.ulonglong_value= v < 0 ? 0 : v; - return 0; + return get_unsigned(thd, var); } bool sys_var_long_ptr_global::update(THD *thd, set_var *var) @@ -1150,9 +1161,9 @@ bool sys_var_long_ptr_global::update(THD *thd, set_var *var) { #if SIZEOF_LONG < SIZEOF_LONG_LONG /* Avoid overflows on 32 bit systems */ - if (tmp > (ulonglong) ~(ulong) 0) + if (tmp > ULONG_MAX) { - tmp= ((ulonglong) ~(ulong) 0); + tmp= ULONG_MAX; throw_bounds_warning(thd, name, var->save_result.ulonglong_value); } #endif @@ -1220,7 +1231,7 @@ uchar *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) bool sys_var_thd_ulong::check(THD *thd, set_var *var) { - return (sys_var_thd::check(thd, var) || + return (get_unsigned(thd, var) || (check_func && (*check_func)(thd, var))); } @@ -1238,9 +1249,9 @@ bool sys_var_thd_ulong::update(THD *thd, set_var *var) if (option_limits) tmp= (ulong) fix_unsigned(thd, tmp, option_limits); #if SIZEOF_LONG < SIZEOF_LONG_LONG - else if (tmp > (ulonglong) ~(ulong) 0) + else if (tmp > ULONG_MAX) { - tmp= ((ulonglong) ~(ulong) 0); + tmp= ULONG_MAX; throw_bounds_warning(thd, name, var->save_result.ulonglong_value); } #endif @@ -1320,6 +1331,11 @@ uchar *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type, return (uchar*) &(thd->variables.*offset); } +bool sys_var_thd_ulonglong::check(THD *thd, set_var *var) +{ + return get_unsigned(thd, var); +} + bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) { ulonglong tmp= var->save_result.ulonglong_value; diff --git a/sql/set_var.h b/sql/set_var.h index eb2c893c89e..2881903133d 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -379,6 +379,7 @@ public: void set_default(THD *thd, enum_var_type type); SHOW_TYPE show_type() { return SHOW_LONGLONG; } uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); + bool check(THD *thd, set_var *var); bool check_default(enum_var_type type) { return type == OPT_GLOBAL && !option_limits; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 08b33c4502c..002fb5be31e 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1880,7 +1880,13 @@ static int check_func_int(THD *thd, struct st_mysql_sys_var *var, struct my_option options; value->val_int(value, &tmp); plugin_opt_set_limits(&options, var); - *(int *)save= (int) getopt_ull_limit_value(tmp, &options, &fixed); + + if (var->flags & PLUGIN_VAR_UNSIGNED) + *(uint *)save= (uint) getopt_ull_limit_value((ulonglong) tmp, &options, + &fixed); + else + *(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed); + if (fixed) { char buf[22]; @@ -1902,7 +1908,13 @@ static int check_func_long(THD *thd, struct st_mysql_sys_var *var, struct my_option options; value->val_int(value, &tmp); plugin_opt_set_limits(&options, var); - *(long *)save= (long) getopt_ull_limit_value(tmp, &options, &fixed); + + if (var->flags & PLUGIN_VAR_UNSIGNED) + *(ulong *)save= (ulong) getopt_ull_limit_value((ulonglong) tmp, &options, + &fixed); + else + *(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed); + if (fixed) { char buf[22]; @@ -1925,6 +1937,13 @@ static int check_func_longlong(THD *thd, struct st_mysql_sys_var *var, value->val_int(value, &tmp); plugin_opt_set_limits(&options, var); *(ulonglong *)save= getopt_ull_limit_value(tmp, &options, &fixed); + + if (var->flags & PLUGIN_VAR_UNSIGNED) + *(ulonglong *)save= getopt_ull_limit_value((ulonglong) tmp, &options, + &fixed); + else + *(longlong *)save= getopt_ll_limit_value(tmp, &options, &fixed); + if (fixed) { char buf[22];