diff --git a/mysql-test/r/binlog_stm_ctype_ucs.result b/mysql-test/r/binlog_stm_ctype_ucs.result deleted file mode 100644 index 76f3a3b06b9..00000000000 --- a/mysql-test/r/binlog_stm_ctype_ucs.result +++ /dev/null @@ -1,27 +0,0 @@ -SET TIMESTAMP=10000; -create table t2 (c char(30)) charset=ucs2; -set @v=convert('abc' using ucs2); -reset master; -insert into t2 values (@v); -show binlog events from 102; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 102 User var 1 142 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci -master-bin.000001 142 Query 1 231 use `test`; insert into t2 values (@v) -flush logs; -/*!40019 SET @@session.max_insert_delayed_threads=0*/; -/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; -DELIMITER /*!*/; -ROLLBACK/*!*/; -SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/; -use test/*!*/; -SET TIMESTAMP=10000/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; -SET @@session.sql_mode=0/*!*/; -/*!\C latin1 *//*!*/; -SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -insert into t2 values (@v)/*!*/; -DELIMITER ; -# End of log file -ROLLBACK /* added by mysqlbinlog */; -/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; -drop table t2; diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog.result new file mode 100644 index 00000000000..ff295961008 --- /dev/null +++ b/mysql-test/r/ctype_cp932_binlog.result @@ -0,0 +1,46 @@ +drop table if exists t1; +set names cp932; +set character_set_database = cp932; +RESET MASTER; +CREATE TABLE t1(f1 blob); +PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; +SET @var1= x'8300'; +EXECUTE stmt1 USING @var1; +SHOW BINLOG EVENTS FROM 98; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 98 Query 1 188 use `test`; CREATE TABLE t1(f1 blob) +master-bin.000001 188 User var 1 227 @`var1`=_binary 0x8300 COLLATE binary +master-bin.000001 227 Query 1 323 use `test`; INSERT INTO t1 VALUES(@'var1') +SELECT HEX(f1) FROM t1; +HEX(f1) +8300 +DROP table t1; +CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1, +s2 CHAR(50) CHARACTER SET cp932, +d DECIMAL(10,2))| +CREATE PROCEDURE bug18293 (IN ins1 CHAR(50), +IN ins2 CHAR(50) CHARACTER SET cp932, +IN ind DECIMAL(10,2)) +BEGIN +INSERT INTO t4 VALUES (ins1, ins2, ind); +END| +CALL bug18293("Foo's a Bar", _cp932 0xED40ED41ED42, 47.93)| +SELECT HEX(s1),HEX(s2),d FROM t4| +HEX(s1) HEX(s2) d +466F6F2773206120426172 ED40ED41ED42 47.93 +DROP PROCEDURE bug18293| +DROP TABLE t4| +SHOW BINLOG EVENTS FROM 402| +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 402 Query 1 568 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1, +s2 CHAR(50) CHARACTER SET cp932, +d DECIMAL(10,2)) +master-bin.000001 568 Query 1 816 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE bug18293 (IN ins1 CHAR(50), +IN ins2 CHAR(50) CHARACTER SET cp932, +IN ind DECIMAL(10,2)) +BEGIN +INSERT INTO t4 VALUES (ins1, ins2, ind); +END +master-bin.000001 816 Query 1 1035 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93)) +master-bin.000001 1035 Query 1 1124 use `test`; DROP PROCEDURE bug18293 +master-bin.000001 1124 Query 1 1203 use `test`; DROP TABLE t4 diff --git a/mysql-test/r/ctype_cp932_notembedded.result b/mysql-test/r/ctype_cp932_notembedded.result new file mode 100644 index 00000000000..c58bfc65454 --- /dev/null +++ b/mysql-test/r/ctype_cp932_notembedded.result @@ -0,0 +1,17 @@ +drop table if exists t1; +set names cp932; +set character_set_database = cp932; +RESET MASTER; +CREATE TABLE t1(f1 blob); +PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; +SET @var1= x'8300'; +EXECUTE stmt1 USING @var1; +SHOW BINLOG EVENTS FROM 98; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 98 Query 1 188 use `test`; CREATE TABLE t1(f1 blob) +master-bin.000001 188 User var 1 227 @`var1`=_binary 0x8300 COLLATE binary +master-bin.000001 227 Query 1 323 use `test`; INSERT INTO t1 VALUES(@'var1') +SELECT HEX(f1) FROM t1; +HEX(f1) +8300 +DROP table t1; diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index d671b347786..db47e70e9e9 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -274,3 +274,60 @@ call p1(); 1 drop procedure p1; flush logs; +create table t1 (a varchar(64) character set utf8); +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set character_set_database=koi8r; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set character_set_database=latin1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set character_set_database=koi8r; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set character_set_database=latin1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8r; +select hex(a) from t1; +hex(a) +C3BF +D0AA +C3BF +C3BF +D0AA +C3BF +D0AA +drop table t1; +flush logs; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +use test/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; +SET @@session.sql_mode=0/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +create table t1 (a varchar(64) character set utf8)/*!*/; +SET TIMESTAMP=1000000000/*!*/; +load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-6-0' INTO table t1/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.collation_database=7/*!*/; +load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-7-0' INTO table t1/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-8-0' INTO table t1/*!*/; +SET TIMESTAMP=1000000000/*!*/; +load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-9-0' INTO table t1/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.collation_database=7/*!*/; +load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-a-0' INTO table t1/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-b-0' INTO table t1/*!*/; +SET TIMESTAMP=1000000000/*!*/; +load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r/*!*/; +SET TIMESTAMP=1000000000/*!*/; +drop table t1/*!*/; +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; diff --git a/mysql-test/r/rpl_loaddata2.result b/mysql-test/r/rpl_loaddata2.result index 196093211b6..929d06e74cf 100644 --- a/mysql-test/r/rpl_loaddata2.result +++ b/mysql-test/r/rpl_loaddata2.result @@ -4,150 +4,34 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -CREATE TABLE t1 (word CHAR(20) NOT NULL); -LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t1; -SELECT * FROM t1 ORDER BY word; -word -Aarhus -Aarhus -Aaron -Aaron -Ababa -Ababa -aback -aback -abaft -abaft -abandon -abandon -abandoned -abandoned -abandoning -abandoning -abandonment -abandonment -abandons -abandons -abase -abased -abasement -abasements -abases -abash -abashed -abashes -abashing -abasing -abate -abated -abatement -abatements -abater -abates -abating -Abba -abbe -abbey -abbeys -abbot -abbots -Abbott -abbreviate -abbreviated -abbreviates -abbreviating -abbreviation -abbreviations -Abby -abdomen -abdomens -abdominal -abduct -abducted -abduction -abductions -abductor -abductors -abducts -Abe -abed -Abel -Abelian -Abelson -Aberdeen -Abernathy -aberrant -aberration -SELECT * FROM t1 ORDER BY word; -word -Aarhus -Aarhus -Aaron -Aaron -Ababa -Ababa -aback -aback -abaft -abaft -abandon -abandon -abandoned -abandoned -abandoning -abandoning -abandonment -abandonment -abandons -abandons -abase -abased -abasement -abasements -abases -abash -abashed -abashes -abashing -abasing -abate -abated -abatement -abatements -abater -abates -abating -Abba -abbe -abbey -abbeys -abbot -abbots -Abbott -abbreviate -abbreviated -abbreviates -abbreviating -abbreviation -abbreviations -Abby -abdomen -abdomens -abdominal -abduct -abducted -abduction -abductions -abductor -abductors -abducts -Abe -abed -Abel -Abelian -Abelson -Aberdeen -Abernathy -aberrant -aberration +create table t1 (a varchar(10) character set utf8); +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set @@character_set_database=koi8r; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set @@character_set_database=DEFAULT; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set @@character_set_database=koi8r; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set @@character_set_database=DEFAULT; +load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8r; +select hex(a) from t1; +hex(a) +C3BF +D0AA +C3BF +C3BF +C3BF +D0AA +D0AA +select hex(a) from t1; +hex(a) +C3BF +D0AA +C3BF +C3BF +C3BF +D0AA +D0AA drop table t1; diff --git a/mysql-test/std_data/loaddata6.dat b/mysql-test/std_data/loaddata6.dat new file mode 100644 index 00000000000..29e181ebb88 --- /dev/null +++ b/mysql-test/std_data/loaddata6.dat @@ -0,0 +1 @@ +ÿ diff --git a/mysql-test/extra/binlog_tests/ctype_cp932_binlog.test b/mysql-test/t/ctype_cp932_binlog.test similarity index 64% rename from mysql-test/extra/binlog_tests/ctype_cp932_binlog.test rename to mysql-test/t/ctype_cp932_binlog.test index 5e93d6e126e..ee0e588fdae 100644 --- a/mysql-test/extra/binlog_tests/ctype_cp932_binlog.test +++ b/mysql-test/t/ctype_cp932_binlog.test @@ -26,11 +26,32 @@ SET @var1= x'8300'; # code (and I have used it to test the fix) until there is some way to # exercise this code from mysql-test-run. EXECUTE stmt1 USING @var1; ---replace_column 2 # 5 # ---replace_regex /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 102; +SHOW BINLOG EVENTS FROM 98; SELECT HEX(f1) FROM t1; DROP table t1; # end test for bug#11338 # End of 4.1 tests + +# +# Bug#18293: Values in stored procedure written to binlog unescaped +# + +delimiter |; +CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1, + s2 CHAR(50) CHARACTER SET cp932, + d DECIMAL(10,2))| +CREATE PROCEDURE bug18293 (IN ins1 CHAR(50), + IN ins2 CHAR(50) CHARACTER SET cp932, + IN ind DECIMAL(10,2)) + BEGIN + INSERT INTO t4 VALUES (ins1, ins2, ind); + END| +CALL bug18293("Foo's a Bar", _cp932 0xED40ED41ED42, 47.93)| +SELECT HEX(s1),HEX(s2),d FROM t4| +DROP PROCEDURE bug18293| +DROP TABLE t4| +SHOW BINLOG EVENTS FROM 402| +delimiter ;| + +# End of 5.0 tests diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 8c5d5f772fc..0d20b1061bf 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -193,6 +193,29 @@ drop procedure p1; --exec $MYSQL_BINLOG --help 2>&1 > /dev/null --enable_query_log +# +# Bug#15126 character_set_database is not replicated +# (LOAD DATA INFILE need it) +# + +flush logs; +create table t1 (a varchar(64) character set utf8); +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set character_set_database=koi8r; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set character_set_database=latin1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set character_set_database=koi8r; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set character_set_database=latin1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8r; +select hex(a) from t1; +drop table t1; +flush logs; +--exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000011 + # End of 5.0 tests # diff --git a/mysql-test/t/rpl_loaddata2.test b/mysql-test/t/rpl_loaddata2.test index 9e908cac677..7f2389cb9f6 100644 --- a/mysql-test/t/rpl_loaddata2.test +++ b/mysql-test/t/rpl_loaddata2.test @@ -1,14 +1,33 @@ ---source include/master-slave.inc +# +# Check LOAD DATA + character sets + replication +# +source include/master-slave.inc; -CREATE TABLE t1 (word CHAR(20) NOT NULL); -LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t1; -SELECT * FROM t1 ORDER BY word; -sync_slave_with_master; +# +# Bug#15126 character_set_database is not replicated +# (LOAD DATA INFILE need it) +# +connection master; +create table t1 (a varchar(10) character set utf8); +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set @@character_set_database=koi8r; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set @@character_set_database=DEFAULT; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set @@character_set_database=koi8r; +load data infile '../std_data_ln/loaddata6.dat' into table t1; +set @@character_set_database=DEFAULT; +load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8r; -# Check -SELECT * FROM t1 ORDER BY word; +select hex(a) from t1; -# Cleanup +save_master_pos; +connection slave; +sync_with_master; + +select hex(a) from t1; connection master; drop table t1; sync_slave_with_master; diff --git a/sql/log_event.cc b/sql/log_event.cc index bf19c552432..f161efe6492 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1281,7 +1281,8 @@ bool Query_log_event::write(IO_CACHE* file) 1+4+ // code of autoinc and the 2 autoinc variables 1+6+ // code of charset and charset 1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name - 1+2 // code of lc_time_names and lc_time_names_number + 1+2+ // code of lc_time_names and lc_time_names_number + 1+2 // code of charset_database and charset_database_number ], *start, *start_of_status; ulong event_length; @@ -1400,6 +1401,13 @@ bool Query_log_event::write(IO_CACHE* file) int2store(start, lc_time_names_number); start+= 2; } + if (charset_database_number) + { + DBUG_ASSERT(charset_database_number <= 0xFFFF); + *start++= Q_CHARSET_DATABASE_CODE; + int2store(start, charset_database_number); + start+= 2; + } /* Here there could be code like if (command-line-option-which-says-"log_this_variable" && inited) @@ -1465,7 +1473,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, sql_mode(thd_arg->variables.sql_mode), auto_increment_increment(thd_arg->variables.auto_increment_increment), auto_increment_offset(thd_arg->variables.auto_increment_offset), - lc_time_names_number(thd_arg->variables.lc_time_names->number) + lc_time_names_number(thd_arg->variables.lc_time_names->number), + charset_database_number(0) { time_t end_time; time(&end_time); @@ -1473,6 +1482,9 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, catalog_len = (catalog) ? (uint32) strlen(catalog) : 0; /* status_vars_len is set just before writing the event */ db_len = (db) ? (uint32) strlen(db) : 0; + if (thd_arg->variables.collation_database != thd_arg->db_charset) + charset_database_number= thd_arg->variables.collation_database->number; + /* If we don't use flags2 for anything else than options contained in thd->options, it would be more efficient to flags2=thd_arg->options @@ -1543,7 +1555,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, db(NullS), catalog_len(0), status_vars_len(0), flags2_inited(0), sql_mode_inited(0), charset_inited(0), auto_increment_increment(1), auto_increment_offset(1), - time_zone_len(0), lc_time_names_number(0) + time_zone_len(0), lc_time_names_number(0), charset_database_number(0) { ulong data_len; uint32 tmp; @@ -1648,6 +1660,10 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, lc_time_names_number= uint2korr(pos); pos+= 2; break; + case Q_CHARSET_DATABASE_CODE: + charset_database_number= uint2korr(pos); + pos+= 2; + break; default: /* That's why you must write status vars in growing order of code */ DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ @@ -1846,6 +1862,16 @@ void Query_log_event::print_query_header(IO_CACHE* file, lc_time_names_number, print_event_info->delimiter); print_event_info->lc_time_names_number= lc_time_names_number; } + if (charset_database_number != print_event_info->charset_database_number) + { + if (charset_database_number) + fprintf(file, "SET @@session.collation_database=%d%s\n", + charset_database_number, print_event_info->delimiter); + else + fprintf(file, "SET @@session.collation_database=DEFAULT%s\n", + print_event_info->delimiter); + print_event_info->charset_database_number= charset_database_number; + } } @@ -2001,7 +2027,21 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, } else thd->variables.lc_time_names= &my_locale_en_US; - + if (charset_database_number) + { + CHARSET_INFO *cs; + if (!(cs= get_charset(charset_database_number, MYF(0)))) + { + char buf[20]; + int10_to_str((int) charset_database_number, buf, -10); + my_error(ER_UNKNOWN_COLLATION, MYF(0), buf); + goto compare_errors; + } + thd->variables.collation_database= cs; + } + else + thd->variables.collation_database= thd->db_charset; + /* Execute the query (note that we bypass dispatch_command()) */ mysql_parse(thd, thd->query, thd->query_length); diff --git a/sql/log_event.h b/sql/log_event.h index ac7bc0cb082..7cbe8925d9a 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -272,6 +272,7 @@ struct sql_ex_info #define Q_LC_TIME_NAMES_CODE 7 +#define Q_CHARSET_DATABASE_CODE 8 /* Intvar event post-header */ #define I_TYPE_OFFSET 0 @@ -533,10 +534,11 @@ typedef struct st_print_event_info char charset[6]; // 3 variables, each of them storable in 2 bytes char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH]; uint lc_time_names_number; + uint charset_database_number; st_print_event_info() :flags2_inited(0), sql_mode_inited(0), auto_increment_increment(1),auto_increment_offset(1), charset_inited(0), - lc_time_names_number(0) + lc_time_names_number(0), charset_database_number(0) { /* Currently we only use static PRINT_EVENT_INFO objects, so zeroed at @@ -849,6 +851,7 @@ public: uint time_zone_len; /* 0 means uninited */ const char *time_zone_str; uint lc_time_names_number; /* 0 means en_US */ + uint charset_database_number; #ifndef MYSQL_CLIENT diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2519d3a15e6..42078678e51 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -996,6 +996,7 @@ sql_exchange::sql_exchange(char *name,bool flag) enclosed= line_start= &my_empty_string; line_term= &default_line_term; escaped= &default_escaped; + cs= NULL; } bool select_send::send_fields(List &list, uint flags) diff --git a/sql/sql_class.h b/sql/sql_class.h index 1f5f7aedbb4..5b507713814 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1656,6 +1656,7 @@ public: bool opt_enclosed; bool dumpfile; ulong skip_lines; + CHARSET_INFO *cs; sql_exchange(char *name,bool dumpfile_flag); }; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 9fbad7eeb07..802eed5116e 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -316,7 +316,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, info.handle_duplicates=handle_duplicates; info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX; - READ_INFO read_info(file,tot_length,thd->variables.collation_database, + READ_INFO read_info(file,tot_length, + ex->cs ? ex->cs : thd->variables.collation_database, *field_term,*ex->line_start, *ex->line_term, *enclosed, info.escape_char, read_file_from_client, is_fifo); if (read_info.error) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 297bd9f2737..b7d7038c338 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1067,6 +1067,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); old_or_new_charset_name_or_default collation_name collation_name_or_default + opt_load_data_charset %type internal_variable_name @@ -4662,6 +4663,10 @@ charset_name_or_default: charset_name { $$=$1; } | DEFAULT { $$=NULL; } ; +opt_load_data_charset: + /* Empty */ { $$= NULL; } + | charset charset_name_or_default { $$= $2; } + ; old_or_new_charset_name: ident_or_text @@ -8964,6 +8969,8 @@ load_data: lex->update_list.empty(); lex->value_list.empty(); } + opt_load_data_charset + { Lex->exchange->cs= $12; } opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec opt_load_data_set_spec {}