mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
Bug#32757: hang with sql_mode set when setting some global variables
If setting a system-variable provided by a plug-in failed, no OK or error was sent in some cases, hanging the client. We now send an error in the case from the ticket (integer-argument out of range in STRICT mode). We also provide a semi-generic fallback message for possible future cases like this where an error is signalled, but no message is sent to the client. The error/warning handling is unified so it's the same again for variables provided by plugins and those in the server proper. mysql-test/r/plugin.result: show that on out-of-range values, plugin interface throws errors in STRICT mode and warnings otherwise. mysql-test/t/plugin.test: show that on out-of-range values, plugin interface throws errors in STRICT mode and warnings otherwise. sql/set_var.cc: - handle signedness of values used in warnings - in STRICT mode, throw errors rather than warnings sql/sql_parse.cc: If sql_set_variables() returns with an error but no message was sent to the client, send a semi-generic one so the session won't hang and we won't fail silently. sql/sql_plugin.cc: throw a warning if more than just block-size was corrected (or an error in STRICT mode). use functions from set_var for uniform behaviour of server- and plug-in variables. storage/example/ha_example.cc: Add a ULONG system variable to example plugin so we can test integers in the plugin-interface without having to depend on the presence of innobase.
This commit is contained in:
parent
a22c3d2109
commit
9bd3b8545a
6 changed files with 125 additions and 43 deletions
|
|
@ -123,7 +123,8 @@ 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);
|
||||
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);
|
||||
void fix_sql_mode_var(THD *thd, enum_var_type type);
|
||||
static uchar *get_error_count(THD *thd);
|
||||
|
|
@ -1106,13 +1107,29 @@ static void fix_server_id(THD *thd, enum_var_type type)
|
|||
}
|
||||
|
||||
|
||||
static void throw_bounds_warning(THD *thd, const char *name, ulonglong num)
|
||||
bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
|
||||
const char *name, longlong val)
|
||||
{
|
||||
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));
|
||||
if (fixed)
|
||||
{
|
||||
char buf[22];
|
||||
|
||||
if (unsignd)
|
||||
ullstr((ulonglong) val, buf);
|
||||
else
|
||||
llstr(val, buf);
|
||||
|
||||
if (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES)
|
||||
{
|
||||
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static ulonglong fix_unsigned(THD *thd, ulonglong num,
|
||||
|
|
@ -1121,8 +1138,7 @@ static ulonglong fix_unsigned(THD *thd, ulonglong num,
|
|||
bool fixed= FALSE;
|
||||
ulonglong out= getopt_ull_limit_value(num, option_limits, &fixed);
|
||||
|
||||
if (fixed)
|
||||
throw_bounds_warning(thd, option_limits->name, num);
|
||||
throw_bounds_warning(thd, fixed, TRUE, option_limits->name, (longlong) num);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -1165,7 +1181,8 @@ bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
|
|||
if (tmp > ULONG_MAX)
|
||||
{
|
||||
tmp= ULONG_MAX;
|
||||
throw_bounds_warning(thd, name, var->save_result.ulonglong_value);
|
||||
throw_bounds_warning(thd, TRUE, TRUE, name,
|
||||
(longlong) var->save_result.ulonglong_value);
|
||||
}
|
||||
#endif
|
||||
*value= (ulong) tmp;
|
||||
|
|
@ -1250,7 +1267,7 @@ bool sys_var_thd_ulong::update(THD *thd, set_var *var)
|
|||
/* Don't use bigger value than given with --maximum-variable-name=.. */
|
||||
if ((ulong) tmp > max_system_variables.*offset)
|
||||
{
|
||||
throw_bounds_warning(thd, name, tmp);
|
||||
throw_bounds_warning(thd, TRUE, TRUE, name, (longlong) tmp);
|
||||
tmp= max_system_variables.*offset;
|
||||
}
|
||||
|
||||
|
|
@ -1260,7 +1277,7 @@ bool sys_var_thd_ulong::update(THD *thd, set_var *var)
|
|||
else if (tmp > ULONG_MAX)
|
||||
{
|
||||
tmp= ULONG_MAX;
|
||||
throw_bounds_warning(thd, name, var->save_result.ulonglong_value);
|
||||
throw_bounds_warning(thd, TRUE, TRUE, name, (longlong) var->save_result.ulonglong_value);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue