MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:June 27 2006 11:11pm
Subject:bk commit into 5.0 tree (anozdrin:1.2203) BUG#20438
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of alik. When alik does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2203 06/06/28 03:11:13 anozdrin@stripped +14 -0
  Fix for BUG#20438: CREATE statements for views, stored routines and
  triggers can be not replicable.

  sql/sql_yacc.yy
    1.472 06/06/28 03:11:09 anozdrin@stripped +5 -0
    Remember whether we was in comment in the middle of CREATE statement
    or not.

  sql/sql_trigger.h
    1.20 06/06/28 03:11:09 anozdrin@stripped +2 -4
    Changed trigger-handling code so that there will be the one
    place for generate statement string for replication log
    and for trigger file.

  sql/sql_trigger.cc
    1.51 06/06/28 03:11:09 anozdrin@stripped +58 -55
    1. Changed trigger-handling code so that there will be the one
      place for generate statement string for replication log
      and for trigger file.
    2. Append beginning paranthesis of version-specific comment.

  sql/sql_parse.cc
    1.556 06/06/28 03:11:09 anozdrin@stripped +11 -0
    Append beginning paranthesis of version-specific comment.

  sql/sql_lex.h
    1.220 06/06/28 03:11:09 anozdrin@stripped +6 -0
    Added member to understand whether we was in comment when
    parsing CREATE statement or not.

  sql/sp.cc
    1.114 06/06/28 03:11:09 anozdrin@stripped +11 -0
    Append beginning paranthesis of version-specific comment.

  server-tools/instance-manager/options.cc
    1.33 06/06/28 03:11:09 anozdrin@stripped +0 -3
    Move useful QUOTE() macro from Instance Manager specific
    code to the common place.

  mysql-test/t/rpl_view.test
    1.4 06/06/28 03:11:09 anozdrin@stripped +84 -0
    Added test case for BUG#20438.

  mysql-test/t/rpl_trigger.test
    1.8 06/06/28 03:11:09 anozdrin@stripped +92 -0
    Added test case for BUG#20438.

  mysql-test/t/rpl_sp.test
    1.13 06/06/28 03:11:08 anozdrin@stripped +80 -0
    Added test case for BUG#20438.

  mysql-test/r/rpl_view.result
    1.5 06/06/28 03:11:08 anozdrin@stripped +37 -0
    Updated result file.

  mysql-test/r/rpl_trigger.result
    1.9 06/06/28 03:11:08 anozdrin@stripped +47 -0
    Updated result file.

  mysql-test/r/rpl_sp.result
    1.18 06/06/28 03:11:08 anozdrin@stripped +44 -0
    Updated result file.

  include/m_string.h
    1.38 06/06/28 03:11:08 anozdrin@stripped +3 -0
    Move useful QUOTE() macro from Instance Manager specific
    code to the common place.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	anozdrin
# Host:	booka.site
# Root:	/home/alik/MySQL/devel/5.0-rt-bug20438

--- 1.37/include/m_string.h	2005-10-13 18:36:40 +04:00
+++ 1.38/include/m_string.h	2006-06-28 03:11:08 +04:00
@@ -256,6 +256,9 @@ extern int my_vsnprintf( char *str, size
                                 const char *format, va_list ap );
 extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
 
+#define QUOTE_IMPL(x) #x
+#define QUOTE(x) QUOTE_IMPL(x)
+
 #if defined(__cplusplus) && !defined(OS2)
 }
 #endif

--- 1.219/sql/sql_lex.h	2006-06-27 00:50:50 +04:00
+++ 1.220/sql/sql_lex.h	2006-06-28 03:11:09 +04:00
@@ -995,6 +995,12 @@ typedef struct st_lex : public Query_tab
   const char *stmt_definition_begin;
 
   /*
+    stmt_definition_begin_in_comment specifies whether the beginning of
+    statement is in version-specific comment or not.
+  */
+  bool stmt_definition_begin_in_comment;
+
+  /*
     Pointers to part of LOAD DATA statement that should be rewritten
     during replication ("LOCAL 'filename' REPLACE INTO" part).
   */

