From a68f171585da08a855df1958caab3264a4b74006 Mon Sep 17 00:00:00 2001 From: unknown <aelkin@mysql.com> Date: Fri, 10 Feb 2006 15:12:27 +0200 Subject: [PATCH] BUG#16217 fix partly backported from 5.0. It is different in mysqlbinlog part. This changeset is assumed to stay in 4.1. client/mysql.cc: BUG#16217 forced to introduce a separate mysql client command. Feature is backported from 5.0, precisely ChangeSet 1.2034 06/02/09 16:23:09 aelkin@mysql.com (under second review at the moment) mysql-test/r/mysqlbinlog.result: changed in 5.0 mysql-test/t/mysqlbinlog.test: backported from 5.0. The last part of the test to mimic bug#16217 sql/log_event.cc: Inserting exclaiming comment command for mysql client made differently than in 5.0. Parsing still is cheap enough not to think to modify server code instead. --- client/mysql.cc | 26 +++++++++++++++++++++++++- mysql-test/r/mysqlbinlog.result | 19 ++++++++++++++++++- mysql-test/t/mysqlbinlog.test | 19 ++++++++++++++++++- sql/log_event.cc | 12 ++++++++++++ 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index d76195535a3..2f9031b84b8 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -190,7 +190,7 @@ static int com_quit(String *str,char*), com_connect(String *str,char*), com_status(String *str,char*), com_use(String *str,char*), com_source(String *str, char*), com_rehash(String *str, char*), com_tee(String *str, char*), - com_notee(String *str, char*), + com_notee(String *str, char*), com_charset(String *str,char*), com_prompt(String *str, char*), com_delimiter(String *str, char*); #ifdef USE_POPEN @@ -263,6 +263,8 @@ static COMMANDS commands[] = { "Set outfile [to_outfile]. Append everything into given outfile." }, { "use", 'u', com_use, 1, "Use another database. Takes database name as argument." }, + { "charset_name", 'C', com_charset, 1, + "Switch to another charset. Might be needed for processing binlog." }, /* Get bash-like expansion for some commands */ { "create table", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""}, @@ -1850,6 +1852,28 @@ com_clear(String *buffer,char *line __attribute__((unused))) return 0; } + /* ARGSUSED */ +static int +com_charset(String *buffer __attribute__((unused)), char *line) +{ + char buff[256], *param; + CHARSET_INFO * new_cs; + strmake(buff, line, sizeof(buff) - 1); + param= get_arg(buff, 0); + if (!param || !*param) + { + return put_info("Usage: \\C char_setname | charset charset_name", + INFO_ERROR, 0); + } + new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME)); + if (new_cs) + { + charset_info= new_cs; + put_info("Charset changed", INFO_INFO); + } + else put_info("Charset is not found", INFO_INFO); + return 0; +} /* Execute command diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index e88ece6b361..adaf0dad56b 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -84,4 +84,21 @@ SET INSERT_ID=1; use test; SET TIMESTAMP=1000000000; insert into t1 values ("Alas"); -drop table t1, t2; +flush logs; +create table t3 (f text character set utf8); +create table t4 (f text character set cp932); +flush logs; +rename table t3 to t03, t4 to t04; +select HEX(f) from t03; +HEX(f) +E382BD +select HEX(f) from t3; +HEX(f) +E382BD +select HEX(f) from t04; +HEX(f) +835C +select HEX(f) from t4; +HEX(f) +835C +drop table t1, t2, t03, t04, t3, t4; diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 0f9faa5c337..871886331f6 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -98,7 +98,24 @@ select "--- --position --" as ""; --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR --exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=27 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 + +# Bug#16217 (mysql client did not know how not switch its internal charset) +flush logs; +create table t3 (f text character set utf8); +create table t4 (f text character set cp932); +--exec $MYSQL --default-character-set=utf8 test -e "insert into t3 values(_utf8'ソ')" +--exec $MYSQL --default-character-set=cp932 test -e "insert into t4 values(_cp932'�\');" +flush logs; +rename table t3 to t03, t4 to t04; +--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000004 | $MYSQL --default-character-set=utf8 +# original and recovered data must be equal +select HEX(f) from t03; +select HEX(f) from t3; +select HEX(f) from t04; +select HEX(f) from t4; + + # clean up -drop table t1, t2; +drop table t1, t2, t03, t04, t3, t4; # End of 4.1 tests diff --git a/sql/log_event.cc b/sql/log_event.cc index 3f545df5776..19c32b2d28e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -949,6 +949,7 @@ Query_log_event::Query_log_event(const char* buf, int event_len, void Query_log_event::print(FILE* file, bool short_form, char* last_db) { char buff[40],*end; // Enough for SET TIMESTAMP + const uint set_len= sizeof("SET ONE_SHOT CHARACTER_SET_CLIENT=") - 1; if (!short_form) { print_header(file); @@ -978,6 +979,17 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME)); if (flags & LOG_EVENT_THREAD_SPECIFIC_F) fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id); + /* charset_name command for mysql client */ + if (!strncmp(query, "SET ONE_SHOT CHARACTER_SET_CLIENT=", set_len)) + { + char * endptr; + int cs_number= strtoul(query + set_len, &endptr, 10); + DBUG_ASSERT(*endptr == ','); + CHARSET_INFO *cs_info= get_charset(cs_number, MYF(MY_WME)); + if (cs_info) { + fprintf(file, "/*!\\C %s */;\n", cs_info->csname); + } + } my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME)); fprintf(file, ";\n"); }