[Commits] Rev 3503: MDEV-382: Multiple SQL injections in mysqld replication code in http://bazaar.launchpad.net/~maria-captains/maria/5.5

knielsen at knielsen-hq.org knielsen at knielsen-hq.org
Wed Aug 22 15:48:43 EEST 2012


At http://bazaar.launchpad.net/~maria-captains/maria/5.5

------------------------------------------------------------
revno: 3503
revision-id: knielsen at knielsen-hq.org-20120706091916-92lztvewh8gij2b9
parent: knielsen at knielsen-hq.org-20120822123105-s7tghd5t47oxywt9
committer: knielsen at knielsen-hq.org
branch nick: mariadb-5.5
timestamp: Fri 2012-07-06 11:19:16 +0200
message:
  MDEV-382: Multiple SQL injections in mysqld replication code
  
  A number of places in the replication code was building SQL statements
  and incorrectly backtick-quoting (or not quoting at all) SQL
  identifiers. This opens the possibility for SQL injections, as
  such statements are run by the slave SQL thread and/or sent through
  mysqlbinlog|mysql, usually with root permissions.
  
  Fix by properly backtick-quoting in all cases. Also fix some cases
  which are mostly informational (so likely not exploitable), like
  SHOW BINLOG EVENTS and error messages.
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc	2012-08-09 15:22:00 +0000
+++ b/client/mysqlbinlog.cc	2012-07-06 09:19:16 +0000
@@ -743,7 +743,9 @@ print_use_stmt(PRINT_EVENT_INFO* pinfo,
     return;
 
   // In case of rewrite rule print USE statement for db_to
-  fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter);
+  char buf[FN_REFLEN*2+3];  /* Room for expand ` to `` + initial/final ` + \0 */
+  my_snprintf(buf, sizeof(buf), "%`s", db_to);
+  fprintf(result_file, "use %s%s\n", buf, pinfo->delimiter);
 
   // Copy the *original* db to pinfo to suppress emiting
   // of USE stmts by log_event print-functions.

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2012-03-28 17:26:00 +0000
+++ b/include/my_sys.h	2012-07-06 09:19:16 +0000
@@ -751,6 +751,8 @@ extern size_t my_b_fill(IO_CACHE *info);
 extern void my_b_seek(IO_CACHE *info,my_off_t pos);
 extern size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length);
 extern my_off_t my_b_filelength(IO_CACHE *info);
+extern size_t my_b_write_backtick_quote(IO_CACHE *info, const char *str,
+                                        size_t len);
 extern size_t my_b_printf(IO_CACHE *info, const char* fmt, ...);
 extern size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
 extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,

=== modified file 'mysql-test/r/mysqlbinlog-innodb.result'
--- a/mysql-test/r/mysqlbinlog-innodb.result	2011-10-19 19:45:18 +0000
+++ b/mysql-test/r/mysqlbinlog-innodb.result	2012-07-06 09:19:16 +0000
@@ -34,7 +34,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 INSERT INTO t1 VALUES (1)
 /*!*/;
@@ -65,7 +65,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use foo/*!*/;
+use `foo`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 INSERT INTO t1 VALUES (1)
 /*!*/;

=== modified file 'mysql-test/r/mysqlbinlog.result'
--- a/mysql-test/r/mysqlbinlog.result	2011-10-19 19:45:18 +0000
+++ b/mysql-test/r/mysqlbinlog.result	2012-07-06 09:19:16 +0000
@@ -18,7 +18,7 @@ flush logs;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -111,7 +111,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
 /*!*/;
@@ -202,7 +202,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 insert into t1 values ("Alas")
 /*!*/;
@@ -219,7 +219,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -312,7 +312,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
 /*!*/;
@@ -403,7 +403,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 insert into t1 values ("Alas")
 /*!*/;
@@ -427,7 +427,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1108844555/*!*/;
 insert t1 values (1)
 /*!*/;
@@ -445,7 +445,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1108844555/*!*/;
 insert t1 values (1)
 /*!*/;
@@ -498,7 +498,7 @@ ERROR 42000: PROCEDURE test.p1 does not
 /*!40019 SET @@session.max_insert_delayed_threads=0*/;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -548,7 +548,7 @@ flush logs;
 /*!40019 SET @@session.max_insert_delayed_threads=0*/;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -725,7 +725,7 @@ FLUSH LOGS;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1253783037/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -825,7 +825,7 @@ BEGIN
 SET TIMESTAMP=1266652094/*!*/;
 SavePoint mixed_cases
 /*!*/;
-use db1/*!*/;
+use `db1`/*!*/;
 SET TIMESTAMP=1266652094/*!*/;
 INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
 /*!*/;

=== modified file 'mysql-test/r/mysqlbinlog2.result'
--- a/mysql-test/r/mysqlbinlog2.result	2010-01-07 15:39:11 +0000
+++ b/mysql-test/r/mysqlbinlog2.result	2012-07-06 09:19:16 +0000
@@ -19,7 +19,7 @@ insert into t1 values(null, "f");
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -103,7 +103,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=1/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 insert into t1 values(null, "a")
 /*!*/;
@@ -172,7 +172,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -209,7 +209,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -263,7 +263,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -289,7 +289,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -326,7 +326,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -369,7 +369,7 @@ flush logs;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -445,7 +445,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=6/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609943/*!*/;
 insert into t1 values(null, "f")
 /*!*/;
@@ -474,7 +474,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=1/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 insert into t1 values(null, "a")
 /*!*/;
@@ -535,7 +535,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=6/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609943/*!*/;
 insert into t1 values(null, "f")
 /*!*/;
@@ -564,7 +564,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -605,7 +605,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=6/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609943/*!*/;
 insert into t1 values(null, "f")
 /*!*/;
@@ -622,7 +622,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -720,7 +720,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -761,7 +761,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=6/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609943/*!*/;
 insert into t1 values(null, "f")
 /*!*/;
@@ -778,7 +778,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -820,7 +820,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -904,7 +904,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=1/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 insert into t1 values(null, "a")
 /*!*/;
@@ -972,7 +972,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -1009,7 +1009,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -1062,7 +1062,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -1088,7 +1088,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -1125,7 +1125,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -1167,7 +1167,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -1243,7 +1243,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=6/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609943/*!*/;
 insert into t1 values(null, "f")
 /*!*/;
@@ -1272,7 +1272,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=1/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 insert into t1 values(null, "a")
 /*!*/;
@@ -1333,7 +1333,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=6/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609943/*!*/;
 insert into t1 values(null, "f")
 /*!*/;
@@ -1361,7 +1361,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -1402,7 +1402,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=6/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609943/*!*/;
 insert into t1 values(null, "f")
 /*!*/;
@@ -1419,7 +1419,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -1516,7 +1516,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=3/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609944/*!*/;
 insert into t1 values(null, "c")
 /*!*/;
@@ -1557,7 +1557,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET INSERT_ID=6/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609943/*!*/;
 insert into t1 values(null, "f")
 /*!*/;
@@ -1574,7 +1574,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -1616,7 +1616,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1579609942/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

=== modified file 'mysql-test/r/mysqlbinlog_row.result'
--- a/mysql-test/r/mysqlbinlog_row.result	2010-08-23 22:31:12 +0000
+++ b/mysql-test/r/mysqlbinlog_row.result	2012-07-06 09:19:16 +0000
@@ -336,7 +336,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

=== modified file 'mysql-test/r/mysqlbinlog_row_innodb.result'
--- a/mysql-test/r/mysqlbinlog_row_innodb.result	2010-03-24 15:03:44 +0000
+++ b/mysql-test/r/mysqlbinlog_row_innodb.result	2012-07-06 09:19:16 +0000
@@ -2253,7 +2253,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -3876,7 +3876,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -4243,7 +4243,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -4804,7 +4804,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

=== modified file 'mysql-test/r/mysqlbinlog_row_myisam.result'
--- a/mysql-test/r/mysqlbinlog_row_myisam.result	2010-03-12 12:42:30 +0000
+++ b/mysql-test/r/mysqlbinlog_row_myisam.result	2012-07-06 09:19:16 +0000
@@ -2253,7 +2253,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -3898,7 +3898,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -4271,7 +4271,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -4842,7 +4842,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

=== modified file 'mysql-test/r/mysqlbinlog_row_trans.result'
--- a/mysql-test/r/mysqlbinlog_row_trans.result	2010-01-07 15:39:11 +0000
+++ b/mysql-test/r/mysqlbinlog_row_trans.result	2012-07-06 09:19:16 +0000
@@ -132,7 +132,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #010909  4:46:40 server id 1  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

=== modified file 'mysql-test/r/user_var-binlog.result'
--- a/mysql-test/r/user_var-binlog.result	2010-01-07 15:39:11 +0000
+++ b/mysql-test/r/user_var-binlog.result	2012-07-06 09:19:16 +0000
@@ -34,7 +34,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=10000/*!*/;
 INSERT INTO t1 VALUES(@`a b`)
 /*!*/;

=== modified file 'mysql-test/suite/binlog/r/binlog_base64_flag.result'
--- a/mysql-test/suite/binlog/r/binlog_base64_flag.result	2011-12-12 22:58:40 +0000
+++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result	2012-07-06 09:19:16 +0000
@@ -35,7 +35,7 @@ DELIMITER /*!*/;
 # at 4
 <#>ROLLBACK/*!*/;
 # at 102
-<#>use test/*!*/;
+<#>use `test`/*!*/;
 SET TIMESTAMP=1196959712/*!*/;
 <#>SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
 SET @@session.sql_mode=0/*!*/;

=== modified file 'mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result'
--- a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result	2011-10-19 19:45:18 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result	2012-07-06 09:19:16 +0000
@@ -35,7 +35,7 @@ DELIMITER /*!*/;
 #010909  4:46:40 server id #  end_log_pos #     Start: binlog v 4, server v #.##.## created 010909  4:46:40 at startup
 ROLLBACK/*!*/;
 # at #
-use new_test1/*!*/;
+use `new_test1`/*!*/;
 #010909  4:46:40 server id #  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
@@ -72,7 +72,7 @@ COMMIT
 /*!*/;
 # at #
 #010909  4:46:40 server id #  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test2/*!*/;
+use `test2`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 CREATE TABLE t2 (a INT)
 /*!*/;
@@ -115,7 +115,7 @@ SET TIMESTAMP=1000000000/*!*/;
 COMMIT
 /*!*/;
 # at #
-use new_test3/*!*/;
+use `new_test3`/*!*/;
 #010909  4:46:40 server id #  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
 SET TIMESTAMP=1000000000/*!*/;
 CREATE TABLE t3 (a INT)