--- 1.555/sql/sql_parse.cc	2006-06-27 03:34:07 +04:00
+++ 1.556/sql/sql_parse.cc	2006-06-28 03:11:09 +04:00
@@ -4749,6 +4749,17 @@ end_with_restore_list:
         append_identifier(thd, &buff, first_table->table_name,
                           first_table->table_name_length);
         buff.append(STRING_WITH_LEN(" AS "));
+
+        if (thd->lex->stmt_definition_begin_in_comment)
+        {
+          /*
+            Open fake version-specific comment, because there is the end of it
+            somewhere later in the original query.
+          */
+
+          buff.append(STRING_WITH_LEN("/*!" QUOTE(MYSQL_VERSION_ID) " "));
+        }
+
         buff.append(first_table->source.str, first_table->source.length);
 
         Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);

--- 1.471/sql/sql_yacc.yy	2006-06-27 00:50:52 +04:00
+++ 1.472/sql/sql_yacc.yy	2006-06-28 03:11:09 +04:00
@@ -9017,6 +9017,8 @@ view_tail:
 	  THD *thd= YYTHD;
 	  LEX *lex= thd->lex;
 	  lex->sql_command= SQLCOM_CREATE_VIEW;
+          lex->stmt_definition_begin_in_comment= lex->in_comment;
+
 	  /* first table in list is target VIEW name */
 	  if (!lex->select_lex.add_table_to_list(thd, $3, NULL, TL_OPTION_UPDATING))
 	    YYABORT;
@@ -9101,6 +9103,7 @@ trigger_tail:
 	  sp->init(lex);
 	
 	  lex->stmt_definition_begin= $2;
+          lex->stmt_definition_begin_in_comment= lex->in_comment;
           lex->ident.str= $7;
           lex->ident.length= $10 - $7;
 
@@ -9161,6 +9164,7 @@ sp_tail:
 	  LEX *lex=Lex;
 	  lex->udf.type= $1;
 	  lex->stmt_definition_begin= $2;
+          lex->stmt_definition_begin_in_comment= lex->in_comment;
 	  lex->spname= $4;
 	}
 	create_function_tail
@@ -9177,6 +9181,7 @@ sp_tail:
 	  }
 	  
 	  lex->stmt_definition_begin= $2;
+          lex->stmt_definition_begin_in_comment= lex->in_comment;
 	  
 	  /* Order is important here: new - reset - init */
 	  sp= new sp_head();

--- 1.4/mysql-test/r/rpl_view.result	2006-05-12 20:58:47 +04:00
+++ 1.5/mysql-test/r/rpl_view.result	2006-06-28 03:11:08 +04:00
@@ -54,3 +54,40 @@ slave-bin.000001	#	Query	1	#	use `test`;
 slave-bin.000001	#	Query	1	#	use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW v1 AS select a as b from t1
 slave-bin.000001	#	Query	1	#	use `test`; drop view v1
 slave-bin.000001	#	Query	1	#	use `test`; drop table t1
+
+---> Test for BUG#20438
+
+---> Preparing environment...
+---> connection: master
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+
+---> Synchronizing slave with master...
+
+---> connection: master
+
+---> Creating objects...
+CREATE TABLE t1(c INT);
+/*!50003 CREATE VIEW v1 AS SELECT * FROM t1 */;
+
+---> Inserting value...
+INSERT INTO t1 VALUES(1);
+
+---> Checking on master...
+SELECT * FROM t1;
+c
+1
+
+---> Synchronizing slave with master...
+---> connection: master
+
+---> Checking on slave...
+SELECT * FROM t1;
+c
+1
+
+---> connection: master
+
+---> Cleaning up...
+DROP VIEW v1;
+DROP TABLE t1;

--- 1.3/mysql-test/t/rpl_view.test	2005-09-15 00:11:56 +04:00
+++ 1.4/mysql-test/t/rpl_view.test	2006-06-28 03:11:09 +04:00
@@ -45,3 +45,87 @@ drop table t1;
 sync_slave_with_master;
 --replace_column 2 # 5 #
 show binlog events limit 1,100;
