summaryrefslogtreecommitdiff
path: root/sql/set_var.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/set_var.cc')
-rw-r--r--sql/set_var.cc119
1 files changed, 87 insertions, 32 deletions
diff --git a/sql/set_var.cc b/sql/set_var.cc
index df78fc58f09..71a5a26f1d7 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -113,6 +113,9 @@ 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);
+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);
static byte *get_error_count(THD *thd);
@@ -1459,6 +1462,40 @@ static void fix_trans_mem_root(THD *thd, enum_var_type type)
static void fix_server_id(THD *thd, enum_var_type type)
{
server_id_supplied = 1;
+ thd->server_id= server_id;
+}
+
+
+static void throw_bounds_warning(THD *thd, const char *name, ulonglong num)
+{
+ char buf[22];
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), name,
+ ullstr(num, buf));
+}
+
+static ulonglong fix_unsigned(THD *thd, ulonglong num,
+ const struct my_option *option_limits)
+{
+ bool fixed= FALSE;
+ ulonglong out= getopt_ull_limit_value(num, option_limits, &fixed);
+
+ if (fixed)
+ throw_bounds_warning(thd, option_limits->name, 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;
}
@@ -1472,9 +1509,7 @@ sys_var_long_ptr(const char *name_arg, ulong *value_ptr_arg,
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)
@@ -1482,9 +1517,20 @@ 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) getopt_ull_limit_value(tmp, 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, name, var->save_result.ulonglong_value);
+ }
+#endif
*value= (ulong) tmp;
+ }
+
pthread_mutex_unlock(guard);
return 0;
}
@@ -1492,8 +1538,10 @@ bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type)
{
+ bool not_used;
pthread_mutex_lock(guard);
- *value= (ulong) option_limits->def_value;
+ *value= (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(guard);
}
@@ -1503,7 +1551,7 @@ 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) getopt_ull_limit_value(tmp, option_limits);
+ *value= (ulonglong) fix_unsigned(thd, tmp, option_limits);
else
*value= (ulonglong) tmp;
pthread_mutex_unlock(&LOCK_global_system_variables);
@@ -1513,8 +1561,10 @@ bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
{
+ bool not_used;
pthread_mutex_lock(&LOCK_global_system_variables);
- *value= (ulonglong) option_limits->def_value;
+ *value= getopt_ull_limit_value((ulonglong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
@@ -1546,45 +1596,36 @@ byte *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)));
}
bool sys_var_thd_ulong::update(THD *thd, set_var *var)
{
ulonglong tmp= var->save_result.ulonglong_value;
- char buf[22];
- bool truncated= false;
/* Don't use bigger value than given with --maximum-variable-name=.. */
if ((ulong) tmp > max_system_variables.*offset)
{
- truncated= true;
- llstr(tmp, buf);
+ throw_bounds_warning(thd, name, tmp);
tmp= max_system_variables.*offset;
}
-#if SIZEOF_LONG == 4
- /* Avoid overflows on 32 bit systems */
- if (tmp > (ulonglong) ~(ulong) 0)
+ if (option_limits)
+ tmp= (ulong) fix_unsigned(thd, tmp, option_limits);
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+ else if (tmp > ULONG_MAX)
{
- truncated= true;
- llstr(tmp, buf);
- tmp= ((ulonglong) ~(ulong) 0);
+ tmp= ULONG_MAX;
+ throw_bounds_warning(thd, name, var->save_result.ulonglong_value);
}
#endif
- if (truncated)
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TRUNCATED_WRONG_VALUE,
- ER(ER_TRUNCATED_WRONG_VALUE), name,
- buf);
- if (option_limits)
- tmp= (ulong) getopt_ull_limit_value(tmp, option_limits);
if (var->type == OPT_GLOBAL)
global_system_variables.*offset= (ulong) tmp;
else
thd->variables.*offset= (ulong) tmp;
+
return 0;
}
@@ -1593,8 +1634,11 @@ void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
/* We will not come here if option_limits is not set */
- global_system_variables.*offset= (ulong) option_limits->def_value;
+ global_system_variables.*offset=
+ (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
+ option_limits, &not_used);
}
else
thd->variables.*offset= global_system_variables.*offset;
@@ -1619,7 +1663,7 @@ bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
tmp= max_system_variables.*offset;
if (option_limits)
- tmp= (ha_rows) getopt_ull_limit_value(tmp, option_limits);
+ tmp= (ha_rows) fix_unsigned(thd, tmp, option_limits);
if (var->type == OPT_GLOBAL)
{
/* Lock is needed to make things safe on 32 bit systems */
@@ -1637,9 +1681,12 @@ void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
/* We will not come here if option_limits is not set */
pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= (ha_rows) option_limits->def_value;
+ global_system_variables.*offset=
+ (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
@@ -1655,6 +1702,11 @@ byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
return (byte*) &(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;
@@ -1663,7 +1715,7 @@ bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
tmp= max_system_variables.*offset;
if (option_limits)
- tmp= getopt_ull_limit_value(tmp, 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 */
@@ -1681,8 +1733,11 @@ void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= (ulonglong) option_limits->def_value;
+ global_system_variables.*offset=
+ getopt_ull_limit_value((ulonglong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
@@ -2522,7 +2577,7 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
}
key_cache->param_buff_size=
- (ulonglong) getopt_ull_limit_value(tmp, option_limits);
+ (ulonglong) fix_unsigned(thd, tmp, option_limits);
/* If key cache didn't existed initialize it, else resize it */
key_cache->in_init= 1;
@@ -2570,7 +2625,7 @@ bool sys_var_key_cache_long::update(THD *thd, set_var *var)
goto end;
*((ulong*) (((char*) key_cache) + offset))=
- (ulong) getopt_ull_limit_value(tmp, option_limits);
+ (ulong) fix_unsigned(thd, tmp, option_limits);
/*
Don't create a new key cache if it didn't exist