@@ -229,7 +229,7 @@ DELIMITER /*!*/;
 #010909  4:46:40 server id #  end_log_pos #     Start: binlog v 4, server v #.##.## created 010909  4:46:40 at startup
 ROLLBACK/*!*/;
 # at #
-use new_test1/*!*/;
+use `new_test1`/*!*/;
 #010909  4:46:40 server id #  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=#/*!*/;
@@ -266,7 +266,7 @@ COMMIT
 /*!*/;
 # at #
 #010909  4:46:40 server id #  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
-use test2/*!*/;
+use `test2`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 CREATE TABLE t2 (a INT)
 /*!*/;
@@ -309,7 +309,7 @@ SET TIMESTAMP=1000000000/*!*/;
 COMMIT
 /*!*/;
 # at #
-use new_test3/*!*/;
+use `new_test3`/*!*/;
 #010909  4:46:40 server id #  end_log_pos #     Query   thread_id=#     exec_time=#     error_code=0
 SET TIMESTAMP=1000000000/*!*/;
 CREATE TABLE t3 (a INT)

=== modified file 'mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result'
--- a/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result	2010-01-07 15:39:11 +0000
+++ b/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result	2012-07-06 09:19:16 +0000
@@ -26,7 +26,7 @@ SET @@session.collation_database=DEFAULT
 BEGIN
 /*!*/;
 SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=10000/*!*/;
 insert into t2 values (@v)
 /*!*/;

=== modified file 'mysql-test/suite/rpl/r/rpl_hrtime.result'
--- a/mysql-test/suite/rpl/r/rpl_hrtime.result	2011-10-19 19:45:18 +0000
+++ b/mysql-test/suite/rpl/r/rpl_hrtime.result	2012-07-06 09:19:16 +0000
@@ -30,7 +30,7 @@ include/rpl_end.inc
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1293832861/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