+
+
+
+#
+# BUG#20438: CREATE statements for views, stored routines and triggers can be
+# not replicable.
+#
+
+--echo
+--echo ---> Test for BUG#20438
+
+# Prepare environment.
+
+--echo
+--echo ---> Preparing environment...
+--echo ---> connection: master
+--connection master
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+--echo
+--echo ---> Synchronizing slave with master...
+
+--save_master_pos
+--connection slave
+--sync_with_master
+
+--echo
+--echo ---> connection: master
+--connection master
+
+# Test.
+
+--echo
+--echo ---> Creating objects...
+
+CREATE TABLE t1(c INT);
+
+/*!50003 CREATE VIEW v1 AS SELECT * FROM t1 */;
+
+--echo
+--echo ---> Inserting value...
+
+INSERT INTO t1 VALUES(1);
+
+--echo
+--echo ---> Checking on master...
+
+SELECT * FROM t1;
+
+--echo
+--echo ---> Synchronizing slave with master...
+
+--save_master_pos
+--connection slave
+--sync_with_master
+
+--echo ---> connection: master
+
+--echo
+--echo ---> Checking on slave...
+
+SELECT * FROM t1;
+
+# Cleanup.
+
+--echo
+--echo ---> connection: master
+--connection master
+
+--echo
+--echo ---> Cleaning up...
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--save_master_pos
+--connection slave
+--sync_with_master
+--connection master
+

--- 1.50/sql/sql_trigger.cc	2006-06-27 00:47:47 +04:00
+++ 1.51/sql/sql_trigger.cc	2006-06-28 03:11:09 +04:00
@@ -158,11 +158,13 @@ bool mysql_create_or_drop_trigger(THD *t
 {
   TABLE *table;
   bool result= TRUE;
-  LEX_STRING definer_user;
-  LEX_STRING definer_host;
+  String stmt_query;
 
   DBUG_ENTER("mysql_create_or_drop_trigger");
 
+ /* Charset of the buffer for statement must be system one. */
+  stmt_query.set_charset(system_charset_info);
+
   /*
     QQ: This function could be merged in mysql_alter_table() function
     But do we want this ?
@@ -255,8 +257,8 @@ bool mysql_create_or_drop_trigger(THD *t
   }
 
   result= (create ?
-           table->triggers->create_trigger(thd, tables, &definer_user, &definer_host):
-           table->triggers->drop_trigger(thd, tables));
+           table->triggers->create_trigger(thd, tables, &stmt_query):
+           table->triggers->drop_trigger(thd, tables, &stmt_query));
 
 end:
   VOID(pthread_mutex_unlock(&LOCK_open));
@@ -268,29 +270,9 @@ end:
     {
       thd->clear_error();
 
-      String log_query(thd->query, thd->query_length, system_charset_info);
-
-      if (create)
-      {
-        log_query.set((char *) 0, 0, system_charset_info); /* reset log_query */
-
-        log_query.append(STRING_WITH_LEN("CREATE "));
-
-        if (definer_user.str && definer_host.str)
-        {
-          /*
-            Append definer-clause if the trigger is SUID (a usual trigger in
-            new MySQL versions).
-          */
-
-          append_definer(thd, &log_query, &definer_user, &definer_host);
-        }
-
-        log_query.append(thd->lex->stmt_definition_begin);
-      }
-
       /* Such a statement can always go directly to binlog, no trans cache. */
-      Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), 0, FALSE);
+      Query_log_event qinfo(thd, stmt_query.ptr(), stmt_query.length(), 0,
+                            FALSE);
       mysql_bin_log.write(&qinfo);
     }
 
@@ -310,22 +292,8 @@ end:
                      LEX)
       tables       - table list containing one open table for which the
                      trigger is created.
-      definer_user - [out] after a call it points to 0-terminated string or
-                     contains the NULL-string:
-                       - 0-terminated is returned if the trigger is SUID. The
-                         string contains user name part of the actual trigger
-                         definer.
-                       - NULL-string is returned if the trigger is non-SUID.
-                     Anyway, the caller is responsible to provide memory for
-                     storing LEX_STRING object.
-      definer_host - [out] after a call it points to 0-terminated string or
-                     contains the NULL-string:
-                       - 0-terminated string is returned if the trigger is
-                         SUID. The string contains host name part of the
-                         actual trigger definer.
-                       - NULL-string is returned if the trigger is non-SUID.
-                     Anyway, the caller is responsible to provide memory for
-                     storing LEX_STRING object.
+      stmt_query   - [OUT] after successful return, this string contains
+                     well-formed statement for creation this trigger.
 
   NOTE
     - Assumes that trigger name is fully qualified.
