diff --git a/mysql-test/r/rpl_charset.result b/mysql-test/r/rpl_charset.result index 6ba82d0dd2f96805eda3c036cd3c7757f44317aa..1433443691dc5207c22969cb9ae5e11f8cf374e2 100644 --- a/mysql-test/r/rpl_charset.result +++ b/mysql-test/r/rpl_charset.result @@ -153,7 +153,7 @@ master-bin.000001 4413 Query 1 4413 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIE master-bin.000001 4549 Query 1 4549 use `test2`; truncate table t1 master-bin.000001 4602 Query 1 4602 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64 master-bin.000001 4738 Intvar 1 4738 INSERT_ID=1 -master-bin.000001 4766 User var 1 4766 @`a`=_cp850'Müller' COLLATE cp850_general_ci +master-bin.000001 4766 User var 1 4766 @`a`=_cp850 0x4DFC6C6C6572 COLLATE cp850_general_ci master-bin.000001 4806 Query 1 4806 use `test2`; insert into t1 (b) values(collation(@a)) master-bin.000001 4882 Query 1 4882 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64 master-bin.000001 5018 Query 1 5018 use `test2`; drop database test2 diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result index ce2fb9c6f9cdb17b6dbece283b7e4314ac57c387..85768270ba30f46e42e6897082963302f61cc2a9 100644 --- a/mysql-test/r/rpl_user_variables.result +++ b/mysql-test/r/rpl_user_variables.result @@ -86,11 +86,11 @@ slave-bin.000001 313 Query 1 313 use `test`; insert into t1 values (@i1), (@i2), slave-bin.000001 396 User var 2 396 @`r1`=12.5 slave-bin.000001 439 User var 2 439 @`r2`=-12.5 slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2) -slave-bin.000001 551 User var 2 551 @`s1`=_latin1'This is a test' COLLATE latin1_swedish_ci -slave-bin.000001 600 User var 2 600 @`s2`=_latin1'' COLLATE latin1_swedish_ci -slave-bin.000001 635 User var 2 635 @`s3`=_latin1'abc\'def' COLLATE latin1_swedish_ci -slave-bin.000001 677 User var 2 677 @`s4`=_latin1'abc\\def' COLLATE latin1_swedish_ci -slave-bin.000001 719 User var 2 719 @`s5`=_latin1'abc\'def' COLLATE latin1_swedish_ci +slave-bin.000001 551 User var 2 551 @`s1`=_latin1 0x5468697320697320612074657374 COLLATE latin1_swedish_ci +slave-bin.000001 600 User var 2 600 @`s2`=_latin1 "" COLLATE latin1_swedish_ci +slave-bin.000001 635 User var 2 635 @`s3`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci +slave-bin.000001 677 User var 2 677 @`s4`=_latin1 0x6162635C646566 COLLATE latin1_swedish_ci +slave-bin.000001 719 User var 2 719 @`s5`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci slave-bin.000001 761 Query 1 761 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5) slave-bin.000001 851 User var 2 851 @`n1`=NULL slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1) @@ -99,7 +99,7 @@ slave-bin.000001 965 Query 1 965 use `test`; insert into t1 values (@n2) slave-bin.000001 1027 Query 1 1027 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1) slave-bin.000001 1115 User var 2 1115 @`a`=2 slave-bin.000001 1157 Query 1 1157 use `test`; insert into t1 values (@a+(@b:=@a+1)) -slave-bin.000001 1229 User var 2 1229 @`q`=_latin1'abc' COLLATE latin1_swedish_ci +slave-bin.000001 1229 User var 2 1229 @`q`=_latin1 0x616263 COLLATE latin1_swedish_ci slave-bin.000001 1266 Query 1 1266 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')) slave-bin.000001 1370 User var 2 1370 @`a`=5 slave-bin.000001 1412 Query 1 1412 use `test`; insert into t1 values (@a),(@a) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 605780a7280fbc46148e08521ce6d68511155760..2750478c1c543bff9827c9a401ceff06a3b27882 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -174,24 +174,24 @@ set @v=convert('abc' using ucs2); insert into t2 values (@v); show binlog events from 79; Log_name Pos Event_type Server_id Orig_log_pos Info -master-bin.000001 79 User var 1 79 @`a b`=_latin1'hello' COLLATE latin1_swedish_ci +master-bin.000001 79 User var 1 79 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci master-bin.000001 120 Query 1 120 use `test`; INSERT INTO t1 VALUES(@`a b`) -master-bin.000001 184 User var 1 184 @`var1`=_latin1'\';aaa' COLLATE latin1_swedish_ci +master-bin.000001 184 User var 1 184 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci master-bin.000001 226 Query 1 226 use `test`; insert into t1 values (@var1) master-bin.000001 290 Query 1 290 use `test`; create table t2 (c char(30)) charset=ucs2 -master-bin.000001 366 User var 1 366 @`v`=_ucs2'\0a\0b\0c' COLLATE ucs2_general_ci +master-bin.000001 366 User var 1 366 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci master-bin.000001 406 Query 1 406 use `test`; insert into t2 values (@v) /*!40019 SET @@session.max_insert_delayed_threads=0*/; -SET @`a b`:=_latin1'hello' COLLATE latin1_swedish_ci; +SET @`a b`:=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci; use test; SET TIMESTAMP=10000; INSERT INTO t1 VALUES(@`a b`); -SET @`var1`:=_latin1'\';aaa' COLLATE latin1_swedish_ci; +SET @`var1`:=_latin1 0x273B616161 COLLATE latin1_swedish_ci; SET TIMESTAMP=10000; insert into t1 values (@var1); SET TIMESTAMP=10000; create table t2 (c char(30)) charset=ucs2; -SET @`v`:=_ucs2'\0a\0b\0c' COLLATE ucs2_general_ci; +SET @`v`:=_ucs2 0x006100620063 COLLATE ucs2_general_ci; SET TIMESTAMP=10000; insert into t2 values (@v); drop table t1, t2; diff --git a/sql/log_event.cc b/sql/log_event.cc index a76725a95e0004ce4a44f7811bfb93e656e19a24..315b0f670dd2c2befc65b2b03335f8b574eac89f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -202,6 +202,29 @@ static inline int read_str(char * &buf, char *buf_end, char * &str, return 0; } +/* + Transforms a string into "" or its expression in 0x... form. +*/ +static char *str_to_hex(char *to, char *from, uint len) +{ + char *p= to; + if (len) + { + p= strmov(p, "0x"); + for (uint i= 0; i < len; i++, p+= 2) + { + /* val[i] is char. Casting to uchar helps greatly if val[i] < 0 */ + uint tmp= (uint) (uchar) from[i]; + p[0]= _dig_vec_upper[tmp >> 4]; + p[1]= _dig_vec_upper[tmp & 15]; + } + *p= 0; + } + else + p= strmov(p, "\"\""); + return p; // pointer to end 0 of 'to' +} + /************************************************************************** Log_event methods @@ -2210,9 +2233,9 @@ void User_var_log_event::pack_info(Protocol* protocol) } else { - char *p= strxmov(buf + val_offset, "_", cs->csname, "'", NullS); - p+= escape_string_for_mysql(&my_charset_bin, p, val, val_len); - p= strxmov(p, "' COLLATE ", cs->name, NullS); + char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS); + p= str_to_hex(p, val, val_len); + p= strxmov(p, " COLLATE ", cs->name, NullS); event_len= p-buf; } break; @@ -2341,11 +2364,24 @@ void User_var_log_event::print(FILE* file, bool short_form, char* last_db) break; case STRING_RESULT: { - char *p; - if (!(p= (char *)my_alloca(2*val_len+1))) + /* + Let's express the string in hex. That's the most robust way. If we + print it in character form instead, we need to escape it with + character_set_client which we don't know (we will know it in 5.0, but + in 4.1 we don't know it easily when we are printing + User_var_log_event). Explanation why we would need to bother with + character_set_client (quoting Bar): + > Note, the parser doesn't switch to another unescaping mode after + > it has met a character set introducer. + > For example, if an SJIS client says something like: + > SET @a= _ucs2 \0a\0b' + > the string constant is still unescaped according to SJIS, not + > according to UCS2. + */ + char *p, *q; + if (!(p= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits per byte break; // no error, as we are 'void' - escape_string_for_mysql(&my_charset_bin, p, val, val_len); -#if MYSQL_VERSION_ID < 50000 + str_to_hex(p, val, val_len); /* For proper behaviour when mysqlbinlog|mysql, we need to explicitely specify the variable's collation. It will however cause problems when @@ -2360,14 +2396,7 @@ void User_var_log_event::print(FILE* file, bool short_form, char* last_db) */ fprintf(file, ":=???;\n"); else - fprintf(file, ":=_%s'%s' COLLATE %s;\n", cs->csname, p, cs->name); -#else - /* - In 5.0 we will have some SET CHARACTER_SET_ect automatically printed - for all events where it's needed. - */ - fprintf(file, ":='%s';\n", p); -#endif + fprintf(file, ":=_%s %s COLLATE %s;\n", cs->csname, p, cs->name); my_afree(p); } break;