Commit 8e688a7a authored by Georgi Kodinov's avatar Georgi Kodinov

Bug #37339: SHOW VARIABLES not working properly with multi-byte datadir

      
The SHOW VARIABLES LIKE .../SELECT @@/SELECT ... FROM INFORMATION_SCHEMA.VARIABLES
were assuming that all the system variables are in system charset (UTF-8).
However the variables that are settable through command line will have a different
character set (character_set_filesystem).
Fixed the server to remember the correct character set of basedir, datadir, tmpdir,
ssl, plugin_dir, slave_load_tmpdir, innodb variables; init_connect and init_slave 
variables and use it when processing data.

mysql-test/r/ctype_filesystem.result:
  Bug #37339: test case (should be in utf-8)
mysql-test/t/ctype_filesystem-master.opt:
  Bug #37339: test case (should be in ISO-8859-1)
mysql-test/t/ctype_filesystem.test:
  Bug #37339: test case
sql/mysqld.cc:
  Bug #37339: remember the correct character set for init_slave and init_connect
sql/set_var.cc:
  Bug #37339: 
    - remember the character set of the relevant variables
    - implement storing and using the correct 
      character set
sql/set_var.h:
  Bug #37339: implement storing and using the correct 
  character set
sql/sql_show.cc:
  Bug #37339: implement storing and using the correct 
  character set
