MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:January 4 2011 3:17pm
Subject:bzr commit into mysql-trunk branch (alfranio.correia:3454) Bug#57873
View as plain text  
#At file:///home/acorreia/workspace.oracle/repository.mysql/bzrwork/bug-57873/mysql-trunk/ based on revid:marc.alff@stripped

 3454 Alfranio Correia	2011-01-04
      BUG#57873 Backtick in savepoint name causes replication failure
      
      Backticks can be used as part of a name which may be wrongly interpreted if
      appropriated quotes are not used. This patch thus quotes names that are
      written to the binary log in the following cases:
      
        . User variable events;
        . Create database;
        . Create table;
        . Savepoint/Rollback;
        . Load data;
        . Drop table;
        . Drop database;
        . Other cases, where statements are constructed 
          and injected in the binary log.
      
      When an event is read from the binary log and used in the mysqlbinlog, the
      current database must have its name quoted before being processed. Such data
      is not quoted before being written to binary log in order to avoid problems
      with filters as they are not expecting quoted names.
     @ client/mysqldump.c
        Refactored this routine in order to avoid duplicated code.
        The code removed from here is used in the quote_str() in
        strings/strfill.c
     @ include/m_string.h
        Created quote_str() to quote strings.
     @ mysql-test/r/mysqlbinlog.result
        Updated result file.
     @ mysql-test/r/mysqlbinlog2.result
        Updated result file.
     @ mysql-test/r/user_var-binlog.result
        Updated result file.
     @ mysql-test/suite/binlog/r/binlog_base64_flag.result
        Updated result file.
     @ mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result
        Updated result file.
     @ mysql-test/suite/rpl/r/rpl_row_ignorable_event.result
        Updated result file.
     @ mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
        Updated result file.
     @ mysql-test/suite/rpl/r/rpl_sp.result
        Updated result file.
     @ sql/binlog.cc
        Quoted "Savepoint" and "Rollback".
     @ sql/ha_ndbcluster_binlog.cc
        The name of the table is quoted before being written to the
        binary log.
     @ sql/log_event.cc
        Quoted the current database and information related to Load_log_event.
     @ sql/log_event.h
        Created a wrapper to quote_str in strings/strfill.c.
     @ sql/sql_base.cc
        The name of the table is quoted before being written to the
        binary log.
     @ sql/sql_db.cc
        The name of the table is quoted before being written to the
        binary log.
     @ sql/sql_load.cc
        The name of the table is quoted before being written to the
        binary log.
     @ sql/sql_table.cc
        Quoted "Drop table".
     @ strings/strfill.c
        Created function to quote names.

    modified:
      client/mysqldump.c
      include/m_string.h
      mysql-test/r/mysqlbinlog.result
      mysql-test/r/mysqlbinlog2.result
      mysql-test/r/user_var-binlog.result
      mysql-test/suite/binlog/r/binlog_base64_flag.result
      mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result
      mysql-test/suite/rpl/r/rpl_row_ignorable_event.result
      mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
      mysql-test/suite/rpl/r/rpl_sp.result
      sql/binlog.cc
      sql/ha_ndbcluster_binlog.cc
      sql/log_event.cc
      sql/log_event.h
      sql/sql_base.cc
      sql/sql_db.cc
      sql/sql_load.cc
      sql/sql_table.cc
      strings/strfill.c
=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c	2010-12-07 12:11:26 +0000
+++ b/client/mysqldump.c	2011-01-04 15:17:14 +0000
@@ -533,7 +533,7 @@ static int init_dumping_tables(char *);
 static int init_dumping(char *, int init_func(char*));
 static int dump_databases(char **);
 static int dump_all_databases();
-static char *quote_name(const char *name, char *buff, my_bool force);
+static char *quote_name(const char *name, char *buffer, my_bool force);
 char check_if_ignore_table(const char *table_name, char *table_type);
 static char *primary_key_fields(const char *table_name);
 static my_bool get_view_structure(char *table, char* db);