=== added file 'mysql-test/suite/rpl/r/rpl_mdev382.result'
--- a/mysql-test/suite/rpl/r/rpl_mdev382.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_mdev382.result	2012-07-06 09:19:16 +0000
@@ -0,0 +1,325 @@
+include/master-slave.inc
+[connection master]
+create table t1 (a int primary key) engine=innodb;
+create table t2 (a int primary key) engine=myisam;
+begin;
+insert into t1 values (1);
+SET sql_mode = 'ANSI_QUOTES';
+savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
+insert into t1 values (2);
+insert into t2 values (1);
+SET sql_mode = '';
+rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
+Warnings:
+Warning 1196    Some non-transactional changed tables couldn't be rolled back
+insert into t1 values (3);
+commit;
+show binlog events from <binlog_start>;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000001       #       Query   #       #       use `test`; create table t1 (a int primary key) engine=innodb
+master-bin.000001       #       Query   #       #       use `test`; create table t2 (a int primary key) engine=myisam
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `test`; insert into t2 values (1)
+master-bin.000001       #       Query   #       #       COMMIT
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values (1)
+master-bin.000001       #       Query   #       #       SAVEPOINT "a`; create database couldbebadthingshere; savepoint `dummy"
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values (2)
+master-bin.000001       #       Query   #       #       ROLLBACK TO `a``; create database couldbebadthingshere; savepoint ``dummy`
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values (3)
+master-bin.000001       #       Xid     #       #       COMMIT /* XID */
+BEGIN;
+insert into t1 values(10);
+set sql_mode = 'ANSI_QUOTES';
+set sql_quote_show_create = 1;
+savepoint a;
+insert into t1 values(11);
+savepoint "a""a";
+insert into t1 values(12);
+set sql_quote_show_create = 0;
+savepoint b;
+insert into t1 values(13);
+savepoint "b""b";
+insert into t1 values(14);
+set sql_mode = '';
+set sql_quote_show_create = 1;
+savepoint c;
+insert into t1 values(15);
+savepoint `c``c`;
+insert into t1 values(16);
+set sql_quote_show_create = 0;
+savepoint d;
+insert into t1 values(17);
+savepoint `d``d`;
+insert into t1 values(18);
+COMMIT;
+set sql_quote_show_create = 1;
+show binlog events from <binlog_start>;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(10)
+master-bin.000001       #       Query   #       #       SAVEPOINT "a"
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(11)
+master-bin.000001       #       Query   #       #       SAVEPOINT "a""a"
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(12)
+master-bin.000001       #       Query   #       #       SAVEPOINT b
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(13)
+master-bin.000001       #       Query   #       #       SAVEPOINT "b""b"
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(14)
+master-bin.000001       #       Query   #       #       SAVEPOINT `c`
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(15)
+master-bin.000001       #       Query   #       #       SAVEPOINT `c``c`
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(16)
+master-bin.000001       #       Query   #       #       SAVEPOINT d
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(17)
+master-bin.000001       #       Query   #       #       SAVEPOINT `d``d`
+master-bin.000001       #       Query   #       #       use `test`; insert into t1 values(18)
+master-bin.000001       #       Xid     #       #       COMMIT /* XID */
+*** Test correct USE statement in SHOW BINLOG EVENTS ***
+set sql_mode = 'ANSI_QUOTES';
+CREATE DATABASE "db1`; SELECT 'oops!'";
+use "db1`; SELECT 'oops!'";
+CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
+INSERT INTO t1 VALUES (1);
+set sql_mode = '';
+INSERT INTO t1 VALUES (2);
+set sql_mode = 'ANSI_QUOTES';
+show binlog events from <binlog_start>;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000001       #       Query   #       #       CREATE DATABASE "db1`; SELECT 'oops!'"
+master-bin.000001       #       Query   #       #       use "db1`; SELECT 'oops!'"; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (1)
+master-bin.000001       #       Query   #       #       COMMIT
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (2)
+master-bin.000001       #       Query   #       #       COMMIT
+set sql_mode = '';
+set sql_quote_show_create = 0;
+show binlog events from <binlog_start>;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000001       #       Query   #       #       CREATE DATABASE "db1`; SELECT 'oops!'"
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
+master-bin.000001       #       Query   #       #       COMMIT
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
+master-bin.000001       #       Query   #       #       COMMIT
+set sql_quote_show_create = 1;
+show binlog events from <binlog_start>;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000001       #       Query   #       #       CREATE DATABASE "db1`; SELECT 'oops!'"
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
+master-bin.000001       #       Query   #       #       COMMIT
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
+master-bin.000001       #       Query   #       #       COMMIT
+DROP TABLE t1;
+use test;
+***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
+use `db1``; SELECT 'oops!'`;
+set timestamp=1000000000;
+CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
+`c``3` VARCHAR(7));
+LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
+  FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
+  LINES TERMINATED BY '\n'
+  (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
+SELECT * FROM `t``1`;
+a`1     b`2     c`3
+fo\o    bar     |b"a'z!
+truncate `t``1`;
+use test;
+LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt'
+  INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
+  FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
+  LINES TERMINATED BY '\n'
+  (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
+SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
+a`1     b`2     c`3
+fo\o    bar     |b"a'z!
+show binlog events from <binlog_start>;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
+`c``3` VARCHAR(7))
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Begin_load_query        #       #       ;file_id=#;block_len=#
+master-bin.000001       #       Execute_load_query      #       #       use `db1``; SELECT 'oops!'`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`= concat('|', "b""a'z", "!") ;file_id=#
+master-bin.000001       #       Query   #       #       COMMIT
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; truncate `t``1`
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Begin_load_query        #       #       ;file_id=#;block_len=#
+master-bin.000001       #       Execute_load_query      #       #       use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`= concat('|', "b""a'z", "!") ;file_id=#
+master-bin.000001       #       Query   #       #       COMMIT
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+ROLLBACK/*!*/;
+use `db1``; SELECT 'oops!'`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
+`c``3` VARCHAR(7))
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+LOAD DATA LOCAL INFILE '<name>' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`= concat('|', "b""a'z", "!")
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+truncate `t``1`
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+use `test`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+LOAD DATA LOCAL INFILE '<name>' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`= concat('|', "b""a'z", "!")
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
+a`1     b`2     c`3
+fo\o    bar     |b"a'z!
+DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
+drop table t1,t2;
+*** Test user variables whose names require correct quoting ***
+use `db1``; SELECT 'oops!'`;
+CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
+INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
+SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
+@`a``1`:=a1     @`a``2`:=a2     @`a``3`:=a3     @`a``4`:=a4     @`b```:=b       @```c`:=c       @```d```:=d
+-9223372036854775808    42      9223372036854775807     18446744073709551615    -1.234560123456789e125  -1234501234567890123456789012345678901234567890123456789.0123456789     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
+show binlog events from <binlog_start>;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
+master-bin.000001       #       Query   #       #       COMMIT
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       User var        #       #       @`a``1`=-9223372036854775808
+master-bin.000001       #       User var        #       #       @`a``2`=42
+master-bin.000001       #       User var        #       #       @`a``3`=9223372036854775807
+master-bin.000001       #       User var        #       #       @`a``4`=18446744073709551615
+master-bin.000001       #       User var        #       #       @`b```=-1.234560123456789e125
+master-bin.000001       #       User var        #       #       @```c`=-1234501234567890123456789012345678901234567890123456789.0123456789
+master-bin.000001       #       User var        #       #       @```d```=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE latin1_swedish_ci
+master-bin.000001       #       Query   #       #       use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
+master-bin.000001       #       Query   #       #       COMMIT
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+ROLLBACK/*!*/;
+use `db1``; SELECT 'oops!'`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+SET @`a``1`:=-9223372036854775808/*!*/;
+SET @`a``2`:=42/*!*/;
+SET @`a``3`:=9223372036854775807/*!*/;
+SET @`a``4`:=18446744073709551615/*!*/;
+SET @`b```:=-1.2345601234568e+125/*!*/;
+SET @```c`:=-1234501234567890123456789012345678901234567890123456789.0123456789/*!*/;
+SET @```d```:=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE `latin1_swedish_ci`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
+a1      a2      a3      a4      b       c       d
+-9223372036854775808    42      9223372036854775807     18446744073709551615    -1.234560123456789e125  -1234501234567890123456789012345678901234567890123456789.0123456789     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+-9223372036854775807    4200    9223372036854775806     18446744073709551614    -6.172800617283945e124  -1234501234567890123456789012345678901234567890123456789.0123456789     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+DROP TABLE t1;
+*** Test correct quoting in foreign key error message ***
+use `db1``; SELECT 'oops!'`;
+CREATE TABLE `t``1` ( `a``` INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE `t``2` ( `b``` INT PRIMARY KEY, `c``` INT NOT NULL,
+FOREIGN KEY fk (`c```) REFERENCES `t``1`(`a```)) ENGINE=innodb;
+TRUNCATE `t``1`;
+ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`db1``; SELECT 'oops!'`.`t``2`, CONSTRAINT `INNODB_FOREIGN_KEY_NAME` FOREIGN KEY (`c```) REFERENCES `db1``; SELECT 'oops!'`.`t``1` (`a```))
+DROP TABLE `t``2`;
+DROP TABLE `t``1`;
+use test;
+DROP DATABASE `db1``; SELECT 'oops!'`;
+*** Test correct quoting of mysqlbinlog --rewrite-db option ***
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES(1);
+show binlog events from <binlog_start>;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000001       #       Query   #       #       BEGIN
+master-bin.000001       #       Query   #       #       use `test`; INSERT INTO t1 VALUES(1)
+master-bin.000001       #       Query   #       #       COMMIT
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+ROLLBACK/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+BEGIN
+/*!*/;
+use `ts``et`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+INSERT INTO t1 VALUES(1)
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+DROP TABLE t1;
+include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result'
--- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result	2010-12-19 17:15:12 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result	2012-07-06 09:19:16 +0000
@@ -154,7 +154,7 @@ c1	c3	c4	c5
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -176,7 +176,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -287,7 +287,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -318,7 +318,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1000000000/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

=== modified file 'mysql-test/suite/rpl/r/rpl_sp.result'
--- a/mysql-test/suite/rpl/r/rpl_sp.result	2010-12-19 17:15:12 +0000
+++ b/mysql-test/suite/rpl/r/rpl_sp.result	2012-07-06 09:19:16 +0000
@@ -670,7 +670,7 @@ drop database if exists mysqltest1
 SET TIMESTAMP=t/*!*/;
 create database mysqltest1
 /*!*/;
-use mysqltest1/*!*/;
+use `mysqltest1`/*!*/;
 SET TIMESTAMP=t/*!*/;
 create table t1 (a varchar(100))
 /*!*/;
@@ -1015,7 +1015,7 @@ drop database mysqltest1
 SET TIMESTAMP=t/*!*/;
 drop user "zedjzlcsjhd"@127.0.0.1
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=t/*!*/;
 drop function if exists f1
 /*!*/;
@@ -1112,7 +1112,7 @@ create database mysqltest
 SET TIMESTAMP=t/*!*/;
 create database mysqltest2
 /*!*/;
-use mysqltest2/*!*/;
+use `mysqltest2`/*!*/;
 SET TIMESTAMP=t/*!*/;
 create table t ( t integer )
 /*!*/;
@@ -1139,7 +1139,7 @@ end
 SET TIMESTAMP=t/*!*/;
 BEGIN
 /*!*/;
-use mysqltest/*!*/;
+use `mysqltest`/*!*/;
 SET TIMESTAMP=t/*!*/;
 SELECT `mysqltest2`.`f1`()
 /*!*/;
@@ -1152,14 +1152,14 @@ drop database mysqltest
 SET TIMESTAMP=t/*!*/;
 drop database mysqltest2
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=t/*!*/;
 CREATE DEFINER=`root`@`localhost` PROCEDURE `mysqltestbug36570_p1`()
 begin
 select 1;
 end
 /*!*/;
-use mysql/*!*/;
+use `mysql`/*!*/;
 SET TIMESTAMP=t/*!*/;
 CREATE DEFINER=`root`@`localhost` PROCEDURE `test`.` mysqltestbug36570_p2`( a int)
 `label`:

=== added file 'mysql-test/suite/rpl/t/rpl_mdev382.test'
--- a/mysql-test/suite/rpl/t/rpl_mdev382.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mdev382.test	2012-07-06 09:19:16 +0000
@@ -0,0 +1,175 @@
+--source include/have_innodb.inc
+--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
+
+# MDEV-382: multiple SQL injections in replication code.
+
+# Test previous SQL injection attack against binlog for SAVEPOINT statement.
+# The test would cause syntax error on slave due to improper quoting of
+# the savepoint name.
+connection master;
+create table t1 (a int primary key) engine=innodb;
+create table t2 (a int primary key) engine=myisam;
+
+begin;
+insert into t1 values (1);
+SET sql_mode = 'ANSI_QUOTES';
+savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
+insert into t1 values (2);
+insert into t2 values (1);
+SET sql_mode = '';
+rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
+insert into t1 values (3);
+commit;
+
+--source include/show_binlog_events.inc
+
+# This failed due to syntax error in query when the bug was not fixed.
+sync_slave_with_master;
+connection slave;
+
+# Test some more combinations of ANSI_QUOTES and sql_quote_show_create
+connection master;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+BEGIN;
+insert into t1 values(10);
+set sql_mode = 'ANSI_QUOTES';
+set sql_quote_show_create = 1;
+savepoint a;
+insert into t1 values(11);
+savepoint "a""a";
+insert into t1 values(12);
+set sql_quote_show_create = 0;
+savepoint b;
+insert into t1 values(13);
+savepoint "b""b";
+insert into t1 values(14);
+set sql_mode = '';
+set sql_quote_show_create = 1;
+savepoint c;
+insert into t1 values(15);
+savepoint `c``c`;
+insert into t1 values(16);
+set sql_quote_show_create = 0;
+savepoint d;
+insert into t1 values(17);
+savepoint `d``d`;
+insert into t1 values(18);
+COMMIT;
+set sql_quote_show_create = 1;
+
+--source include/show_binlog_events.inc
+
+--echo *** Test correct USE statement in SHOW BINLOG EVENTS ***
+connection master;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+set sql_mode = 'ANSI_QUOTES';
+CREATE DATABASE "db1`; SELECT 'oops!'";
+use "db1`; SELECT 'oops!'";
+CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
+INSERT INTO t1 VALUES (1);
+set sql_mode = '';
+INSERT INTO t1 VALUES (2);
+set sql_mode = 'ANSI_QUOTES';
+--source include/show_binlog_events.inc
+set sql_mode = '';
+set sql_quote_show_create = 0;
+--source include/show_binlog_events.inc
+set sql_quote_show_create = 1;
+--source include/show_binlog_events.inc
+DROP TABLE t1;
+
+use test;
+
+--echo ***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
+
+--let $load_file= $MYSQLTEST_VARDIR/tmp/f'le.txt
+--write_file $MYSQLTEST_VARDIR/tmp/f'le.txt
+'fo\\o','bar'
+EOF
+
+use `db1``; SELECT 'oops!'`;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+set timestamp=1000000000;
+CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
+    `c``3` VARCHAR(7));
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
+  FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
+  LINES TERMINATED BY '\\n'
+  (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
+#  FIELDS TERMINATED BY ',' ESCAPED BY '\\' LINES TERMINATED BY '\n'
+SELECT * FROM `t``1`;
+# Also test when code prefixes table name with database.
+truncate `t``1`;
+use test;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt'
+  INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
+  FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
+  LINES TERMINATED BY '\\n'
+  (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
+SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
+let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+--source include/show_binlog_events.inc
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_regex /LOCAL INFILE '.*SQL_LOAD.*' INTO/LOCAL INFILE '<name>' INTO/
+--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
+connection master;
+
+DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
+--remove_file $MYSQLTEST_VARDIR/tmp/f'le.txt
+
+connection master;
+drop table t1,t2;
+
+--echo *** Test user variables whose names require correct quoting ***
+use `db1``; SELECT 'oops!'`;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
+INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
+SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
+INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
+let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+--source include/show_binlog_events.inc
+
+--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
+
+connection master;
+DROP TABLE t1;
+
+--echo *** Test correct quoting in foreign key error message ***
+use `db1``; SELECT 'oops!'`;
+CREATE TABLE `t``1` ( `a``` INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE `t``2` ( `b``` INT PRIMARY KEY, `c``` INT NOT NULL,
+    FOREIGN KEY fk (`c```) REFERENCES `t``1`(`a```)) ENGINE=innodb;
+--replace_regex /t@[0-9]+_ibfk_[0-9]+/INNODB_FOREIGN_KEY_NAME/
+--error ER_TRUNCATE_ILLEGAL_FK
+TRUNCATE `t``1`;
+DROP TABLE `t``2`;
+DROP TABLE `t``1`;
+
+connection master;
+use test;
+DROP DATABASE `db1``; SELECT 'oops!'`;
+
+--echo *** Test correct quoting of mysqlbinlog --rewrite-db option ***
+CREATE TABLE t1 (a INT PRIMARY KEY);
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+INSERT INTO t1 VALUES(1);
+--source include/show_binlog_events.inc
+let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
+--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 --rewrite-db='test->ts`et' $MYSQLD_DATADIR/master-bin.000001
+DROP TABLE t1;
+
+--source include/rpl_end.inc

=== modified file 'mysys/mf_iocache2.c'
--- a/mysys/mf_iocache2.c	2012-08-09 15:22:00 +0000
+++ b/mysys/mf_iocache2.c	2012-07-06 09:19:16 +0000
@@ -287,6 +287,40 @@ my_off_t my_b_filelength(IO_CACHE *info)
 }
 
 
+size_t
+my_b_write_backtick_quote(IO_CACHE *info, const char *str, size_t len)
+{
+  const uchar *start;
+  const uchar *p= (const uchar *)str;
+  const uchar *end= p + len;
+  size_t count;
+  size_t total= 0;
+
+  if (my_b_write(info, (uchar *)"`", 1))
+    return (size_t)-1;
+  ++total;
+  for (;;)
+  {
+    start= p;
+    while (p < end && *p != '`')
+      ++p;
+    count= p - start;
+    if (count && my_b_write(info, start, count))
+      return (size_t)-1;
+    total+= count;
+    if (p >= end)
+      break;
+    if (my_b_write(info, (uchar *)"``", 2))
+      return (size_t)-1;
+    total+= 2;
+    ++p;
+  }
+  if (my_b_write(info, (uchar *)"`", 1))
+    return (size_t)-1;
+  ++total;
+  return total;
+}
+
 /*
   Simple printf version.  Supports '%s', '%d', '%u', "%ld" and "%lu"
   Used for logging in MySQL
@@ -311,6 +345,7 @@ size_t my_b_vprintf(IO_CACHE *info, cons
   uint minimum_width_sign;
   uint precision; /* as yet unimplemented for anything but %b */
   my_bool is_zero_padded;
+  my_bool backtick_quoting;
 
   /*
     Store the location of the beginning of a format directive, for the
@@ -345,6 +380,7 @@ size_t my_b_vprintf(IO_CACHE *info, cons
     fmt++;
 
     is_zero_padded= FALSE;
+    backtick_quoting= FALSE;
     minimum_width_sign= 1;
     minimum_width= 0;
     precision= 0;
@@ -357,6 +393,8 @@ size_t my_b_vprintf(IO_CACHE *info, cons
         minimum_width_sign= -1; fmt++; goto process_flags;
       case '0':
         is_zero_padded= TRUE; fmt++; goto process_flags;
+      case '`':
+        backtick_quoting= TRUE; fmt++; goto process_flags;
       case '#':
         /** @todo Implement "#" conversion flag. */  fmt++; goto process_flags;
       case ' ':
@@ -400,9 +438,19 @@ size_t my_b_vprintf(IO_CACHE *info, cons
       reg2 char *par = va_arg(args, char *);
       size_t length2 = strlen(par);
       /* TODO: implement precision */
-      out_length+= length2;
-      if (my_b_write(info, (uchar*) par, length2))
-        goto err;
+      if (backtick_quoting)
+      {
+        size_t total= my_b_write_backtick_quote(info, (uchar *) par, length2);
+        if (total == (size_t)-1)
+          goto err;
+        out_length+= total;
+      }
+      else
+      {
+        out_length+= length2;
+        if (my_b_write(info, (uchar*) par, length2))
+          goto err;
+      }
     }
     else if (*fmt == 'b')                       /* Sized buffer parameter, only precision makes sense */
     {

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2012-01-13 14:50:02 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2012-07-06 09:19:16 +0000
@@ -1295,7 +1295,7 @@ int ndbcluster_log_schema_op(THD *thd, N
     DBUG_RETURN(0);
   }
 
-  char tmp_buf2[FN_REFLEN];
+  String tmp_buf2;
   const char *type_str;
   switch (type)
   {
@@ -1304,17 +1304,24 @@ int ndbcluster_log_schema_op(THD *thd, N
     if (thd->lex->sql_command ==  SQLCOM_DROP_DB)
       DBUG_RETURN(0);
     /* redo the drop table query as is may contain several tables */
-    query= tmp_buf2;
-    query_length= (uint) (strxmov(tmp_buf2, "drop table `",
-                                  table_name, "`", NullS) - tmp_buf2);
+    tmp_buf2.append(STRING_WITH_LEN("drop table "));
+    append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
+    query= tmp_buf2.c_ptr_safe();
+    query_length= tmp_buf2.length();
     type_str= "drop table";
     break;
   case SOT_RENAME_TABLE:
     /* redo the rename table query as is may contain several tables */
-    query= tmp_buf2;
-    query_length= (uint) (strxmov(tmp_buf2, "rename table `",
-                                  db, ".", table_name, "` to `",
-                                  new_db, ".", new_table_name, "`", NullS) - tmp_buf2);
+    tmp_buf2.append(STRING_WITH_LEN("rename table "));
+    append_identifier(thd, &tmp_buf2, db, strlen(db));
+    tmp_buf2.append(STRING_WITH_LEN("."));
+    append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
+    tmp_buf2.append(STRING_WITH_LEN(" to "));
+    append_identifier(thd, &tmp_buf2, new_db, strlen(new_db));
+    tmp_buf2.append(STRING_WITH_LEN("."));
+    append_identifier(thd, &tmp_buf2, new_table_name, strlen(new_table_name));
+    query= tmp_buf2.c_ptr_safe();
+    query_length= tmp_buf2.length();
     type_str= "rename table";
     break;
   case SOT_CREATE_TABLE:

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2012-08-09 15:22:00 +0000
+++ b/sql/log.cc	2012-07-06 09:19:16 +0000
@@ -52,6 +52,7 @@
 #include "sql_plugin.h"
 #include "rpl_handler.h"
 #include "debug_sync.h"
+#include "sql_show.h"
 
 /* max size of the log message */
 #define MAX_LOG_BUFFER_SIZE 1024
@@ -2072,11 +2073,11 @@ static int binlog_savepoint_set(handlert
   /* Write it to the binary log */
 
   String log_query;
-  if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) ||
-      log_query.append("`") ||
-      log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
-      log_query.append("`"))
+  if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")))
     DBUG_RETURN(1);
+  /* ToDo: need return value here to check ?!? */
+  append_identifier(thd, &log_query,
+                    thd->lex->ident.str, thd->lex->ident.length);
   int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
   Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
                         TRUE, FALSE, TRUE, errcode);
@@ -2096,11 +2097,10 @@ static int binlog_savepoint_rollback(han
                (thd->variables.option_bits & OPTION_KEEP_LOG)))
   {
     String log_query;
-    if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) ||
-        log_query.append("`") ||
-        log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
-        log_query.append("`"))
+    if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")))
       DBUG_RETURN(1);
+    append_identifier(thd, &log_query,
+                      thd->lex->ident.str, thd->lex->ident.length);
     int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
     Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
                           TRUE, FALSE, TRUE, errcode);

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2012-08-09 15:22:00 +0000
+++ b/sql/log_event.cc	2012-07-06 09:19:16 +0000
@@ -46,6 +46,7 @@
 #include "rpl_record.h"
 #include "transaction.h"
 #include <my_dir.h>