@@ -340,8 +308,7 @@ end:
     True  - error
 */
 bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
-                                         LEX_STRING *definer_user,
-                                         LEX_STRING *definer_host)
+                                         String *stmt_query)
 {
   LEX *lex= thd->lex;
   TABLE *table= tables->table;
@@ -349,6 +316,8 @@ bool Table_triggers_list::create_trigger
        trigname_path[FN_REFLEN];
   LEX_STRING dir, file, trigname_file;
   LEX_STRING *trg_def, *name;
+  LEX_STRING definer_user;
+  LEX_STRING definer_host;
   ulonglong *trg_sql_mode;
   char trg_definer_holder[USER_HOST_BUFF_SIZE];
   LEX_STRING *trg_definer;
@@ -494,8 +463,6 @@ bool Table_triggers_list::create_trigger
       definers_list.push_back(trg_definer, &table->mem_root))
     goto err_with_cleanup;
 
-  trg_def->str= thd->query;
-  trg_def->length= thd->query_length;
   *trg_sql_mode= thd->variables.sql_mode;
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -515,27 +482,60 @@ bool Table_triggers_list::create_trigger
   {
     /* SUID trigger. */
 
-    *definer_user= lex->definer->user;
-    *definer_host= lex->definer->host;
+    definer_user= lex->definer->user;
+    definer_host= lex->definer->host;
 
     trg_definer->str= trg_definer_holder;
-    trg_definer->length= strxmov(trg_definer->str, definer_user->str, "@",
-                                 definer_host->str, NullS) - trg_definer->str;
+    trg_definer->length= strxmov(trg_definer->str, definer_user.str, "@",
+                                 definer_host.str, NullS) - trg_definer->str;
   }
   else
   {
     /* non-SUID trigger. */
 
-    definer_user->str= 0;
-    definer_user->length= 0;
+    definer_user.str= 0;
+    definer_user.length= 0;
 
-    definer_host->str= 0;
-    definer_host->length= 0;
+    definer_host.str= 0;
+    definer_host.length= 0;
 
     trg_definer->str= (char*) "";
     trg_definer->length= 0;
   }
 
+  /*
+    Create well-formed trigger definition query. Original query is not
+    appropriated, because definer-clause can be not truncated.
+  */
+
+  stmt_query->append(STRING_WITH_LEN("CREATE "));
+
+  if (trg_definer)
+  {
+    /*
+      Append definer-clause if the trigger is SUID (a usual trigger in
+      new MySQL versions).
+    */
+
+    append_definer(thd, stmt_query, &definer_user, &definer_host);
+  }
+
+  if (thd->lex->stmt_definition_begin_in_comment)
+  {
+    /*
+      Open fake version-specific comment, because there is the end of it
+      somewhere later in the original query.
+    */
+
+    stmt_query->append(STRING_WITH_LEN("/*!" QUOTE(MYSQL_VERSION_ID) " "));
+  }
+
+  stmt_query->append(thd->lex->stmt_definition_begin);
+  trg_def->str= stmt_query->c_ptr();
+  trg_def->length= stmt_query->length();
+
+  /* Create trigger definition file. */
+
   if (!sql_create_definition_file(&dir, &file, &triggers_file_type,
                                   (gptr)this, triggers_file_parameters, 0))
     return 0;