@@ -1574,23 +1574,14 @@ static my_bool test_if_special_chars(con
   buff                 quoted string
 
 */
-static char *quote_name(const char *name, char *buff, my_bool force)
+static char *quote_name(const char *name, char *buffer, my_bool force)
 {
-  char *to= buff;
   char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
 
   if (!force && !opt_quoted && !test_if_special_chars(name))
     return (char*) name;
-  *to++= qtype;
-  while (*name)
-  {
-    if (*name == qtype)
-      *to++= qtype;
-    *to++= *name++;
-  }
-  to[0]= qtype;
-  to[1]= 0;
-  return buff;
+
+  return (quote_str(buffer, name, qtype));
 } /* quote_name */
 
 

=== modified file 'include/m_string.h'
--- a/include/m_string.h	2010-11-22 10:02:01 +0000
+++ b/include/m_string.h	2011-01-04 15:17:14 +0000
@@ -101,6 +101,7 @@ extern	void strappend(char *s,size_t len
 extern	char *strend(const char *s);
 extern  char *strcend(const char *, pchar);
 extern	char *strfill(char * s,size_t len,pchar fill);
+extern  char *quote_str(char *buffer, const char *name, char qtype);
 extern	char *strmake(char *dst,const char *src,size_t length);
 
 #ifndef strmov
@@ -291,5 +292,4 @@ static inline void lex_string_set(LEX_ST
   lex_str->str= (char *) c_str;
   lex_str->length= strlen(c_str);
 }
-
 #endif

=== modified file 'mysql-test/r/mysqlbinlog.result'
--- a/mysql-test/r/mysqlbinlog.result	2010-12-29 05:35:31 +0000
+++ b/mysql-test/r/mysqlbinlog.result	2011-01-04 15:17:14 +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")
 /*!*/;
@@ -420,7 +420,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
 DELIMITER /*!*/;
 ROLLBACK/*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1108844556/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
@@ -438,7 +438,7 @@ ROLLBACK /* added by mysqlbinlog */;
 /*!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=1108844556/*!*/;
 SET @@session.pseudo_thread_id=999999999/*!*/;
 SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=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/*!*/;
@@ -822,22 +822,22 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1266652094/*!*/;
 SavePoint mixed_cases
 /*!*/;
-use db1/*!*/;
+use `db1`/*!*/;
 SET TIMESTAMP=1266652094/*!*/;
 INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
 /*!*/;
 SET TIMESTAMP=1266652094/*!*/;
 INSERT INTO db1.t1 VALUES(40)
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1266652094/*!*/;
 ROLLBACK TO mixed_cases
 /*!*/;
-use db1/*!*/;
+use `db1`/*!*/;
 SET TIMESTAMP=1266652094/*!*/;
 INSERT INTO db1.t2 VALUES("after rollback to")
 /*!*/;
@@ -865,7 +865,7 @@ SET @@session.lc_time_names=0/*!*/;
 SET @@session.collation_database=DEFAULT/*!*/;
 BEGIN
 /*!*/;
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=1266652094/*!*/;
 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	2011-01-04 15:17:14 +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/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	2011-01-04 15:17:14 +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	2010-12-02 13:44:21 +0000
+++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result	2011-01-04 15:17:14 +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_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	2011-01-04 15:17:14 +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_row_ignorable_event.result'
--- a/mysql-test/suite/rpl/r/rpl_row_ignorable_event.result	2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_ignorable_event.result	2011-01-04 15:17:14 +0000
@@ -155,7 +155,7 @@ DELIMITER /*!*/;
 ROLLBACK/*!*/;
 # at #
 #server id #  end_log_pos # 	Query	thread_id=#	exec_time=#	error_code=#
-use test/*!*/;
+use `test`/*!*/;
 SET TIMESTAMP=t/*!*/;
 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/suite/rpl/r/rpl_row_mysqlbinlog.result'
--- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result	2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result	2011-01-04 15:17:14 +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:22:30 +0000
+++ b/mysql-test/suite/rpl/r/rpl_sp.result	2011-01-04 15:17:14 +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`:

=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2010-12-17 02:01:32 +0000
+++ b/sql/binlog.cc	2011-01-04 15:17:14 +0000
@@ -856,12 +856,12 @@ static int binlog_savepoint_set(handlert
 {
   DBUG_ENTER("binlog_savepoint_set");
   int error= 1;
-
   String log_query;
+  char quoted_id[NAME_LEN * 2];
+
+  Log_event::quote_name(quoted_id, thd->lex->ident.str);
   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("`"))
+      log_query.append(quoted_id))
     DBUG_RETURN(error);
 
   int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
@@ -889,6 +889,7 @@ static int binlog_savepoint_set(handlert
 static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
 {
   DBUG_ENTER("binlog_savepoint_rollback");
+  char quoted_id[NAME_LEN * 2];
 
   /*
     Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
@@ -898,11 +899,10 @@ static int binlog_savepoint_rollback(han
   if (unlikely(trans_has_updated_non_trans_table(thd) ||
                (thd->variables.option_bits & OPTION_KEEP_LOG)))
   {
+    Log_event::quote_name(quoted_id, thd->lex->ident.str);
     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("`"))
+        log_query.append(quoted_id))
       DBUG_RETURN(1);
     int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
     Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
@@ -4302,7 +4302,6 @@ err1:
   return 1;
 }
 
-
 /*
   These functions are placed in this file since they need access to
   binlog_hton, which has internal linkage.

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2010-10-21 09:49:16 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2011-01-04 15:17:14 +0000
@@ -1293,6 +1293,10 @@ int ndbcluster_log_schema_op(THD *thd, N
   }
 
   char tmp_buf2[FN_REFLEN];
+  char quoted_db[NAME_LEN * 2];
+  char quoted_new_db[NAME_LEN * 2];
+  char quoted_table[NAME_LEN * 2];
+  char quoted_new_table[NAME_LEN * 2];
   const char *type_str;
   switch (type)
   {
@@ -1302,16 +1306,19 @@ int ndbcluster_log_schema_op(THD *thd, N
       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);
+    query_length= (uint) (strxmov(tmp_buf2, "drop table ",
+                                  Log_event::quote_name(quoted_table,
+                                                        table_name), NullS) - tmp_buf2);
     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);
+    query_length= (uint) (strxmov(tmp_buf2, "rename table ",
+                                  Log_event::quote_name(quoted_db, db), ".",
+                                  Log_event::quote_name(quoted_table, table_name), " to ",
+                                  Log_event::quote_name(quoted_new_db, new_db), ".",
+                                  Log_event::quote_name(quoted_new_table, new_table_name), NullS) - tmp_buf2);
     type_str= "rename table";
     break;
   case SOT_CREATE_TABLE:

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-12-29 05:35:31 +0000
+++ b/sql/log_event.cc	2011-01-04 15:17:14 +0000
@@ -3241,8 +3241,12 @@ void Query_log_event::print_query_header
     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);
+    if (db[0] && different_db)
+    {
+      char quoted_db[NAME_LEN * 2];
+      Log_event::quote_name(quoted_db, db);
+      my_b_printf(file, "use %s%s\n", quoted_db, print_event_info->delimiter);
+    }
   }
 
   end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
@@ -4656,34 +4660,41 @@ 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, ...)"
+    5 + (NAME_LEN * 2)  + 3 +                   // "use DB; "
+    18 + fname_len + 2 +                        // "LOAD DATA INFILE 'file''"
+    11 +                                        // "CONCURRENT "
+    7 +					        // LOCAL
+    9 +                                         // " REPLACE or IGNORE "
+    13 + table_name_len +                       // "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)
 {
+  char quoted_id[NAME_LEN * 2];
+  size_t quoted_id_len= 0;
   char *pos= buf;
 
   if (need_db && db && db_len)
   {
-    pos= strmov(pos, "use `");
-    memcpy(pos, db, db_len);
-    pos= strmov(pos+db_len, "`; ");
+    String buffer;
+
+    buffer.set_charset(&my_charset_bin);
+    buffer.append("use ");
+    buffer.append(Log_event::quote_name(quoted_id, db));
+    buffer.append("; ");
+
+    pos= strmov(pos, buffer.c_ptr_safe());
   }
 
   pos= strmov(pos, "LOAD DATA ");
@@ -4710,17 +4721,15 @@ void Load_log_event::print_query(bool ne
   if (fn_end)
     *fn_end= pos;
 
-  pos= strmov(pos ," TABLE `");
+  pos= strmov(pos ," TABLE ");
   memcpy(pos, table_name, table_name_len);
   pos+= table_name_len;
 
   if (cs != NULL)
   {
-    pos= strmov(pos ,"` CHARACTER SET ");
+    pos= strmov(pos ," CHARACTER SET ");
     pos= strmov(pos ,  cs);
   }
-  else
-    pos= strmov(pos, "`");
 
   /* We have to create all optional fields as the default is not empty */
   pos= strmov(pos, " FIELDS TERMINATED BY ");
@@ -4760,8 +4769,12 @@ void Load_log_event::print_query(bool ne
         *pos++= ' ';
         *pos++= ',';
       }
-      memcpy(pos, field, field_lens[i]);
-      pos+=   field_lens[i];
+
+      Log_event::quote_name(quoted_id, field);
+      quoted_id_len= strlen(quoted_id);
+      memcpy(pos, quoted_id, quoted_id_len);
+      pos+= quoted_id_len;
+
       field+= field_lens[i]  + 1;
     }
     *pos++= ')';
@@ -5006,10 +5019,10 @@ void Load_log_event::print(FILE* file, P
   print(file, print_event_info, 0);
 }
 
-
 void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
 			   bool commented)
 {
+  char quoted_id[NAME_LEN * 2];
   IO_CACHE *const head= &print_event_info->head_cache;
 
   DBUG_ENTER("Load_log_event::print");
@@ -5033,11 +5046,14 @@ void Load_log_event::print(FILE* file_ar
         !commented)
       memcpy(print_event_info->db, db, db_len + 1);
   }
-  
+
   if (db && db[0] && different_db)
+  {
+    Log_event::quote_name(quoted_id, db);
     my_b_printf(head, "%suse %s%s\n", 
             commented ? "# " : "",
-            db, print_event_info->delimiter);
+            quoted_id, print_event_info->delimiter);
+  }
 
   if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
     my_b_printf(head,"%sSET @@session.pseudo_thread_id=%lu%s\n",
@@ -5053,8 +5069,15 @@ void Load_log_event::print(FILE* file_ar
     my_b_printf(head,"REPLACE ");
   else if (sql_ex.opt_flags & IGNORE_FLAG)
     my_b_printf(head,"IGNORE ");
-  
-  my_b_printf(head, "INTO TABLE `%s`", table_name);
+
+  /*
+    This part of the code is called for old Load_log_event events and will
+    not work correctly if table is fully qualified (e.g. db`.`table) as we
+    cannot distinguish this case from tables with names like xxx`.`yyy or
+    xxx.yyy, i.e. with dots. See also write_execute_load_query_log_event.
+  */
+  Log_event::quote_name(quoted_id, table_name);
+  my_b_printf(head, "INTO TABLE %s", quoted_id);
   my_b_printf(head, " FIELDS TERMINATED BY ");
   pretty_print_str(head, sql_ex.field_term, sql_ex.field_term_len);
 
@@ -5069,7 +5092,6 @@ void Load_log_event::print(FILE* file_ar
   my_b_printf(head," LINES TERMINATED BY ");
   pretty_print_str(head, sql_ex.line_term, sql_ex.line_term_len);
 
-
   if (sql_ex.line_start)
   {
     my_b_printf(head," STARTING BY ");
@@ -5087,8 +5109,9 @@ void Load_log_event::print(FILE* file_ar
     {
       if (i)
         my_b_printf(head, ",");
-      my_b_printf(head, "%s", field);
 
+      Log_event::quote_name(quoted_id, field);
+      my_b_printf(head, "%s", quoted_id);
       field += field_lens[i]  + 1;
     }
     my_b_printf(head, ")");
@@ -6140,7 +6163,6 @@ void User_var_log_event::pack_info(Proto
 }
 #endif /* !MYSQL_CLIENT */
 
-
 User_var_log_event::
 User_var_log_event(const char* buf,
                    const Format_description_log_event* description_event)
@@ -6281,6 +6303,7 @@ bool User_var_log_event::write(IO_CACHE*
 #ifdef MYSQL_CLIENT
 void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 {
+  char quoted_id[NAME_LEN * 2];
   IO_CACHE *const head= &print_event_info->head_cache;
 
   if (!print_event_info->short_form)
@@ -6289,9 +6312,9 @@ void User_var_log_event::print(FILE* fil
     my_b_printf(head, "\tUser_var\n");
   }
 
-  my_b_printf(head, "SET @`");
-  my_b_write(head, (uchar*) name, (uint) (name_len));
-  my_b_printf(head, "`");
+  my_b_printf(head, "SET @");
+  Log_event::quote_name(quoted_id, name);
+  my_b_write(head, (uchar*) quoted_id, (uint) strlen(quoted_id));
 
   if (is_null)
   {
@@ -7446,7 +7469,6 @@ void Execute_load_query_log_event::pack_
   my_free(buf);
 }
 
-
 int
 Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
 {

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2010-12-21 10:39:20 +0000
+++ b/sql/log_event.h	2011-01-04 15:17:14 +0000
@@ -33,6 +33,7 @@
 #endif
 
 #include <my_bitmap.h>
+#include <m_string.h>
 #include "rpl_constants.h"
 
 #ifdef MYSQL_CLIENT
@@ -1123,6 +1124,10 @@ public:
     return my_time(0);
   }
 #endif
+  static char *quote_name(char *buffer, const char *name)
+  {
+    return (quote_str(buffer, name, '`'));
+  }
   virtual Log_event_type get_type_code() = 0;
   virtual bool is_valid() const = 0;
   void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; }

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-12-29 00:38:59 +0000
+++ b/sql/sql_base.cc	2011-01-04 15:17:14 +0000
@@ -3753,13 +3753,17 @@ static bool open_table_entry_fini(THD *t
     entry->file->implicit_emptied= 0;
     if (mysql_bin_log.is_open())
     {
+      char quoted_db[NAME_LEN * 2];
+      char quoted_table[NAME_LEN * 2];
       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))))
       {
         /* this DELETE FROM is needed even with row-based binlogging */
-        end = strxmov(strmov(query, "DELETE FROM `"),
-                      share->db.str,"`.`",share->table_name.str,"`", NullS);
+        end = strxmov(strmov(query, "DELETE FROM "),
+                      Log_event::quote_name(quoted_db, share->db.str), ".",
+                      Log_event::quote_name(quoted_table, share->table_name.str),
+                      NullS);
         int errcode= query_error_code(thd, TRUE);
         if (thd->binlog_query(THD::STMT_QUERY_TYPE,
                               query, (ulong)(end-query),

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2010-12-10 12:52:55 +0000
+++ b/sql/sql_db.cc	2011-01-04 15:17:14 +0000
@@ -616,14 +616,16 @@ int mysql_create_db(THD *thd, char *db,
 not_silent:
   if (!silent)
   {
+    char quoted_db[NAME_LEN * 2];
     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);
+      query_length= (uint) (strxmov(tmp_query,"create database ",
+                                    Log_event::quote_name(quoted_db, db),
+                                    NullS) - tmp_query);
     }
     else
     {
@@ -883,14 +885,16 @@ bool mysql_rm_db(THD *thd,char *db,bool
 update_binlog:
   if (!silent && !error)
   {
+    char quoted_db[NAME_LEN * 2];
     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);
+      query_length= (uint) (strxmov(path, "drop database ",
+                                    Log_event::quote_name(quoted_db, db),
+                                    NullS) - path);
     }
     else
     {

=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc	2010-12-10 16:55:50 +0000
+++ b/sql/sql_load.cc	2011-01-04 15:17:14 +0000
@@ -675,7 +675,21 @@ static bool write_execute_load_query_log
   const char          *tbl= table_name_arg;
   const char          *tdb= (thd->db != NULL ? thd->db : db_arg);
   String              string_buf;
+  char                quoted_id[NAME_LEN * 2];
 
+  /*
+    The SQL statement is not written to the event and is automaticaly
+    constructed based on information, such as table and fields, that
+    is stored in the event.
+
+    In the future, if we decide to filter on the master, this may
+    cause problems because the table name is written to the binary
+    log with quote information. See WL#2387.
+
+    This is necessary because we need to ensure that tables with
+    names like xxx`.`yyy or xxx.yyy, i.e. with dots, are correctly
+    replicated.
+  */
   if (!thd->db || strcmp(db_arg, thd->db)) 
   {
     /*
@@ -684,13 +698,21 @@ static bool write_execute_load_query_log
       becomes a FQ name.
      */
     string_buf.set_charset(system_charset_info);
-    string_buf.append(db_arg);
-    string_buf.append("`");
+    Log_event::quote_name(quoted_id, db_arg);
+    string_buf.append(quoted_id);
+
     string_buf.append(".");
-    string_buf.append("`");
-    string_buf.append(table_name_arg);
-    tbl= string_buf.c_ptr_safe();
+  
+    Log_event::quote_name(quoted_id, table_name_arg);
+    string_buf.append(quoted_id);
+  }
+  else
+  {
+    string_buf.set_charset(system_charset_info);
+    Log_event::quote_name(quoted_id, table_name_arg);
+    string_buf.append(quoted_id);
   }
+  tbl= string_buf.c_ptr_safe();
 
   Load_log_event       lle(thd, ex, tdb, tbl, fv, is_concurrent,
                            duplicates, ignore, transactional_table);
@@ -717,9 +739,8 @@ static bool write_execute_load_query_log
         pfields.append(", ");
       if (item->type() == Item::FIELD_ITEM)
       {
-        pfields.append("`");
-        pfields.append(item->name);
-        pfields.append("`");
+        pfields.append(
+          Log_event::quote_name(quoted_id, item->name));
       }
       else
         item->print(&pfields, QT_ORDINARY);
@@ -740,9 +761,8 @@ static bool write_execute_load_query_log
       val= lv++;
       if (n++)
         pfields.append(", ");
-      pfields.append("`");
-      pfields.append(item->name);
-      pfields.append("`");
+      pfields.append(
+          Log_event::quote_name(quoted_id, item->name));
       pfields.append("=");
       val->print(&pfields, QT_ORDINARY);
     }

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-12-17 18:43:38 +0000
+++ b/sql/sql_table.cc	2011-01-04 15:17:14 +0000
@@ -2161,6 +2161,9 @@ int mysql_rm_table_no_locks(THD *thd, TA
   bool non_tmp_table_deleted= 0;
   String built_query;
   String built_trans_tmp_query, built_non_trans_tmp_query;
+  char quoted_db[NAME_LEN * 2];
+  char quoted_table[NAME_LEN * 2];
+
   DBUG_ENTER("mysql_rm_table_no_locks");
 
   /*
@@ -2280,14 +2283,16 @@ 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("`.`");
+          built_ptr_query->append(
+            Log_event::quote_name(quoted_db, db));
+          built_ptr_query->append(".");
         }
-        built_ptr_query->append(table->table_name);
-        built_ptr_query->append("`,");
+        built_ptr_query->append(
+          Log_event::quote_name(quoted_table, 
+                                table->table_name));
+        built_ptr_query->append(",");
       }
       /*
         This means that a temporary table was droped and as such there
@@ -2346,15 +2351,16 @@ 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("`.`");
+          built_query.append(
+            Log_event::quote_name(quoted_db, db));
+          built_query.append(".");
         }
-
-        built_query.append(table->table_name);
-        built_query.append("`,");
+        built_query.append(
+          Log_event::quote_name(quoted_table,
+                                table->table_name));
+        built_query.append(",");
       }
     }
     DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
@@ -4107,7 +4113,6 @@ bool mysql_create_table_no_lock(THD *thd
   DBUG_PRINT("enter", ("db: '%s'  table: '%s'  tmp: %d",
                        db, table_name, internal_tmp_table));
 
-
   /* Check for duplicate fields and check type of table to create */
   if (!alter_info->create_list.elements)
   {

=== modified file 'strings/strfill.c'
--- a/strings/strfill.c	2007-05-10 09:59:39 +0000
+++ b/strings/strfill.c	2011-01-04 15:17:14 +0000
@@ -32,3 +32,32 @@ char * strfill(char *s, size_t len, pcha
   *(s) = '\0';
   return(s);
 } /* strfill */
+
+/**
+  Wraps up name with qtype, doubles any qtype in name and stores the
+  result string in buffer;
+
+  @param[in,out] buffer Place where the modified name is stored
+  @param[in]     name   String that will have their qtype
+                        doubled
+  @param[in]     qtype  Token used to create a modified
+                        version of name
+
+  @return
+    @c buffer where the result string is placed.
+*/
+char *quote_str(char *buffer, const char *name, char qtype)
+{
+  char *to= buffer;
+
+  *to++= qtype;
+  while (*name)
+  {
+    if (*name == qtype)
+      *to++= qtype;
+    *to++= *name++;
+  }
+  to[0]= qtype;
+  to[1]= 0;
+  return buffer;
+}


Attachment: [text/bzr-bundle] bzr/alfranio.correia@oracle.com-20110104151714-nx6gxa9enyr9cx84.bundle
Thread
bzr commit into mysql-trunk branch (alfranio.correia:3454) Bug#57873Alfranio Correia4 Jan