+#include "sql_show.h"
 
 #endif /* MYSQL_CLIENT */
 
@@ -471,29 +472,28 @@ inline bool unexpected_error_code(int un
   pretty_print_str()
 */
 
-static char *pretty_print_str(char *packet, const char *str, int len)
+static void
+pretty_print_str(String *packet, const char *str, int len)
 {
   const char *end= str + len;
-  char *pos= packet;
-  *pos++= '\'';
+  packet->append(STRING_WITH_LEN("'"));
   while (str < end)
   {
     char c;
     switch ((c=*str++)) {
-    case '\n': *pos++= '\\'; *pos++= 'n'; break;
-    case '\r': *pos++= '\\'; *pos++= 'r'; break;
-    case '\\': *pos++= '\\'; *pos++= '\\'; break;
-    case '\b': *pos++= '\\'; *pos++= 'b'; break;
-    case '\t': *pos++= '\\'; *pos++= 't'; break;
-    case '\'': *pos++= '\\'; *pos++= '\''; break;
-    case 0   : *pos++= '\\'; *pos++= '0'; break;
+    case '\n': packet->append(STRING_WITH_LEN("\\n")); break;
+    case '\r': packet->append(STRING_WITH_LEN("\\r")); break;
+    case '\\': packet->append(STRING_WITH_LEN("\\\\")); break;
+    case '\b': packet->append(STRING_WITH_LEN("\\b")); break;
+    case '\t': packet->append(STRING_WITH_LEN("\\t")); break;
+    case '\'': packet->append(STRING_WITH_LEN("\\'")); break;
+    case 0   : packet->append(STRING_WITH_LEN("\\0")); break;
     default:
-      *pos++= c;
+      packet->append(&c, 1);
       break;
     }
   }
-  *pos++= '\'';
-  return pos;
+  packet->append(STRING_WITH_LEN("'"));
 }
 #endif /* !MYSQL_CLIENT */
 
@@ -926,7 +926,7 @@ Log_event::do_shall_skip(Relay_log_info
   Log_event::pack_info()
 */
 
-void Log_event::pack_info(Protocol *protocol)
+void Log_event::pack_info(THD *thd, Protocol *protocol)
 {
   protocol->store("", &my_charset_bin);
 }
@@ -935,7 +935,8 @@ void Log_event::pack_info(Protocol *prot
 /**
   Only called by SHOW BINLOG EVENTS
 */
-int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
+int Log_event::net_send(THD *thd, Protocol *protocol, const char* log_name,
+                        my_off_t pos)
 {
   const char *p= strrchr(log_name, FN_LIBCHAR);
   const char *event_type;
@@ -949,7 +950,7 @@ int Log_event::net_send(Protocol *protoc
   protocol->store(event_type, strlen(event_type), &my_charset_bin);
   protocol->store((uint32) server_id);
   protocol->store((ulonglong) log_pos);
-  pack_info(protocol);
+  pack_info(thd, protocol);
   return protocol->write();
 }
 #endif /* HAVE_REPLICATION */
@@ -2448,27 +2449,20 @@ Log_event::continue_group(Relay_log_info
     show the catalog ??
 */
 
-void Query_log_event::pack_info(Protocol *protocol)
+void Query_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   // TODO: show the catalog ??
-  char *buf, *pos;
-  if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
-    return;
-  pos= buf;
+  String buf(9 + db_len + q_len);
   if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
       && db && db_len)
   {
-    pos= strmov(buf, "use `");
-    memcpy(pos, db, db_len);
-    pos= strmov(pos+db_len, "`; ");
+    buf.append(STRING_WITH_LEN("use "));
+    append_identifier(thd, &buf, db, db_len);
+    buf.append("; ");
   }
   if (query && q_len)
-  {
-    memcpy(pos, query, q_len);
-    pos+= q_len;
-  }
-  protocol->store(buf, pos-buf, &my_charset_bin);
-  my_free(buf);
+    buf.append(query, q_len);
+  protocol->store(&buf);
 }
 #endif
 
@@ -3334,11 +3328,17 @@ void Query_log_event::print_query_header
   }
   else if (db)
   {
+    /* Room for expand ` to `` + initial/final ` + \0 */
+    char buf[FN_REFLEN*2+3];
+
     different_db= memcmp(print_event_info->db, db, db_len + 1);
     if (different_db)
       memcpy(print_event_info->db, db, db_len + 1);
     if (db[0] && different_db) 
-      my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
+    {
+      my_snprintf(buf, sizeof(buf), "%`s", db);
+      my_b_printf(file, "use %s%s\n", buf, print_event_info->delimiter);
+    }
   }
 
   end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
@@ -4002,7 +4002,7 @@ Start_log_event_v3::Start_log_event_v3()
 */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Start_log_event_v3::pack_info(Protocol *protocol)
+void Start_log_event_v3::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
   pos= strmov(buf, "Server ver: ");
@@ -4778,131 +4778,112 @@ uint8 get_checksum_alg(const char* buf,
 */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-uint Load_log_event::get_query_buffer_length()
-{
-  return
-    5 + db_len + 3 +                        // "use DB; "
-    18 + fname_len + 2 +                    // "LOAD DATA INFILE 'file''"
-    11 +                                    // "CONCURRENT "
-    7 +                                     // LOCAL
-    9 +                                     // " REPLACE or IGNORE "
-    13 + table_name_len*2 +                 // "INTO TABLE `table`"
-    21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
-    23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
-    12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
-    21 + sql_ex.line_term_len*4 + 2 +       // " LINES TERMINATED BY 'str'"
-    19 + sql_ex.line_start_len*4 + 2 +      // " LINES STARTING BY 'str'"
-    15 + 22 +                               // " IGNORE xxx  LINES"
-    3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
-}
-
-
-void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
-                                 char **end, char **fn_start, char **fn_end)
+void Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
+                                 String *buf, my_off_t *fn_start,
+                                 my_off_t *fn_end, const char *qualify_db)
 {
-  char *pos= buf;
-
   if (need_db && db && db_len)
   {
-    pos= strmov(pos, "use `");
-    memcpy(pos, db, db_len);
-    pos= strmov(pos+db_len, "`; ");
+    buf->append(STRING_WITH_LEN("use "));
+    append_identifier(thd, buf, db, db_len);
+    buf->append(STRING_WITH_LEN("; "));
   }
 
-  pos= strmov(pos, "LOAD DATA ");
+  buf->append(STRING_WITH_LEN("LOAD DATA "));
 
   if (is_concurrent)
-    pos= strmov(pos, "CONCURRENT ");
+    buf->append(STRING_WITH_LEN("CONCURRENT "));
 
   if (fn_start)
-    *fn_start= pos;
+    *fn_start= buf->length();
 
   if (check_fname_outside_temp_buf())
-    pos= strmov(pos, "LOCAL ");
-  pos= strmov(pos, "INFILE '");
-  memcpy(pos, fname, fname_len);
-  pos= strmov(pos+fname_len, "' ");
+    buf->append(STRING_WITH_LEN("LOCAL "));
+  buf->append(STRING_WITH_LEN("INFILE '"));
+  buf->append_for_single_quote(fname, fname_len);
+  buf->append(STRING_WITH_LEN("' "));
 
   if (sql_ex.opt_flags & REPLACE_FLAG)
-    pos= strmov(pos, "REPLACE ");
+    buf->append(STRING_WITH_LEN("REPLACE "));
   else if (sql_ex.opt_flags & IGNORE_FLAG)
-    pos= strmov(pos, "IGNORE ");
+    buf->append(STRING_WITH_LEN("IGNORE "));
 
-  pos= strmov(pos ,"INTO");
+  buf->append(STRING_WITH_LEN("INTO"));
 
   if (fn_end)
-    *fn_end= pos;
+    *fn_end= buf->length();
 
-  pos= strmov(pos ," TABLE `");
-  memcpy(pos, table_name, table_name_len);
-  pos+= table_name_len;
+  buf->append(STRING_WITH_LEN(" TABLE "));
+  if (qualify_db)
+  {
+    append_identifier(thd, buf, qualify_db, strlen(qualify_db));
+    buf->append(STRING_WITH_LEN("."));
+  }
+  append_identifier(thd, buf, table_name, table_name_len);
 
   if (cs != NULL)
   {
-    pos= strmov(pos ,"` CHARACTER SET ");
-    pos= strmov(pos ,  cs);
+    buf->append(STRING_WITH_LEN(" CHARACTER SET "));
+    buf->append(cs, strlen(cs));
   }
-  else
-    pos= strmov(pos, "`");
 
   /* We have to create all optional fields as the default is not empty */
-  pos= strmov(pos, " FIELDS TERMINATED BY ");
-  pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
+  buf->append(STRING_WITH_LEN(" FIELDS TERMINATED BY "));
+  pretty_print_str(buf, sql_ex.field_term, sql_ex.field_term_len);
   if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
-    pos= strmov(pos, " OPTIONALLY ");
-  pos= strmov(pos, " ENCLOSED BY ");
-  pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
+    buf->append(STRING_WITH_LEN(" OPTIONALLY "));
+  buf->append(STRING_WITH_LEN(" ENCLOSED BY "));
+  pretty_print_str(buf, sql_ex.enclosed, sql_ex.enclosed_len);
 
-  pos= strmov(pos, " ESCAPED BY ");
-  pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
+  buf->append(STRING_WITH_LEN(" ESCAPED BY "));
+  pretty_print_str(buf, sql_ex.escaped, sql_ex.escaped_len);
 
-  pos= strmov(pos, " LINES TERMINATED BY ");
-  pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
+  buf->append(STRING_WITH_LEN(" LINES TERMINATED BY "));
+  pretty_print_str(buf, sql_ex.line_term, sql_ex.line_term_len);
   if (sql_ex.line_start_len)
   {
-    pos= strmov(pos, " STARTING BY ");
-    pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
+    buf->append(STRING_WITH_LEN(" STARTING BY "));
+    pretty_print_str(buf, sql_ex.line_start, sql_ex.line_start_len);
   }
 
   if ((long) skip_lines > 0)
   {
-    pos= strmov(pos, " IGNORE ");
-    pos= longlong10_to_str((longlong) skip_lines, pos, 10);
-    pos= strmov(pos," LINES ");    
+    buf->append(STRING_WITH_LEN(" IGNORE "));
+    buf->append_ulonglong(skip_lines);
+    buf->append(STRING_WITH_LEN(" LINES "));
   }
 
   if (num_fields)
   {
     uint i;
     const char *field= fields;
-    pos= strmov(pos, " (");
+    buf->append(STRING_WITH_LEN(" ("));
     for (i = 0; i < num_fields; i++)
     {
       if (i)
       {
-        *pos++= ' ';
-        *pos++= ',';
+        /*
+          Yes, the space and comma is reversed here. But this is mostly dead
+          code, at most used when reading really old binlogs from old servers,
+          so better just leave it as is...
+        */
+        buf->append(STRING_WITH_LEN(" ,"));
       }
-      memcpy(pos, field, field_lens[i]);
-      pos+=   field_lens[i];
+      append_identifier(thd, buf, field, field_lens[i]);
       field+= field_lens[i]  + 1;
     }
-    *pos++= ')';
+    buf->append(STRING_WITH_LEN(")"));
   }
-
-  *end= pos;
 }
 
 
-void Load_log_event::pack_info(Protocol *protocol)
+void Load_log_event::pack_info(THD *thd, Protocol *protocol)
 {
-  char *buf, *end;
+  char query_buffer[1024];
+  String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
 
-  if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
-    return;
-  print_query(TRUE, NULL, buf, &end, 0, 0);
-  protocol->store(buf, end-buf, &my_charset_bin);
-  my_free(buf);
+  print_query(thd, TRUE, NULL, &query_str, 0, 0, NULL);
+  protocol->store(query_str.ptr(), query_str.length(), &my_charset_bin);
 }
 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
@@ -5358,16 +5339,19 @@ int Load_log_event::do_apply_event(NET*
     else
     {
       char llbuff[22];
-      char *end;
       enum enum_duplicates handle_dup;
       bool ignore= 0;
+      char query_buffer[1024];
+      String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
       char *load_data_query;
 
       /*
         Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
         and written to slave's binlog if binlogging is on.
       */
-      if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
+      print_query(thd, FALSE, NULL, &query_str, NULL, NULL, NULL);
+      if (!(load_data_query= (char *)thd->strmake(query_str.ptr(),
+                                                  query_str.length())))
       {
         /*
           This will set thd->fatal_error in case of OOM. So we surely will notice
@@ -5376,9 +5360,7 @@ int Load_log_event::do_apply_event(NET*
         goto error;
       }
 
-      print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
-      *end= 0;
-      thd->set_query(load_data_query, (uint) (end - load_data_query));
+      thd->set_query(load_data_query, (uint) (query_str.length()));
 
       if (sql_ex.opt_flags & REPLACE_FLAG)
         handle_dup= DUP_REPLACE;
@@ -5556,7 +5538,7 @@ Error '%s' running LOAD DATA INFILE on t
 */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Rotate_log_event::pack_info(Protocol *protocol)
+void Rotate_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf1[256], buf[22];
   String tmp(buf1, sizeof(buf1), log_cs);
@@ -5774,7 +5756,7 @@ Rotate_log_event::do_shall_skip(Relay_lo
 */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Intvar_log_event::pack_info(Protocol *protocol)
+void Intvar_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[256], *pos;
   pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
@@ -5928,7 +5910,7 @@ Intvar_log_event::do_shall_skip(Relay_lo
 **************************************************************************/
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Rand_log_event::pack_info(Protocol *protocol)
+void Rand_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf1[256], *pos;
   pos= strmov(buf1,"rand_seed1=");
@@ -6053,7 +6035,7 @@ bool slave_execute_deferred_events(THD *
 **************************************************************************/
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Xid_log_event::pack_info(Protocol *protocol)
+void Xid_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[128], *pos;
   pos= strmov(buf, "COMMIT /* xid=");
@@ -6150,84 +6132,99 @@ Xid_log_event::do_shall_skip(Relay_log_i
 **************************************************************************/
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void User_var_log_event::pack_info(Protocol* protocol)
+static void
+user_var_append_name_part(THD *thd, String *buf,
+                          const char *name, size_t name_len)
+{
+  buf->append("@");
+  append_identifier(thd, buf, name, name_len);
+  buf->append("=");
+}
+
+void User_var_log_event::pack_info(THD *thd, Protocol* protocol)
 {
-  char *buf= 0;
   uint val_offset= 4 + name_len;
-  uint event_len= val_offset;
 
   if (is_null)
   {
-    if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
-      return;
-    strmov(buf + val_offset, "NULL");
-    event_len= val_offset + 4;
+    String buf(val_offset + 5);
+    user_var_append_name_part(thd, &buf, name, name_len);
+    buf.append("NULL");
+    protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
   }
   else
   {
     switch (type) {
     case REAL_RESULT:
+    {
       double real_val;
+      char buf2[MY_GCVT_MAX_FIELD_WIDTH+1];
+      String buf(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1);
+      user_var_append_name_part(thd, &buf, name, name_len);
       float8get(real_val, val);
-      if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
-                                   MYF(MY_WME))))
-        return;
-      event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
-                          buf + val_offset, NULL);
+      buf.append(buf2, my_gcvt(real_val, MY_GCVT_ARG_DOUBLE,
+                               MY_GCVT_MAX_FIELD_WIDTH, buf2, NULL));
+      protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
       break;
+    }
     case INT_RESULT:
-      if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
-        return;
-      event_len= longlong10_to_str(uint8korr(val), buf + val_offset, 
-                                   ((flags & User_var_log_event::UNSIGNED_F) ? 
-                                    10 : -10))-buf;
+    {
+      char buf2[22];
+      String buf(val_offset + 22);
+      user_var_append_name_part(thd, &buf, name, name_len);
+      buf.append(buf2,
+                 longlong10_to_str(uint8korr(val), buf2,
+                   ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10))-buf2);
+      protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
       break;
+    }
     case DECIMAL_RESULT:
     {
-      if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
-                                   MYF(MY_WME))))
-        return;
-      String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
+      String buf(val_offset + DECIMAL_MAX_STR_LENGTH);
+      char buf2[DECIMAL_MAX_STR_LENGTH+1];
+      String str(buf2, sizeof(buf2), &my_charset_bin);
       my_decimal dec;
+      user_var_append_name_part(thd, &buf, name, name_len);
       binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
                         val[1]);
       my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
-      event_len= str.length() + val_offset;
+      buf.append(buf2);
+      protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
       break;
-    } 
+    }
     case STRING_RESULT:
+    {
       /* 15 is for 'COLLATE' and other chars */
-      buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
-                             MYF(MY_WME));
+      String buf(val_offset+val_len*2+1+2*MY_CS_NAME_SIZE+15);
       CHARSET_INFO *cs;
-      if (!buf)
-        return;
       if (!(cs= get_charset(charset_number, MYF(0))))
-      {
-        strmov(buf+val_offset, "???");
-        event_len+= 3;
-      }
+        buf.append("???");
       else
       {
-        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;
+        size_t old_len;
+        char *beg, *end;
+        user_var_append_name_part(thd, &buf, name, name_len);
+        buf.append("_");
+        buf.append(cs->csname);
+        buf.append(" ");
+        old_len= buf.length();
+        buf.reserve(old_len + val_len*2 + 2 + sizeof(" COLLATE ") +
+                    MY_CS_NAME_SIZE);
+        beg= const_cast<char *>(buf.ptr()) + old_len;
+        end= str_to_hex(beg, val, val_len);
+        buf.length(old_len + (end - beg));
+        buf.append(" COLLATE ");
+        buf.append(cs->name);
       }
+      protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
       break;
+    }
     case ROW_RESULT:
     default:
       DBUG_ASSERT(0);
       return;
     }
   }