@@ -641,7 +641,8 @@ static bool save_trigger_file(Table_trig
     False - success
     True  - error
 */
-bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables)
+bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
+                                       String *stmt_query)
 {
   LEX *lex= thd->lex;
   LEX_STRING *name;
@@ -650,6 +651,8 @@ bool Table_triggers_list::drop_trigger(T
   List_iterator<ulonglong>       it_mod(definition_modes_list);
   List_iterator<LEX_STRING>      it_definer(definers_list);
   char path[FN_REFLEN];
+
+  stmt_query->append(thd->query, thd->query_length);
 
   while ((name= it_name++))
   {

--- 1.19/sql/sql_trigger.h	2006-02-26 16:32:52 +03:00
+++ 1.20/sql/sql_trigger.h	2006-06-28 03:11:09 +04:00
@@ -86,10 +86,8 @@ public:
   }
   ~Table_triggers_list();
 
-  bool create_trigger(THD *thd, TABLE_LIST *table,
-                      LEX_STRING *definer_user,
-                      LEX_STRING *definer_host);
-  bool drop_trigger(THD *thd, TABLE_LIST *table);
+  bool create_trigger(THD *thd, TABLE_LIST *table, String *stmt_query);
+  bool drop_trigger(THD *thd, TABLE_LIST *table, String *stmt_query);
   bool process_triggers(THD *thd, trg_event_type event,
                         trg_action_time_type time_type,
                         bool old_row_is_record1);

--- 1.17/mysql-test/r/rpl_sp.result	2006-03-02 15:18:45 +03:00
+++ 1.18/mysql-test/r/rpl_sp.result	2006-06-28 03:11:08 +04:00
@@ -420,4 +420,48 @@ SELECT * FROM t1;
 col
 test
 DROP PROCEDURE p1;
+
+---> Test for BUG#20438
+
+---> Preparing environment...
+---> connection: master
+DROP PROCEDURE IF EXISTS p1;
+DROP FUNCTION IF EXISTS f1;
+
+---> Synchronizing slave with master...
+
+---> connection: master
+
+---> Creating procedure...
+/*!50003 CREATE PROCEDURE p1() SET @a = 1 */;
+/*!50003 CREATE FUNCTION f1() RETURNS INT RETURN 0 */;
+
+---> Checking on master...
+SHOW CREATE PROCEDURE p1;
+Procedure	sql_mode	Create Procedure
+p1		CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+SET @a = 1
+SHOW CREATE FUNCTION f1;
+Function	sql_mode	Create Function
+f1		CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
+RETURN 0
+
+---> Synchronizing slave with master...
+---> connection: master
+
+---> Checking on slave...
+SHOW CREATE PROCEDURE p1;
+Procedure	sql_mode	Create Procedure
+p1		CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+SET @a = 1
+SHOW CREATE FUNCTION f1;
+Function	sql_mode	Create Function
+f1		CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
+RETURN 0
+
+---> connection: master
+
+---> Cleaning up...
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
 drop table t1;

--- 1.12/mysql-test/t/rpl_sp.test	2006-02-18 19:26:25 +03:00
+++ 1.13/mysql-test/t/rpl_sp.test	2006-06-28 03:11:08 +04:00
@@ -435,6 +435,86 @@ connection master;
 
 DROP PROCEDURE p1;
 
+
+#
+# BUG#20438: CREATE statements for views, stored routines and triggers can be
+# not replicable.
+#
+
+--echo
+--echo ---> Test for BUG#20438
+
+# Prepare environment.
+
+--echo
+--echo ---> Preparing environment...
+--echo ---> connection: master
+--connection master
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP FUNCTION IF EXISTS f1;
+--enable_warnings
+
+--echo
+--echo ---> Synchronizing slave with master...
+
+--save_master_pos
+--connection slave
+--sync_with_master
+
+--echo
+--echo ---> connection: master
+--connection master
+
+# Test.
+
+--echo
+--echo ---> Creating procedure...
+
+/*!50003 CREATE PROCEDURE p1() SET @a = 1 */;
+
+/*!50003 CREATE FUNCTION f1() RETURNS INT RETURN 0 */;
+
+--echo
+--echo ---> Checking on master...
+
+SHOW CREATE PROCEDURE p1;
+SHOW CREATE FUNCTION f1;
+
+--echo
+--echo ---> Synchronizing slave with master...
+
+--save_master_pos
+--connection slave
+--sync_with_master
+
+--echo ---> connection: master
+
+--echo
+--echo ---> Checking on slave...
+
+SHOW CREATE PROCEDURE p1;
+SHOW CREATE FUNCTION f1;
+
+# Cleanup.
+
+--echo
+--echo ---> connection: master
+--connection master
+
+--echo
+--echo ---> Cleaning up...
+
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
+
+--save_master_pos
+--connection slave
+--sync_with_master
+--connection master
+
+
 # cleanup
 connection master;
 drop table t1;

--- 1.32/server-tools/instance-manager/options.cc	2006-05-10 18:53:25 +04:00
+++ 1.33/server-tools/instance-manager/options.cc	2006-06-28 03:11:09 +04:00
@@ -27,9 +27,6 @@
 #include <m_string.h>
 #include <mysql_com.h>
 
-#define QUOTE2(x) #x
-#define QUOTE(x) QUOTE2(x)
-
 #ifdef __WIN__
 char Options::install_as_service;
 char Options::remove_service;

--- 1.8/mysql-test/r/rpl_trigger.result	2006-05-12 20:58:47 +04:00
+++ 1.9/mysql-test/r/rpl_trigger.result	2006-06-28 03:11:08 +04:00
@@ -896,3 +896,50 @@ Tables_in_test (t_)
 SHOW TRIGGERS;
 Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
 RESET MASTER;
+START SLAVE;
+
+---> Test for BUG#20438
+
+---> Preparing environment...
+---> connection: master
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+
+---> Synchronizing slave with master...
+
+---> connection: master
+
+---> Creating objects...
+CREATE TABLE t1(c INT);
+CREATE TABLE t2(c INT);
+/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1
+FOR EACH ROW
+INSERT INTO t2 VALUES(NEW.c * 10) */;
+
+---> Inserting value...
+INSERT INTO t1 VALUES(1);
+
+---> Checking on master...
+SELECT * FROM t1;
+c
+1
+SELECT * FROM t2;
+c
+10
+
+---> Synchronizing slave with master...
+---> connection: master
+
+---> Checking on slave...
+SELECT * FROM t1;
+c
+1
+SELECT * FROM t2;
+c
+10
+
+---> connection: master
+
+---> Cleaning up...
+DROP TABLE t1;
+DROP TABLE t2;

--- 1.7/mysql-test/t/rpl_trigger.test	2006-03-08 00:13:25 +03:00
+++ 1.8/mysql-test/t/rpl_trigger.test	2006-06-28 03:11:09 +04:00
@@ -331,6 +331,98 @@ SHOW TRIGGERS;
 
 RESET MASTER;
 
+# Restart slave.
+
+connection slave;
+START SLAVE;
+
+
+#
+# BUG#20438: CREATE statements for views, stored routines and triggers can be
+# not replicable.
+#
+
+--echo
+--echo ---> Test for BUG#20438
+
+# Prepare environment.
+
+--echo
+--echo ---> Preparing environment...
+--echo ---> connection: master
+--connection master
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+--echo
+--echo ---> Synchronizing slave with master...
+
+--save_master_pos
+--connection slave
+--sync_with_master
+
+--echo
+--echo ---> connection: master
+--connection master
+
+# Test.
+
+--echo
+--echo ---> Creating objects...
+
+CREATE TABLE t1(c INT);
+CREATE TABLE t2(c INT);
+
+/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1
+  FOR EACH ROW
+    INSERT INTO t2 VALUES(NEW.c * 10) */;
+
+--echo
+--echo ---> Inserting value...
+
+INSERT INTO t1 VALUES(1);
+
+--echo
+--echo ---> Checking on master...
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+--echo
+--echo ---> Synchronizing slave with master...
+
+--save_master_pos
+--connection slave
+--sync_with_master
+
+--echo ---> connection: master
+
+--echo
+--echo ---> Checking on slave...
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+# Cleanup.
+
+--echo
+--echo ---> connection: master
+--connection master
+
+--echo
+--echo ---> Cleaning up...
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+--save_master_pos
+--connection slave
+--sync_with_master
+--connection master
+
 
 #
 # End of tests

--- 1.113/sql/sp.cc	2006-06-27 00:47:47 +04:00
+++ 1.114/sql/sp.cc	2006-06-28 03:11:09 +04:00
@@ -626,6 +626,17 @@ db_create_routine(THD *thd, int type, sp
       log_query.append(STRING_WITH_LEN("CREATE "));
       append_definer(thd, &log_query, &thd->lex->definer->user,
                      &thd->lex->definer->host);
+
+      if (thd->lex->stmt_definition_begin_in_comment)
+      {
+        /*
+          Open fake version-specific comment, because there is the end of it
+          somewhere later in the original query.
+        */
+
+        log_query.append(STRING_WITH_LEN("/*!" QUOTE(MYSQL_VERSION_ID) " "));
+      }
+
       log_query.append(thd->lex->stmt_definition_begin);
 
       /* Such a statement can always go directly to binlog, no trans cache */
Thread
bk commit into 5.0 tree (anozdrin:1.2203) BUG#20438Alexander Nozdrin28 Jun