Below is the list of changes that have just been committed into a local
5.1 repository of tnurnberg. When tnurnberg does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-24 13:47:44+01:00, tnurnberg@stripped +9 -0
Bug#32753: PAD_CHAR_TO_FULL_LENGTH is not documented and interferes with grant tables
SQL-mode PAD_CHAR_TO_FULL_LENGTH affected mysqld's user-table too. If
enabled, user-name and host were space-padded and no longer matched
the login-data of incoming connexions.
Patch disregards pad-flag while loading privileges so ability to log
in does not depend on SQL-mode.
---
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@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +27 -0
show that on out-of-range values, plugin interface throws errors
in STRICT mode and warnings otherwise.
mysql-test/r/sql_mode.result@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +10 -0
show that SQL-mode 'PAD_CHAR_TO_FULL_LENGTH' does not affect
loading of privileges (and by extension, ability to log in).
mysql-test/t/plugin.test@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +35 -0
show that on out-of-range values, plugin interface throws errors
in STRICT mode and warnings otherwise.
mysql-test/t/sql_mode.test@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +29 -0
show that SQL-mode 'PAD_CHAR_TO_FULL_LENGTH' does not affect
loading of privileges (and by extension, ability to log in).
sql/set_var.cc@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +29 -12
- handle signedness of values used in warnings
- in STRICT mode, throw errors rather than warnings
sql/sql_acl.cc@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +12 -3
temporarily disable SQL-mode 'PAD_CHAR_TO_FULL_LENGTH' while
reloading privileges
sql/sql_parse.cc@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +12 -0
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@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +8 -31
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@stripped, 2008-02-24 13:47:42+01:00, tnurnberg@stripped +14 -0
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.
diff -Nrup a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result
--- a/mysql-test/r/plugin.result 2007-11-14 10:48:18 +01:00
+++ b/mysql-test/r/plugin.result 2008-02-24 13:47:42 +01:00
@@ -27,3 +27,30 @@ SET GLOBAL example_enum_var= e2;
SET GLOBAL example_enum_var= impossible;
ERROR 42000: Variable 'enum_var' can't be set to the value of 'impossible'
UNINSTALL PLUGIN example;
+INSTALL PLUGIN example SONAME 'ha_example.so';
+select @@session.sql_mode into @old_sql_mode;
+set session sql_mode='';
+set global example_ulong_var=500;
+select @@global.example_ulong_var;
+@@global.example_ulong_var
+500
+set global example_ulong_var=1111;
+Warnings:
+Warning 1292 Truncated incorrect ulong_var value: '1111'
+select @@global.example_ulong_var;
+@@global.example_ulong_var
+1000
+set session sql_mode='STRICT_ALL_TABLES';
+set global example_ulong_var=500;
+select @@global.example_ulong_var;
+@@global.example_ulong_var
+500
+set global example_ulong_var=1111;
+ERROR 42000: Variable 'ulong_var' can't be set to the value of '1111'
+select @@global.example_ulong_var;
+@@global.example_ulong_var
+500
+set session sql_mode=@old_sql_mode;
+set session old=bla;
+ERROR HY000: Variable 'old' is a read only variable
+UNINSTALL PLUGIN example;
diff -Nrup a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result
--- a/mysql-test/r/sql_mode.result 2007-06-28 19:34:47 +02:00
+++ b/mysql-test/r/sql_mode.result 2008-02-24 13:47:42 +01:00
@@ -496,3 +496,13 @@ xb x
xcx
drop table t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
+create user mysqltest_32753@localhost;
+set @OLD_SQL_MODE=@@SESSION.SQL_MODE;
+set session sql_mode='PAD_CHAR_TO_FULL_LENGTH';
+flush privileges;
+select current_user();
+current_user()
+mysqltest_32753@localhost
+set session sql_mode=@OLD_SQL_MODE;
+flush privileges;
+drop user mysqltest_32753@localhost;
diff -Nrup a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test
--- a/mysql-test/t/plugin.test 2007-11-14 10:48:17 +01:00
+++ b/mysql-test/t/plugin.test 2008-02-24 13:47:42 +01:00
@@ -39,3 +39,38 @@ SET GLOBAL example_enum_var= e2;
SET GLOBAL example_enum_var= impossible;
UNINSTALL PLUGIN example;
+
+
+
+#
+# Bug #32757 hang with sql_mode set when setting some global variables
+#
+INSTALL PLUGIN example SONAME 'ha_example.so';
+
+select @@session.sql_mode into @old_sql_mode;
+
+# first, try normal sql_mode (no error, send OK)
+set session sql_mode='';
+set global example_ulong_var=500;
+select @@global.example_ulong_var;
+# overflow -- correct value, but throw warning
+set global example_ulong_var=1111;
+select @@global.example_ulong_var;
+
+# now, try STRICT (error occurrs, no message is sent, so send default)
+set session sql_mode='STRICT_ALL_TABLES';
+set global example_ulong_var=500;
+select @@global.example_ulong_var;
+# overflow -- throw warning, do NOT change value
+--error ER_WRONG_VALUE_FOR_VAR
+set global example_ulong_var=1111;
+select @@global.example_ulong_var;
+
+set session sql_mode=@old_sql_mode;
+
+# finally, show that conditions that already raised an error are not
+# adversely affected (error was already sent, do nothing)
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set session old=bla;
+
+UNINSTALL PLUGIN example;
diff -Nrup a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test
--- a/mysql-test/t/sql_mode.test 2007-04-27 00:12:06 +02:00
+++ b/mysql-test/t/sql_mode.test 2008-02-24 13:47:42 +01:00
@@ -279,3 +279,32 @@ select concat('x',b,'x') from t1;
drop table t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
+
+
+#
+# Bug #32753: PAD_CHAR_TO_FULL_LENGTH is not documented and interferes
+# with grant tables
+#
+
+create user mysqltest_32753@localhost;
+
+# try to make the user-table space-padded
+--connection default
+set @OLD_SQL_MODE=@@SESSION.SQL_MODE;
+set session sql_mode='PAD_CHAR_TO_FULL_LENGTH';
+flush privileges;
+
+# if user-table is affected by PAD_CHAR_TO_FULL_LENGTH, our connect will fail
+# --error 1045
+connect (user_32753,localhost,mysqltest_32753,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
+select current_user();
+
+# clean up
+--connection default
+set session sql_mode=@OLD_SQL_MODE;
+flush privileges;
+
+--disconnect user_32753
+
+--connection default
+drop user mysqltest_32753@localhost;
diff -Nrup a/sql/set_var.cc b/sql/set_var.cc
--- a/sql/set_var.cc 2008-01-10 18:44:20 +01:00
+++ b/sql/set_var.cc 2008-02-24 13:47:42 +01:00
@@ -123,7 +123,8 @@ static void fix_server_id(THD *thd, enum
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
}
-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,
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
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,
/* 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,
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
diff -Nrup a/sql/sql_acl.cc b/sql/sql_acl.cc
--- a/sql/sql_acl.cc 2008-02-13 16:37:03 +01:00
+++ b/sql/sql_acl.cc 2008-02-24 13:47:42 +01:00
@@ -192,7 +192,7 @@ static void update_hostname(acl_host_and
static bool compare_hostname(const acl_host_and_ip *host,const char *hostname,
const char *ip);
static my_bool acl_load(THD *thd, TABLE_LIST *tables);
-static my_bool grant_load(TABLE_LIST *tables);
+static my_bool grant_load(THD *thd, TABLE_LIST *tables);
/*
Convert scrambled password to binary form, according to scramble type,
@@ -314,8 +314,11 @@ static my_bool acl_load(THD *thd, TABLE_
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
char tmp_name[NAME_LEN+1];
int password_length;
+ ulong old_sql_mode= thd->variables.sql_mode;
DBUG_ENTER("acl_load");
+ thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
+
grant_version++; /* Privileges updated */
acl_cache->clear(1); // Clear locked hostname cache
@@ -622,6 +625,7 @@ static my_bool acl_load(THD *thd, TABLE_
return_val=0;
end:
+ thd->variables.sql_mode= old_sql_mode;
DBUG_RETURN(return_val);
}
@@ -3613,7 +3617,7 @@ end_unlock:
@retval TRUE Error
*/
-static my_bool grant_load(TABLE_LIST *tables)
+static my_bool grant_load(THD *thd, TABLE_LIST *tables)
{
MEM_ROOT *memex_ptr;
my_bool return_val= 1;
@@ -3621,7 +3625,11 @@ static my_bool grant_load(TABLE_LIST *ta
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**,
THR_MALLOC);
+ ulong old_sql_mode= thd->variables.sql_mode;
DBUG_ENTER("grant_load");
+
+ thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
+
(void) hash_init(&column_priv_hash,system_charset_info,
0,0,0, (hash_get_key) get_grant_table,
(hash_free_key) free_grant_table,0);
@@ -3673,6 +3681,7 @@ static my_bool grant_load(TABLE_LIST *ta
return_val=0; // Return ok
end_unlock:
+ thd->variables.sql_mode= old_sql_mode;
t_table->file->ha_index_end();
my_pthread_setspecific_ptr(THR_MALLOC, save_mem_root_ptr);
DBUG_RETURN(return_val);
@@ -3786,7 +3795,7 @@ my_bool grant_reload(THD *thd)
old_mem= memex;
init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0);
- if ((return_val= grant_load(tables)))
+ if ((return_val= grant_load(thd, tables)))
{ // Error. Revert to old hash
DBUG_PRINT("error",("Reverting to old privileges"));
grant_free(); /* purecov: deadcode */
diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
--- a/sql/sql_parse.cc 2007-12-14 14:01:11 +01:00
+++ b/sql/sql_parse.cc 2008-02-24 13:47:42 +01:00
@@ -3185,6 +3185,18 @@ end_with_restore_list:
thd->one_shot_set|= lex->one_shot_set;
send_ok(thd);
}
+ else
+ {
+ /*
+ We encountered some sort of error, but no message was sent.
+ Send something semi-generic here since we don't know which
+ assignment in the list caused the error.
+ */
+ if (!thd->is_error())
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
+ goto error;
+ }
+
break;
}
diff -Nrup a/sql/sql_plugin.cc b/sql/sql_plugin.cc
--- a/sql/sql_plugin.cc 2007-12-13 12:49:55 +01:00
+++ b/sql/sql_plugin.cc 2008-02-24 13:47:42 +01:00
@@ -210,6 +210,8 @@ static void reap_plugins(void);
/* declared in set_var.cc */
extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error);
+extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
+ const char *name, longlong val);
#ifdef EMBEDDED_LIBRARY
/* declared in sql_base.cc */
@@ -1888,16 +1890,8 @@ static int check_func_int(THD *thd, stru
else
*(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
- if (fixed)
- {
- char buf[22];
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TRUNCATED_WRONG_VALUE,
- ER(ER_TRUNCATED_WRONG_VALUE), var->name,
- ullstr(tmp, buf));
- }
- return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
- (*(int *)save != (int) tmp);
+ return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
+ var->name, (longlong) tmp);
}
@@ -1916,16 +1910,8 @@ static int check_func_long(THD *thd, str
else
*(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
- if (fixed)
- {
- char buf[22];
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TRUNCATED_WRONG_VALUE,
- ER(ER_TRUNCATED_WRONG_VALUE), var->name,
- ullstr(tmp, buf));
- }
- return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
- (*(long *)save != (long) tmp);
+ return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
+ var->name, (longlong) tmp);
}
@@ -1937,7 +1923,6 @@ static int check_func_longlong(THD *thd,
struct my_option options;
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,
@@ -1945,16 +1930,8 @@ static int check_func_longlong(THD *thd,
else
*(longlong *)save= getopt_ll_limit_value(tmp, &options, &fixed);
- if (fixed)
- {
- char buf[22];
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TRUNCATED_WRONG_VALUE,
- ER(ER_TRUNCATED_WRONG_VALUE), var->name,
- ullstr(tmp, buf));
- }
- return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
- (*(long long *)save != tmp);
+ return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
+ var->name, (longlong) tmp);
}
static int check_func_str(THD *thd, struct st_mysql_sys_var *var,
diff -Nrup a/storage/example/ha_example.cc b/storage/example/ha_example.cc
--- a/storage/example/ha_example.cc 2007-11-14 10:48:15 +01:00
+++ b/storage/example/ha_example.cc 2008-02-24 13:47:42 +01:00
@@ -849,6 +849,7 @@ struct st_mysql_storage_engine example_s
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
static ulong srv_enum_var= 0;
+static ulong srv_ulong_var= 0;
const char *enum_var_names[]=
{
@@ -871,8 +872,21 @@ static MYSQL_SYSVAR_ENUM(
0, // def
&enum_var_typelib); // typelib
+static MYSQL_SYSVAR_ULONG(
+ ulong_var,
+ srv_ulong_var,
+ PLUGIN_VAR_RQCMDARG,
+ "0..1000",
+ NULL,
+ NULL,
+ 8,
+ 0,
+ 1000,
+ 0);
+
static struct st_mysql_sys_var* example_system_variables[]= {
MYSQL_SYSVAR(enum_var),
+ MYSQL_SYSVAR(ulong_var),
NULL
};
| Thread |
|---|
| • bk commit into 5.1 tree (tnurnberg:1.2668) BUG#32753 | Tatjana A Nuernberg | 24 Feb |