-  buf[0]= '@';
-  buf[1]= '`';
-  memcpy(buf+2, name, name_len);
-  buf[2+name_len]= '`';
-  buf[3+name_len]= '=';
-  protocol->store(buf, event_len, &my_charset_bin);
-  my_free(buf);
 }
 #endif /* !MYSQL_CLIENT */
 
@@ -6385,9 +6382,8 @@ void User_var_log_event::print(FILE* fil
     my_b_printf(&cache, "\tUser_var\n");
   }
 
-  my_b_printf(&cache, "SET @`");
-  my_b_write(&cache, (uchar*) name, (uint) (name_len));
-  my_b_printf(&cache, "`");
+  my_b_printf(&cache, "SET @");
+  my_b_write_backtick_quote(&cache, name, name_len);
 
   if (is_null)
   {
@@ -6609,7 +6605,7 @@ void Unknown_log_event::print(FILE* file
 #endif  
 
 #ifndef MYSQL_CLIENT
-void Slave_log_event::pack_info(Protocol *protocol)
+void Slave_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[256+HOSTNAME_LENGTH], *pos;
   pos= strmov(buf, "host=");
@@ -6991,7 +6987,7 @@ void Create_file_log_event::print(FILE*
 */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Create_file_log_event::pack_info(Protocol *protocol)
+void Create_file_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos;
   pos= strmov(buf, "db=");
@@ -7177,7 +7173,7 @@ void Append_block_log_event::print(FILE*
 */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Append_block_log_event::pack_info(Protocol *protocol)
+void Append_block_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[256];
   uint length;
@@ -7334,7 +7330,7 @@ void Delete_file_log_event::print(FILE*
 */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Delete_file_log_event::pack_info(Protocol *protocol)
+void Delete_file_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[64];
   uint length;
@@ -7433,7 +7429,7 @@ void Execute_load_log_event::print(FILE*
 */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Execute_load_log_event::pack_info(Protocol *protocol)
+void Execute_load_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[64];
   uint length;
@@ -7695,27 +7691,20 @@ void Execute_load_query_log_event::print
 
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Execute_load_query_log_event::pack_info(Protocol *protocol)
+void Execute_load_query_log_event::pack_info(THD *thd, Protocol *protocol)
 {
-  char *buf, *pos;
-  if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
-    return;
-  pos= buf;
+  String buf(9 + db_len + q_len + 10 + 21);
   if (db && db_len)
   {
-    pos= strmov(buf, "use `");
-    memcpy(pos, db, db_len);
-    pos= strmov(pos+db_len, "`; ");
+    buf.append("use ");
+    append_identifier(thd, &buf, db, db_len);
+    buf.append("; ");
   }
   if (query && q_len)
-  {
-    memcpy(pos, query, q_len);
-    pos+= q_len;
-  }
-  pos= strmov(pos, " ;file_id=");
-  pos= int10_to_str((long) file_id, pos, 10);
-  protocol->store(buf, pos-buf, &my_charset_bin);
-  my_free(buf);
+    buf.append(query, q_len);
+  buf.append(" ;file_id=");
+  buf.append_ulonglong(file_id);
+  protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
 }
 
 
@@ -8678,7 +8667,7 @@ bool Rows_log_event::write_data_body(IO_
 #endif
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Rows_log_event::pack_info(Protocol *protocol)
+void Rows_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[256];
   char const *const flagstr=
@@ -8782,7 +8771,7 @@ bool Annotate_rows_log_event::write_data
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-void Annotate_rows_log_event::pack_info(Protocol* protocol)
+void Annotate_rows_log_event::pack_info(THD *thd, Protocol* protocol)
 {
   if (m_query_txt && m_query_len)
     protocol->store(m_query_txt, m_query_len, &my_charset_bin);
@@ -9526,7 +9515,7 @@ bool Table_map_log_event::write_data_bod
  */
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Table_map_log_event::pack_info(Protocol *protocol)
+void Table_map_log_event::pack_info(THD *thd, Protocol *protocol)
 {
     char buf[256];
     size_t bytes= my_snprintf(buf, sizeof(buf),
@@ -9547,7 +9536,7 @@ void Table_map_log_event::print(FILE *,
   {
     print_header(&print_event_info->head_cache, print_event_info, TRUE);
     my_b_printf(&print_event_info->head_cache,
-                "\tTable_map: `%s`.`%s` mapped to number %lu\n",
+                "\tTable_map: %`s.%`s mapped to number %lu\n",
                 m_dbnam, m_tblnam, m_table_id);
     print_base64(&print_event_info->body_cache, print_event_info, TRUE);
   }
@@ -10880,7 +10869,7 @@ Incident_log_event::description() const
 
 
 #ifndef MYSQL_CLIENT
-void Incident_log_event::pack_info(Protocol *protocol)
+void Incident_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[256];
   size_t bytes;

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2012-08-09 15:22:00 +0000
+++ b/sql/log_event.h	2012-07-06 09:19:16 +0000
@@ -1065,14 +1065,15 @@ class Log_event
   */
   static void init_show_field_list(List<Item>* field_list);
 #ifdef HAVE_REPLICATION
-  int net_send(Protocol *protocol, const char* log_name, my_off_t pos);
+  int net_send(THD *thd, Protocol *protocol, const char* log_name,
+               my_off_t pos);
 
   /*
     pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends
     a string to display to the user, so it resembles print().
   */
 
-  virtual void pack_info(Protocol *protocol);
+  virtual void pack_info(THD *thd, Protocol *protocol);
 
 #endif /* HAVE_REPLICATION */
   virtual const char* get_db()
@@ -1809,7 +1810,7 @@ class Query_log_event: public Log_event
                   bool using_trans, bool direct, bool suppress_use, int error);
   const char* get_db() { return db; }
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
@@ -1939,7 +1940,7 @@ class Slave_log_event: public Log_event
 
 #ifdef MYSQL_SERVER
   Slave_log_event(THD* thd_arg, Relay_log_info* rli);
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
 #endif
@@ -2172,9 +2173,9 @@ class Load_log_event: public Log_event
                      const Format_description_log_event* description_event);
 
 public:
-  uint get_query_buffer_length();
-  void print_query(bool need_db, const char *cs, char *buf, char **end,
-                   char **fn_start, char **fn_end);
+  void print_query(THD *thd, bool need_db, const char *cs, String *buf,
+                   my_off_t *fn_start, my_off_t *fn_end,
+                   const char *qualify_db);
   ulong thread_id;
   ulong slave_proxy_id;
   uint32 table_name_len;
@@ -2235,7 +2236,7 @@ class Load_log_event: public Log_event
                   Name_resolution_context *context);
   const char* get_db() { return db; }
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -2332,7 +2333,7 @@ class Start_log_event_v3: public Log_eve
 #ifdef MYSQL_SERVER
   Start_log_event_v3();
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   Start_log_event_v3() {}
@@ -2496,7 +2497,7 @@ Intvar_log_event(THD* thd_arg,uchar type
       cache_type= Log_event::EVENT_NO_CACHE;
   }
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -2576,7 +2577,7 @@ class Rand_log_event: public Log_event
       cache_type= Log_event::EVENT_NO_CACHE;
   }
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -2625,7 +2626,7 @@ class Xid_log_event: public Log_event
        cache_type= Log_event::EVENT_NO_CACHE;
    }
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -2687,7 +2688,7 @@ class User_var_log_event: public Log_eve
       if (direct)
         cache_type= Log_event::EVENT_NO_CACHE;
     }
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
 #endif
@@ -2825,7 +2826,7 @@ class Rotate_log_event: public Log_event
                    uint ident_len_arg,
                    ulonglong pos_arg, uint flags);
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -2886,7 +2887,7 @@ class Create_file_log_event: public Load
                         uchar* block_arg, uint block_len_arg,
                         bool using_trans);
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -2958,7 +2959,7 @@ class Append_block_log_event: public Log
   Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg,
                          uint block_len_arg, bool using_trans);
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
   virtual int get_create_or_append() const;
 #endif /* HAVE_REPLICATION */
 #else
@@ -2999,7 +3000,7 @@ class Delete_file_log_event: public Log_
 #ifdef MYSQL_SERVER
   Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -3040,7 +3041,7 @@ class Execute_load_log_event: public Log
 #ifdef MYSQL_SERVER
   Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -3136,7 +3137,7 @@ class Execute_load_query_log_event: publ
                                bool using_trans, bool direct,
                                bool suppress_use, int errcode);
 #ifdef HAVE_REPLICATION
-  void pack_info(Protocol* protocol);
+  void pack_info(THD *thd, Protocol* protocol);
 #endif /* HAVE_REPLICATION */
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -3222,7 +3223,7 @@ class Annotate_rows_log_event: public Lo
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  virtual void pack_info(Protocol*);
+  virtual void pack_info(THD *thd, Protocol*);
 #endif
 
 #ifdef MYSQL_CLIENT
@@ -3636,7 +3637,7 @@ class Table_map_log_event : public Log_e
 #endif
 
 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
-  virtual void pack_info(Protocol *protocol);
+  virtual void pack_info(THD *thd, Protocol *protocol);
 #endif
 
 #ifdef MYSQL_CLIENT
@@ -3748,7 +3749,7 @@ class Rows_log_event : public Log_event
   flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
 
 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
-  virtual void pack_info(Protocol *protocol);
+  virtual void pack_info(THD *thd, Protocol *protocol);
 #endif
 
 #ifdef MYSQL_CLIENT
@@ -4195,7 +4196,7 @@ class Incident_log_event : public Log_ev
 #endif
 
 #ifdef MYSQL_SERVER
-  void pack_info(Protocol*);
+  void pack_info(THD *thd, Protocol*);
 #endif
 
   Incident_log_event(const char *buf, uint event_len,

=== modified file 'sql/log_event_old.cc'
--- a/sql/log_event_old.cc	2012-06-14 18:05:31 +0000
+++ b/sql/log_event_old.cc	2012-07-06 09:19:16 +0000
@@ -1935,7 +1935,7 @@ bool Old_rows_log_event::write_data_body
 
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-void Old_rows_log_event::pack_info(Protocol *protocol)
+void Old_rows_log_event::pack_info(THD *thd, Protocol *protocol)
 {
   char buf[256];
   char const *const flagstr=

=== modified file 'sql/log_event_old.h'
--- a/sql/log_event_old.h	2012-03-13 14:38:43 +0000
+++ b/sql/log_event_old.h	2012-07-06 09:19:16 +0000
@@ -108,7 +108,7 @@ class Old_rows_log_event : public Log_ev
   flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  virtual void pack_info(Protocol *protocol);
+  virtual void pack_info(THD *thd, Protocol *protocol);
 #endif
 
 #ifdef MYSQL_CLIENT

=== modified file 'sql/repl_failsafe.cc'
--- a/sql/repl_failsafe.cc	2012-01-13 14:50:02 +0000
+++ b/sql/repl_failsafe.cc	2012-07-06 09:19:16 +0000
@@ -35,7 +35,6 @@
 #include "rpl_mi.h"
 #include "rpl_filter.h"
 #include "log_event.h"
-#include "sql_db.h"                             // mysql_create_db
 #include <mysql.h>
 
 #define SLAVE_LIST_CHUNK 128

=== modified file 'sql/rpl_record.cc'
--- a/sql/rpl_record.cc	2012-03-17 08:26:58 +0000
+++ b/sql/rpl_record.cc	2012-07-06 09:19:16 +0000
@@ -314,7 +314,7 @@ unpack_row(Relay_log_info const *rli,
         if (!pack_ptr)
         {
           rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT,
-                      "Could not read field `%s` of table `%s`.`%s`",
+                      "Could not read field %`s of table %`s.%`s",
                       f->field_name, table->s->db.str,
                       table->s->table_name.str);
           DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2012-08-09 15:22:00 +0000
+++ b/sql/sql_base.cc	2012-07-06 09:19:16 +0000
@@ -3887,22 +3887,20 @@ static bool open_table_entry_fini(THD *t
     entry->file->implicit_emptied= 0;
     if (mysql_bin_log.is_open())
     {
-      char *query, *end;
-      uint query_buf_size= 20 + share->db.length + share->table_name.length +1;
-      if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
+      String query(20 + share->db.length + share->table_name.length +1);
+      if (query.ptr())
       {
         /* this DELETE FROM is needed even with row-based binlogging */
-        end = strxmov(strmov(query, "DELETE FROM `"),
-                      share->db.str,"`.`",share->table_name.str,"`", NullS);
+        query.append("DELETE FROM ");
+        append_identifier(thd, &query, share->db.str, share->db.length);
+        query.append(".");
+        append_identifier(thd, &query, share->table_name.str,
+                          share->table_name.length);
         int errcode= query_error_code(thd, TRUE);
         if (thd->binlog_query(THD::STMT_QUERY_TYPE,
-                              query, (ulong)(end-query),
+                              query.ptr(), query.length(),
                               FALSE, FALSE, FALSE, errcode))
-        {
-          my_free(query);
           return TRUE;
-        }
-        my_free(query);
       }
       else
       {
@@ -3912,7 +3910,7 @@ static bool open_table_entry_fini(THD *t
           because of MYF(MY_WME) in my_malloc() above).
         */
         sql_print_error("When opening HEAP table, could not allocate memory "
-                        "to write 'DELETE FROM `%s`.`%s`' to the binary log",
+                        "to write 'DELETE FROM %`s.%`s' to the binary log",
                         share->db.str, share->table_name.str);
         delete entry->triggers;
         return TRUE;

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2012-01-13 14:50:02 +0000
+++ b/sql/sql_db.cc	2012-07-06 09:19:16 +0000
@@ -544,7 +544,6 @@ int mysql_create_db(THD *thd, char *db,
                      bool silent)
 {
   char   path[FN_REFLEN+16];
-  char   tmp_query[FN_REFLEN+16];
   long result= 1;
   int error= 0;
   MY_STAT stat_info;
@@ -622,17 +621,9 @@ int mysql_create_db(THD *thd, char *db,
     char *query;
     uint query_length;
 
-    if (!thd->query())                          // Only in replication
-    {
-      query=         tmp_query;
-      query_length= (uint) (strxmov(tmp_query,"create database `",
-                                    db, "`", NullS) - tmp_query);
-    }
-    else
-    {
-      query=        thd->query();
-      query_length= thd->query_length();
-    }
+    query=        thd->query();
+    query_length= thd->query_length();
+    DBUG_ASSERT(query);
 
     ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
                         query, query_length,
@@ -885,18 +876,11 @@ bool mysql_rm_db(THD *thd,char *db,bool
   {
     const char *query;
     ulong query_length;
-    if (!thd->query())
-    {
-      /* The client used the old obsolete mysql_drop_db() call */
-      query= path;
-      query_length= (uint) (strxmov(path, "drop database `", db, "`",
-                                     NullS) - path);
-    }
-    else
-    {
-      query= thd->query();
-      query_length= thd->query_length();
-    }
+
+    query= thd->query();
+    query_length= thd->query_length();
+    DBUG_ASSERT(query);
+
     if (mysql_bin_log.is_open())
     {
       int errcode= query_error_code(thd, TRUE);
@@ -940,6 +924,7 @@ bool mysql_rm_db(THD *thd,char *db,bool
     {
       uint tbl_name_len;
       bool exists;
+      char quoted_name[FN_REFLEN+3];
 
       // Only write drop table to the binlog for tables that no longer exist.
       if (check_if_table_exists(thd, tbl, &exists))
@@ -950,8 +935,8 @@ bool mysql_rm_db(THD *thd,char *db,bool
       if (exists)
         continue;
 
-      /* 3 for the quotes and the comma*/
-      tbl_name_len= strlen(tbl->table_name) + 3;
+      my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name);
+      tbl_name_len= strlen(quoted_name) + 1; /* +1 for the comma */
       if (query_pos + tbl_name_len + 1 >= query_end)
       {
         /*
@@ -966,9 +951,7 @@ bool mysql_rm_db(THD *thd,char *db,bool
         query_pos= query_data_start;
       }
 
-      *query_pos++ = '`';
-      query_pos= strmov(query_pos,tbl->table_name);
-      *query_pos++ = '`';
+      query_pos= strmov(query_pos, quoted_name);
       *query_pos++ = ',';
     }
 

=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc	2012-04-07 13:58:46 +0000
+++ b/sql/sql_load.cc	2012-07-06 09:19:16 +0000
@@ -39,6 +39,7 @@
 #include "sp_head.h"
 #include "sql_trigger.h"
 #include "sql_derived.h"
+#include "sql_show.h"
 
 class XML_TAG {
 public:
@@ -675,24 +676,31 @@ static bool write_execute_load_query_log
                                                bool transactional_table,
                                                int errcode)
 {
-  char                *load_data_query,
-                      *end,
-                      *fname_start,
-                      *fname_end,
-                      *p= NULL;
-  size_t               pl= 0;
+  char                *load_data_query;
+  my_off_t            fname_start,
+                      fname_end;
   List<Item>           fv;
   Item                *item, *val;
   int                  n;
-  const char          *tbl= table_name_arg;
   const char          *tdb= (thd->db != NULL ? thd->db : db_arg);
+  const char          *qualify_db= NULL;
   char                name_buffer[SAFE_NAME_LEN*2];
   char                command_buffer[1024];
   String              string_buf(name_buffer, sizeof(name_buffer),
                                  system_charset_info);
-  String              pfields(command_buffer, sizeof(command_buffer),
+  String              query_str(command_buffer, sizeof(command_buffer),
                               system_charset_info);
 
+  Load_log_event       lle(thd, ex, tdb, table_name_arg, fv, is_concurrent,
+                           duplicates, ignore, transactional_table);
+
+  /*
+    force in a LOCAL if there was one in the original.
+  */
+  if (thd->lex->local_file)
+    lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
+
+  query_str.length(0);
   if (!thd->db || strcmp(db_arg, thd->db)) 
   {
     /*
@@ -700,49 +708,31 @@ static bool write_execute_load_query_log
       prefix table name with database name so that it 
       becomes a FQ name.
      */
-    string_buf.length(0);
-    string_buf.append(db_arg);
-    string_buf.append("`");
-    string_buf.append(".");
-    string_buf.append("`");
-    string_buf.append(table_name_arg);
-    tbl= string_buf.c_ptr_safe();
+    qualify_db= db_arg;
   }
-
-  Load_log_event       lle(thd, ex, tdb, tbl, fv, is_concurrent,
-                           duplicates, ignore, transactional_table);
-
-  /*
-    force in a LOCAL if there was one in the original.
-  */
-  if (thd->lex->local_file)
-    lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
+  lle.print_query(thd, FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
+                  &query_str, &fname_start, &fname_end, qualify_db);
 
   /*
     prepare fields-list and SET if needed; print_query won't do that for us.
   */
-  pfields.length(0);
   if (!thd->lex->field_list.is_empty())
   {
     List_iterator<Item>  li(thd->lex->field_list);
 
-    pfields.append(" (");
+    query_str.append(" (");
     n= 0;
 
     while ((item= li++))
     {
       if (n++)
-        pfields.append(", ");
+        query_str.append(", ");
       if (item->type() == Item::FIELD_ITEM)
-      {
-        pfields.append("`");
-        pfields.append(item->name);
-        pfields.append("`");
-      }
+        append_identifier(thd, &query_str, item->name, strlen(item->name));
       else
-        item->print(&pfields, QT_ORDINARY);
+        item->print(&query_str, QT_ORDINARY);
     }
-    pfields.append(")");
+    query_str.append(")");
   }
 
   if (!thd->lex->update_list.is_empty())
@@ -750,38 +740,25 @@ static bool write_execute_load_query_log
     List_iterator<Item> lu(thd->lex->update_list);
     List_iterator<Item> lv(thd->lex->value_list);
 
-    pfields.append(" SET ");
+    query_str.append(" SET ");
     n= 0;
 
     while ((item= lu++))
     {
       val= lv++;
       if (n++)
-        pfields.append(", ");
-      pfields.append("`");
-      pfields.append(item->name);
-      pfields.append("`");
-      pfields.append(val->name);
+        query_str.append(", ");
+      append_identifier(thd, &query_str, item->name, strlen(item->name));
+      query_str.append(val->name);
     }
   }
 
-  p=  pfields.c_ptr_safe();
-  pl= pfields.length();
-
-  if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl)))
+  if (!(load_data_query= (char *)thd->strmake(query_str.ptr(), query_str.length())))
     return TRUE;
 
-  lle.print_query(FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
-                  load_data_query, &end,
-                  (char **)&fname_start, (char **)&fname_end);
-
-  strcpy(end, p);
-  end += pl;
-
   Execute_load_query_log_event
-    e(thd, load_data_query, end-load_data_query,
-      (uint) ((char*) fname_start - load_data_query - 1),
-      (uint) ((char*) fname_end - load_data_query),
+    e(thd, load_data_query, query_str.length(),
+      (uint) (fname_start - 1), (uint) fname_end,
       (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
       (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
       transactional_table, FALSE, FALSE, errcode);

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2012-08-09 15:22:00 +0000
+++ b/sql/sql_repl.cc	2012-07-06 09:19:16 +0000
@@ -2000,7 +2000,7 @@ bool mysql_show_binlog_events(THD* thd)
         description_event->checksum_alg= ev->checksum_alg;
 
       if (event_count >= limit_start &&
-          ev->net_send(protocol, linfo.log_file_name, pos))
+          ev->net_send(thd, protocol, linfo.log_file_name, pos))
       {
         errmsg = "Net error";
         delete ev;

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2012-08-21 12:24:43 +0000
+++ b/sql/sql_select.cc	2012-07-06 09:19:16 +0000
@@ -16481,7 +16481,7 @@ int report_error(TABLE *table, int error
       && !table->in_use->killed)
   {
     push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, error,
-                        "Got error %d when reading table `%s`.`%s`",
+                        "Got error %d when reading table %`s.%`s",
                         error, table->s->db.str, table->s->table_name.str);
     sql_print_error("Got error %d when reading table '%s'",
                     error, table->s->path.str);

=== modified file 'sql/sql_string.cc'
--- a/sql/sql_string.cc	2012-04-07 13:58:46 +0000
+++ b/sql/sql_string.cc	2012-07-06 09:19:16 +0000
@@ -1121,39 +1121,47 @@ well_formed_copy_nchars(CHARSET_INFO *to
 
 
 
-
-void String::print(String *str)
+/*
+  Append characters to a single-quoted string '...', escaping special
+  characters as necessary.
+  Does not add the enclosing quotes, this is left up to caller.
+*/
+void String::append_for_single_quote(const char *st, uint len)
 {
-  char *st= (char*)Ptr, *end= st+str_length;
+  const char *end= st+len;
   for (; st < end; st++)
   {
     uchar c= *st;
     switch (c)
     {
     case '\\':
-      str->append(STRING_WITH_LEN("\\\\"));
+      append(STRING_WITH_LEN("\\\\"));
       break;
     case '\0':
-      str->append(STRING_WITH_LEN("\\0"));
+      append(STRING_WITH_LEN("\\0"));
       break;
     case '\'':
-      str->append(STRING_WITH_LEN("\\'"));
+      append(STRING_WITH_LEN("\\'"));
       break;
     case '\n':
-      str->append(STRING_WITH_LEN("\\n"));
+      append(STRING_WITH_LEN("\\n"));
       break;
     case '\r':
-      str->append(STRING_WITH_LEN("\\r"));
+      append(STRING_WITH_LEN("\\r"));
       break;
     case '\032': // Ctrl-Z
-      str->append(STRING_WITH_LEN("\\Z"));
+      append(STRING_WITH_LEN("\\Z"));
       break;
     default:
-      str->append(c);
+      append(c);
     }
   }
 }
 
+void String::print(String *str)
+{
+  str->append_for_single_quote(Ptr, str_length);
+}
 
 /*
   Exchange state of this object and argument.

=== modified file 'sql/sql_string.h'
--- a/sql/sql_string.h	2012-01-13 14:50:02 +0000
+++ b/sql/sql_string.h	2012-07-06 09:19:16 +0000
@@ -459,6 +459,7 @@ class String
     return FALSE;
   }
   void print(String *print);
+  void append_for_single_quote(const char *st, uint len);
 
   /* Swap two string objects. Efficient way to exchange data without memcpy. */
   void swap(String &s);

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2012-08-15 11:37:55 +0000
+++ b/sql/sql_table.cc	2012-07-06 09:19:16 +0000
@@ -2104,6 +2104,7 @@ int mysql_rm_table_no_locks(THD *thd, TA
   {
     bool is_trans;
     char *db=table->db;
+    size_t db_length= table->db_length;
     handlerton *table_type;
     enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
 
@@ -2165,14 +2166,14 @@ int mysql_rm_table_no_locks(THD *thd, TA
           Don't write the database name if it is the current one (or if
           thd->db is NULL).
         */
-        built_ptr_query->append("`");
         if (thd->db == NULL || strcmp(db,thd->db) != 0)
         {
-          built_ptr_query->append(db);
-          built_ptr_query->append("`.`");
+          append_identifier(thd, built_ptr_query, db, db_length);
+          built_ptr_query->append(".");
         }
-        built_ptr_query->append(table->table_name);
-        built_ptr_query->append("`,");
+        append_identifier(thd, built_ptr_query, table->table_name,
+                          table->table_name_length);
+        built_ptr_query->append(",");
       }
       /*
         This means that a temporary table was droped and as such there
@@ -2228,15 +2229,15 @@ int mysql_rm_table_no_locks(THD *thd, TA
           Don't write the database name if it is the current one (or if
           thd->db is NULL).
         */
-        built_query.append("`");
         if (thd->db == NULL || strcmp(db,thd->db) != 0)
         {
-          built_query.append(db);
-          built_query.append("`.`");
+          append_identifier(thd, &built_query, db, db_length);
+          built_query.append(".");
         }
 
-        built_query.append(table->table_name);
-        built_query.append("`,");
+        append_identifier(thd, &built_query, table->table_name,
+                          table->table_name_length);
+        built_query.append(",");
       }
     }
     DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");

=== modified file 'sql/sql_truncate.cc'
--- a/sql/sql_truncate.cc	2012-05-16 22:47:28 +0000
+++ b/sql/sql_truncate.cc	2012-07-06 09:19:16 +0000
@@ -24,6 +24,7 @@
 #include "sql_acl.h"     // DROP_ACL
 #include "sql_parse.h"   // check_one_table_access()
 #include "sql_truncate.h"
+#include "sql_show.h"
 
 
 /**
@@ -35,7 +36,8 @@
   @return TRUE on failure, FALSE otherwise.
 */
 
-static bool fk_info_append_fields(String *str, List<LEX_STRING> *fields)
+static bool fk_info_append_fields(THD *thd, String *str,
+                                  List<LEX_STRING> *fields)
 {
   bool res= FALSE;
   LEX_STRING *field;
@@ -43,9 +45,8 @@ static bool fk_info_append_fields(String
 
   while ((field= it++))
   {
-    res|= str->append("`");
-    res|= str->append(field);
-    res|= str->append("`, ");
+    append_identifier(thd, str, field->str, field->length);
+    res|= str->append(", ");
   }
 
   str->chop();
@@ -76,20 +77,24 @@ static const char *fk_info_str(THD *thd,
     `db`.`tbl`, CONSTRAINT `id` FOREIGN KEY (`fk`) REFERENCES `db`.`tbl` (`fk`)
   */
 
-  res|= str.append('`');
-  res|= str.append(fk_info->foreign_db);
-  res|= str.append("`.`");
-  res|= str.append(fk_info->foreign_table);
-  res|= str.append("`, CONSTRAINT `");
-  res|= str.append(fk_info->foreign_id);
-  res|= str.append("` FOREIGN KEY (");
-  res|= fk_info_append_fields(&str, &fk_info->foreign_fields);
-  res|= str.append(") REFERENCES `");
-  res|= str.append(fk_info->referenced_db);
-  res|= str.append("`.`");
-  res|= str.append(fk_info->referenced_table);
-  res|= str.append("` (");
-  res|= fk_info_append_fields(&str, &fk_info->referenced_fields);
+  append_identifier(thd, &str, fk_info->foreign_db->str,
+                    fk_info->foreign_db->length);
+  res|= str.append(".");
+  append_identifier(thd, &str, fk_info->foreign_table->str,
+                    fk_info->foreign_table->length);
+  res|= str.append(", CONSTRAINT ");
+  append_identifier(thd, &str, fk_info->foreign_id->str,
+                    fk_info->foreign_id->length);
+  res|= str.append(" FOREIGN KEY (");
+  res|= fk_info_append_fields(thd, &str, &fk_info->foreign_fields);
+  res|= str.append(") REFERENCES ");
+  append_identifier(thd, &str, fk_info->referenced_db->str,
+                    fk_info->referenced_db->length);
+  res|= str.append(".");
+  append_identifier(thd, &str, fk_info->referenced_table->str,
+                    fk_info->referenced_table->length);
+  res|= str.append(" (");
+  res|= fk_info_append_fields(thd, &str, &fk_info->referenced_fields);
   res|= str.append(')');
 
   return res ? NULL : thd->strmake(str.ptr(), str.length());



More information about the commits mailing list