parent 380f1a84
SET CHARACTER SET utf8;
SHOW VARIABLES like 'character_sets_dir';
Variable_name Value
character_sets_dir /ß/
SHOW VARIABLES like 'character_set_filesystem';
Variable_name Value
character_set_filesystem latin1
SHOW VARIABLES like 'character_set_client';
Variable_name Value
character_set_client utf8
SET CHARACTER SET default;
--character-sets-dir=/ß
--character-set-filesystem=latin1
SET CHARACTER SET utf8;
SHOW VARIABLES like 'character_sets_dir';
SHOW VARIABLES like 'character_set_filesystem';
SHOW VARIABLES like 'character_set_client';
SET CHARACTER SET default;
...@@ -3035,12 +3035,14 @@ static int init_common_variables(const char *conf_file_name, int argc, ...@@ -3035,12 +3035,14 @@ static int init_common_variables(const char *conf_file_name, int argc,
sys_init_connect.value_length= strlen(opt_init_connect); sys_init_connect.value_length= strlen(opt_init_connect);
else else
sys_init_connect.value=my_strdup("",MYF(0)); sys_init_connect.value=my_strdup("",MYF(0));
sys_init_connect.is_os_charset= TRUE;
sys_init_slave.value_length= 0; sys_init_slave.value_length= 0;
if ((sys_init_slave.value= opt_init_slave)) if ((sys_init_slave.value= opt_init_slave))
sys_init_slave.value_length= strlen(opt_init_slave); sys_init_slave.value_length= strlen(opt_init_slave);
else else
sys_init_slave.value=my_strdup("",MYF(0)); sys_init_slave.value=my_strdup("",MYF(0));
sys_init_slave.is_os_charset= TRUE;
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1)) if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1; return 1;
......
This diff is collapsed.
...@@ -46,9 +46,17 @@ class sys_var ...@@ -46,9 +46,17 @@ class sys_var
sys_after_update_func after_update; sys_after_update_func after_update;
bool no_support_one_shot; bool no_support_one_shot;
/*
true if the value is in character_set_filesystem,
false otherwise.
Note that we can't use a pointer to the charset as the system var is
instantiated in global scope and the charset pointers are initialized
later.
*/
bool is_os_charset;
sys_var(const char *name_arg, sys_after_update_func func= NULL) sys_var(const char *name_arg, sys_after_update_func func= NULL)
:name(name_arg), after_update(func) :name(name_arg), after_update(func)
, no_support_one_shot(1) , no_support_one_shot(1), is_os_charset(FALSE)
{} {}
virtual ~sys_var() {} virtual ~sys_var() {}
virtual bool check(THD *thd, set_var *var); virtual bool check(THD *thd, set_var *var);
...@@ -68,6 +76,7 @@ class sys_var ...@@ -68,6 +76,7 @@ class sys_var
Item *item(THD *thd, enum_var_type type, LEX_STRING *base); Item *item(THD *thd, enum_var_type type, LEX_STRING *base);
virtual bool is_struct() { return 0; } virtual bool is_struct() { return 0; }
virtual bool is_readonly() const { return 0; } virtual bool is_readonly() const { return 0; }
CHARSET_INFO *charset(THD *thd);
}; };
...@@ -247,6 +256,17 @@ class sys_var_const_str :public sys_var ...@@ -247,6 +256,17 @@ class sys_var_const_str :public sys_var
}; };
class sys_var_const_os_str: public sys_var_const_str
{
public:
sys_var_const_os_str(const char *name_arg, const char *value_arg)
:sys_var_const_str(name_arg, value_arg)
{
is_os_charset= TRUE;
}
};
class sys_var_const_str_ptr :public sys_var class sys_var_const_str_ptr :public sys_var
{ {
public: public:
...@@ -276,6 +296,17 @@ class sys_var_const_str_ptr :public sys_var ...@@ -276,6 +296,17 @@ class sys_var_const_str_ptr :public sys_var
}; };
class sys_var_const_os_str_ptr :public sys_var_const_str_ptr
{
public:
sys_var_const_os_str_ptr(const char *name_arg, char **value_arg)
:sys_var_const_str_ptr(name_arg, value_arg)
{
is_os_charset= TRUE;
}
};
class sys_var_enum :public sys_var class sys_var_enum :public sys_var
{ {
uint *value; uint *value;
...@@ -791,6 +822,20 @@ class sys_var_readonly: public sys_var ...@@ -791,6 +822,20 @@ class sys_var_readonly: public sys_var
bool is_readonly() const { return 1; } bool is_readonly() const { return 1; }
}; };
class sys_var_readonly_os: public sys_var_readonly
{
public:
sys_var_readonly_os(const char *name_arg, enum_var_type type,
SHOW_TYPE show_type_arg,
sys_value_ptr_func value_ptr_func_arg)
:sys_var_readonly(name_arg, type, show_type_arg, value_ptr_func_arg)
{
is_os_charset= TRUE;
}
};
class sys_var_thd_time_zone :public sys_var_thd class sys_var_thd_time_zone :public sys_var_thd
{ {
public: public:
......
...@@ -1441,6 +1441,7 @@ static bool show_status_array(THD *thd, const char *wild, ...@@ -1441,6 +1441,7 @@ static bool show_status_array(THD *thd, const char *wild,
char name_buffer[80]; char name_buffer[80];
int len; int len;
LEX_STRING null_lex_str; LEX_STRING null_lex_str;
CHARSET_INFO *charset= system_charset_info;
DBUG_ENTER("show_status_array"); DBUG_ENTER("show_status_array");
null_lex_str.str= 0; // For sys_var->value_ptr() null_lex_str.str= 0; // For sys_var->value_ptr()
...@@ -1469,9 +1470,10 @@ static bool show_status_array(THD *thd, const char *wild, ...@@ -1469,9 +1470,10 @@ static bool show_status_array(THD *thd, const char *wild,
long nr; long nr;
if (show_type == SHOW_SYS) if (show_type == SHOW_SYS)
{ {
show_type= ((sys_var*) value)->show_type(); sys_var *var= ((sys_var *) value);
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type, show_type= var->show_type();
&null_lex_str); value= (char*) var->value_ptr(thd, value_type, &null_lex_str);
charset= var->charset(thd);
} }
pos= end= buff; pos= end= buff;
...@@ -1794,7 +1796,7 @@ static bool show_status_array(THD *thd, const char *wild, ...@@ -1794,7 +1796,7 @@ static bool show_status_array(THD *thd, const char *wild,
restore_record(table, s->default_values); restore_record(table, s->default_values);
table->field[0]->store(name_buffer, strlen(name_buffer), table->field[0]->store(name_buffer, strlen(name_buffer),
system_charset_info); system_charset_info);
table->field[1]->store(pos, (uint32) (end - pos), system_charset_info); table->field[1]->store(pos, (uint32) (end - pos), charset);
if (schema_table_store_record(thd, table)) if (schema_table_store_record(thd, table))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment