summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbar@mysql.com <>2006-01-18 12:55:38 +0400
committerbar@mysql.com <>2006-01-18 12:55:38 +0400
commit4e4b37a8ef4f69b90cc0e462b9e996f069a187dd (patch)
treea82974ad04899e9e56801ed796233b0748686eba
parent0e665a7aa56db02ca10d6feef7a7eec6c81e1642 (diff)
downloadmariadb-git-4e4b37a8ef4f69b90cc0e462b9e996f069a187dd.tar.gz
loaddata.result, loaddata.test:
Adding test case. sql_yacc.yy: Adding TEXT_STRING_filesystem, which converts from character_set_client to character_set_conversion. Replacing TEXT_STRING_sys to TEXT_STRING_filesystem in LOAD DATA and SELECT INTO OUTFILE contexts. sql_class.h, sql_class.cc: Adding character_set_filesystem variable, and charset_is_character_set_filesystem flag (to avoid conversion when it's not necessary). set_var.h, set_var.cc: Adding sys_var_character_set_filesystem mysqld.cc: Adding --character-set-filesystem startup option.
-rw-r--r--mysql-test/r/loaddata.result27
-rw-r--r--mysql-test/t/loaddata.test24
-rw-r--r--sql/mysqld.cc16
-rw-r--r--sql/set_var.cc28
-rw-r--r--sql/set_var.h9
-rw-r--r--sql/sql_class.cc3
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_yacc.yy20
8 files changed, 125 insertions, 4 deletions
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index a52952ffdb5..0246ca5f71d 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -139,3 +139,30 @@ a b c
10 NULL Ten
15 NULL Fifteen
drop table t1, t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1);
+SET NAMES latin1;
+SET character_set_filesystem=filename;
+select @@character_set_filesystem;
+@@character_set_filesystem
+filename
+SELECT * INTO OUTFILE 't-1' FROM t1;
+DELETE FROM t1;
+LOAD DATA INFILE 't-1' INTO TABLE t1;
+SELECT * FROM t1;
+a
+1
+DELETE FROM t1;
+SET character_set_filesystem=latin1;
+select @@character_set_filesystem;
+@@character_set_filesystem
+latin1
+LOAD DATA INFILE 't@002d1' INTO TABLE t1;
+SELECT * FROM t1;
+a
+1
+DROP TABLE t1;
+SET character_set_filesystem=default;
+select @@character_set_filesystem;
+@@character_set_filesystem
+binary
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index 09d97a42714..014d09da746 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -114,3 +114,27 @@ select * from t1;
drop table t1, t2;
# End of 5.0 tests
+
+
+#
+# Bug#12448 LOAD DATA / SELECT INTO OUTFILE
+# doesn't work with multibyte path name
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1);
+SET NAMES latin1;
+SET character_set_filesystem=filename;
+select @@character_set_filesystem;
+SELECT * INTO OUTFILE 't-1' FROM t1;
+DELETE FROM t1;
+LOAD DATA INFILE 't-1' INTO TABLE t1;
+SELECT * FROM t1;
+DELETE FROM t1;
+SET character_set_filesystem=latin1;
+select @@character_set_filesystem;
+LOAD DATA INFILE 't@002d1' INTO TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+--exec rm $MYSQL_TEST_DIR/var/master-data/test/t@002d1
+SET character_set_filesystem=default;
+select @@character_set_filesystem;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 5a78ab87d00..b1ca9466d05 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -315,6 +315,7 @@ static const char *sql_mode_str= "OFF";
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
static char *opt_init_slave, *language_ptr, *opt_init_connect;
static char *default_character_set_name;
+static char *character_set_filesystem_name;
static char *my_bind_addr_str;
static char *default_collation_name;
static char mysql_data_home_buff[2];
@@ -562,6 +563,7 @@ MY_BITMAP temp_pool;
CHARSET_INFO *system_charset_info, *files_charset_info ;
CHARSET_INFO *national_charset_info, *table_alias_charset;
+CHARSET_INFO *character_set_filesystem;
SHOW_COMP_OPTION have_row_based_replication;
SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_query_cache;
@@ -2799,6 +2801,12 @@ static int init_common_variables(const char *conf_file_name, int argc,
global_system_variables.character_set_client= default_charset_info;
global_system_variables.collation_connection= default_charset_info;
+ if (!(character_set_filesystem=
+ get_charset_by_csname(character_set_filesystem_name,
+ MY_CS_PRIMARY, MYF(MY_WME))))
+ return 1;
+ global_system_variables.character_set_filesystem= character_set_filesystem;
+
sys_init_connect.value_length= 0;
if ((sys_init_connect.value= opt_init_connect))
sys_init_connect.value_length= strlen(opt_init_connect);
@@ -4761,6 +4769,7 @@ enum options_mysqld
OPT_GROUP_CONCAT_MAX_LEN,
OPT_DEFAULT_COLLATION,
OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
+ OPT_CHARACTER_SET_FILESYSTEM,
OPT_INIT_CONNECT,
OPT_INIT_SLAVE,
OPT_SECURE_AUTH,
@@ -4914,6 +4923,11 @@ Disable with --skip-bdb (will save memory).",
(gptr*) &opt_character_set_client_handshake,
(gptr*) &opt_character_set_client_handshake,
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
+ "Set the filesystem character set.",
+ (gptr*) &character_set_filesystem_name,
+ (gptr*) &character_set_filesystem_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"character-set-server", 'C', "Set the default character set.",
(gptr*) &default_character_set_name, (gptr*) &default_character_set_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
@@ -6924,6 +6938,7 @@ static void mysql_init_variables(void)
files_charset_info= &my_charset_utf8_general_ci;
national_charset_info= &my_charset_utf8_general_ci;
table_alias_charset= &my_charset_bin;
+ character_set_filesystem= &my_charset_bin;
opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;
@@ -6977,6 +6992,7 @@ static void mysql_init_variables(void)
default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
default_collation_name= (char*) MYSQL_DEFAULT_COLLATION_NAME;
sys_charset_system.value= (char*) system_charset_info->csname;
+ character_set_filesystem_name= (char*) "binary";
/* Set default values for some option variables */
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 1ccd590171f..4f31c6ad1b4 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -193,6 +193,7 @@ sys_var_character_set_database sys_character_set_database("character_set_databas
sys_var_character_set_client sys_character_set_client("character_set_client");
sys_var_character_set_connection sys_character_set_connection("character_set_connection");
sys_var_character_set_results sys_character_set_results("character_set_results");
+sys_var_character_set_filesystem sys_character_set_filesystem("character_set_filesystem");
sys_var_thd_ulong sys_completion_type("completion_type",
&SV::completion_type,
check_completion_type,
@@ -706,6 +707,7 @@ SHOW_VAR init_vars[]= {
{sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS},
{sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS},
{sys_character_set_database.name, (char*) &sys_character_set_database,SHOW_SYS},
+ {sys_character_set_filesystem.name,(char*) &sys_character_set_filesystem, SHOW_SYS},
{sys_character_set_results.name,(char*) &sys_character_set_results, SHOW_SYS},
{sys_character_set_server.name, (char*) &sys_character_set_server,SHOW_SYS},
{sys_charset_system.name, (char*) &sys_charset_system, SHOW_SYS},
@@ -2022,6 +2024,32 @@ void sys_var_character_set_client::set_default(THD *thd, enum_var_type type)
CHARSET_INFO **
+sys_var_character_set_filesystem::ci_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return &global_system_variables.character_set_filesystem;
+ else
+ return &thd->variables.character_set_filesystem;
+}
+
+
+extern CHARSET_INFO *character_set_filesystem;
+
+void
+sys_var_character_set_filesystem::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.character_set_filesystem= character_set_filesystem;
+ else
+ {
+ thd->variables.character_set_filesystem= (global_system_variables.
+ character_set_filesystem);
+ thd->update_charset();
+ }
+}
+
+
+CHARSET_INFO **
sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
diff --git a/sql/set_var.h b/sql/set_var.h
index 2dde7f44a55..01705d5ff4d 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -549,6 +549,15 @@ public:
virtual CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type)= 0;
};
+class sys_var_character_set_filesystem :public sys_var_character_set
+{
+public:
+ sys_var_character_set_filesystem(const char *name_arg) :
+ sys_var_character_set(name_arg) {}
+ void set_default(THD *thd, enum_var_type type);
+ CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
+};
+
class sys_var_character_set_client :public sys_var_character_set
{
public:
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 3d5c9ac79b6..0885faffeb6 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -658,6 +658,9 @@ void THD::update_charset()
charset_is_collation_connection=
!String::needs_conversion(0,charset(),variables.collation_connection,
&not_used);
+ charset_is_character_set_filesystem=
+ !String::needs_conversion(0, charset(),
+ variables.character_set_filesystem, &not_used);
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index cb8c2818a19..e7efa5fcfda 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -258,6 +258,7 @@ struct system_variables
my_bool old_passwords;
/* Only charset part of these variables is sensible */
+ CHARSET_INFO *character_set_filesystem;
CHARSET_INFO *character_set_client;
CHARSET_INFO *character_set_results;
@@ -1126,6 +1127,7 @@ public:
bool query_error, bootstrap, cleanup_done;
bool tmp_table_used;
bool charset_is_system_charset, charset_is_collation_connection;
+ bool charset_is_character_set_filesystem;
bool enable_slow_log; /* enable slow log for current statement */
bool no_trans_update, abort_on_warning;
bool got_warning; /* Set on call to push_warning() */
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 69c33a8e7d0..4d7192812cc 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -730,7 +730,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
NCHAR_STRING opt_component key_cache_name
- sp_opt_label BIN_NUM label_ident
+ sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem
%type <lex_str_ptr>
opt_table_alias opt_fulltext_parser
@@ -7524,7 +7524,7 @@ select_var_ident:
;
into:
- INTO OUTFILE TEXT_STRING_sys
+ INTO OUTFILE TEXT_STRING_filesystem
{
LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -7533,7 +7533,7 @@ into:
YYABORT;
}
opt_field_term opt_line_term
- | INTO DUMPFILE TEXT_STRING_sys
+ | INTO DUMPFILE TEXT_STRING_filesystem
{
LEX *lex=Lex;
if (!lex->describe)
@@ -8596,7 +8596,7 @@ load: LOAD DATA_SYM
};
load_data:
- load_data_lock opt_local INFILE TEXT_STRING_sys
+ load_data_lock opt_local INFILE TEXT_STRING_filesystem
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_LOAD;
@@ -9124,6 +9124,18 @@ TEXT_STRING_literal:
;
+TEXT_STRING_filesystem:
+ TEXT_STRING
+ {
+ THD *thd= YYTHD;
+ if (thd->charset_is_character_set_filesystem)
+ $$= $1;
+ else
+ thd->convert_string(&$$, thd->variables.character_set_filesystem,
+ $1.str, $1.length, thd->charset());
+ }
+ ;
+
ident:
IDENT_sys { $$=$1; }
| READ_ONLY_SYM