List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:April 23 2012 9:04am
Subject:bzr push into mysql-5.5 branch (andrei.elkin:3798 to 3802)
View as plain text  
 3802 Andrei Elkin	2012-04-23 [merge]
      null merge from 5.1.

 3801 Andrei Elkin	2012-04-21
      merge bug11754117-45670 fixes from 5.1: fixing comments in sql_lex.h.

    modified:
      sql/sql_lex.h
 3800 Andrei Elkin	2012-04-21
      merge bug11754117-45670 fixes from 5.1: fixing result files.

    modified:
      mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result
      mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result
 3799 Andrei Elkin	2012-04-21 [merge]
      merge bug11754117-45670 fixes from 5.1.

    added:
      mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result
      mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test
    modified:
      mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result
      mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test
      sql/log_event.cc
      sql/log_event.h
      sql/rpl_rli.cc
      sql/rpl_rli.h
      sql/rpl_utility.cc
      sql/rpl_utility.h
      sql/share/errmsg-utf8.txt
      sql/slave.cc
      sql/sql_base.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_lex.cc
      sql/sql_lex.h
      sql/sql_parse.cc
 3798 Mayank Prasad	2012-04-21
      BUG#12427262 : 60961: SHOW TABLES VERY SLOW WHEN NOT IN SYSTEM DISK CACHE
      
      Details:
       - test case bug12427262.test was failing on windows because
         on windows '/' was not recognized. And this was used in
         LIKE clause of the query being run in this test case.
      
      Fix:
       - Windows needs '\\\\' for path seperater in mysql. I was 
         not sure how to keep a single query with two different 
         syntax based on platform. So modifying query to make sure
         it runs correctly on both platform.

    modified:
      mysql-test/r/bug12427262.result
      mysql-test/t/bug12427262.test
=== added file 'mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result'
--- a/mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result	2012-04-23 08:56:23 +0000
@@ -0,0 +1,41 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
+create table tm (b int auto_increment, a int, primary key (a,b)) engine= myisam;
+create table ti (b int auto_increment, a int, primary key (a,b)) engine= innodb;
+ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key
+create table ti (b int auto_increment, a int, primary key (b,a)) engine= innodb;
+set @@binlog_format=statement;
+*** autoincrement field is not the first in PK warning must be there: ***
+insert into tm set b=null, a=1;
+Warnings:
+Note	1592	Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT into autoincrement field which is not the first part in the composed primary key is unsafe.
+show warnings;
+Level	Code	Message
+Note	1592	Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT into autoincrement field which is not the first part in the composed primary key is unsafe.
+*** no warning when autoincrement is the first in PK
+insert into ti set b=null, a=1;
+show warnings;
+Level	Code	Message
+create function multi_part_pk_with_autoinc (arg int)
+returns int
+begin
+insert into tm set b=null, a=arg;
+return arg;
+end//
+select multi_part_pk_with_autoinc (3);
+multi_part_pk_with_autoinc (3)
+3
+Warnings:
+Note	1592	Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
+Note	1592	Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT into autoincrement field which is not the first part in the composed primary key is unsafe.
+*** autoincrement field is not the first in PK warning must be there: ***
+show warnings;
+Level	Code	Message
+Note	1592	Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
+Note	1592	Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT into autoincrement field which is not the first part in the composed primary key is unsafe.
+set @@binlog_format=mixed;
+insert into tm set b=null, a=2;
+drop table tm, ti;
+drop function multi_part_pk_with_autoinc;
+include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result'
--- a/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result	2011-02-23 09:31:37 +0000
+++ b/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result	2012-04-21 11:19:06 +0000
@@ -114,4 +114,25 @@ id	c
 3	3
 [on master]
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT);
+CREATE TABLE test.t1 (a INT);
+INSERT INTO test.t1 VALUES(1);
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT);
+CREATE TRIGGER t1_update AFTER UPDATE ON test.t1 FOR EACH ROW
+INSERT INTO test.t_slave VALUES(NULL, ROUND(RAND() * 1000), @c);
+SET INSERT_ID=2;
+SET @c=2;
+SET @@rand_seed1=10000000, @@rand_seed2=1000000;
+INSERT INTO t5 VALUES (NULL, ROUND(RAND() * 1000), @c);
+Warnings:
+Note	1592	Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave.
+SELECT b into @b FROM test.t5;
+UPDATE test.t1 SET a=2;
+SELECT a AS 'ONE' into @a FROM test.t_slave;
+SELECT c AS 'NULL' into @c FROM test.t_slave;
+SELECT b into @b FROM test.t_slave;
+drop table test.t5;
+drop table test.t1;
+drop table test.t_slave;
 include/rpl_end.inc

=== added file 'mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test'
--- a/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test	2012-04-23 08:56:23 +0000
@@ -0,0 +1,62 @@
+# Test of auto-increment.
+#
+# BUG#11754117-45670 
+# Multipart primary key with the autoincrement part not first in it
+# is replication unsafe.
+#
+
+source include/master-slave.inc;
+source include/have_binlog_format_mixed.inc;
+source include/have_innodb.inc;
+
+call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
+
+--connection master
+create table tm (b int auto_increment, a int, primary key (a,b)) engine= myisam;
+--error ER_WRONG_AUTO_KEY
+create table ti (b int auto_increment, a int, primary key (a,b)) engine= innodb;
+create table ti (b int auto_increment, a int, primary key (b,a)) engine= innodb;
+
+set @@binlog_format=statement;
+--echo *** autoincrement field is not the first in PK warning must be there: ***
+insert into tm set b=null, a=1;
+show warnings;
+--echo *** no warning when autoincrement is the first in PK
+insert into ti set b=null, a=1;
+show warnings;
+
+delimiter //;
+create function multi_part_pk_with_autoinc (arg int)
+returns int
+begin
+  insert into tm set b=null, a=arg;
+  return arg;
+end//
+delimiter ;//
+
+select multi_part_pk_with_autoinc (3);
+--echo *** autoincrement field is not the first in PK warning must be there: ***
+show warnings;
+
+set @@binlog_format=mixed;
+insert into tm set b=null, a=2;
+
+sync_slave_with_master;
+
+if (`select count(*) <> 3 from tm`)
+{
+  --echo Wrong result from SELECT on the slave side.
+  select * from tm;
+  --die
+}
+
+# cleanup
+
+--connection master
+
+drop table tm, ti;
+drop function multi_part_pk_with_autoinc;
+
+sync_slave_with_master;
+
+--source include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test'
--- a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test	2011-02-23 09:31:37 +0000
+++ b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test	2012-04-20 16:41:20 +0000
@@ -206,4 +206,64 @@ SELECT * FROM t3;
 connection master;
 echo [on master];
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+
+--sync_slave_with_master
+
+#
+# BUG#11754117 - 45670: INTVAR_EVENTS FOR FILTERED-OUT QUERY_LOG_EVENTS ARE EXECUTED
+# Int-, Rand- and User- var events accompaning a filtered out Query-log-event should
+# be filtered as well.
+#
+connection master;
+CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); # ignored on slave
+CREATE TABLE test.t1 (a INT); # accepted on slave
+INSERT INTO test.t1 VALUES(1);
+
+--sync_slave_with_master
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT);
+CREATE TRIGGER t1_update AFTER UPDATE ON test.t1 FOR EACH ROW
+                               INSERT INTO test.t_slave VALUES(NULL, ROUND(RAND() * 1000), @c);
+
+connection master;
+SET INSERT_ID=2;
+SET @c=2;
+SET @@rand_seed1=10000000, @@rand_seed2=1000000;
+INSERT INTO t5 VALUES (NULL, ROUND(RAND() * 1000), @c); # to be ignored
+SELECT b into @b FROM test.t5;
+--let $b_master=`select @b`
+UPDATE test.t1 SET a=2; # to run trigger on slave
+
+--sync_slave_with_master
+
+# The proof:
+SELECT a AS 'ONE' into @a FROM test.t_slave;
+SELECT c AS 'NULL' into @c FROM test.t_slave;
+
+let $count= 1;
+let $table= test.t_slave;
+source include/wait_until_rows_count.inc;
+
+if (`SELECT @a != 2 and @c != NULL`)
+{
+    SELECT * FROM test.t_slave;
+    --die Intvar or user var from replication events unexpetedly escaped out to screw a following query applying context.
+}
+
+SELECT b into @b FROM test.t_slave;
+--let $b_slave=`select @b`
+
+if (`SELECT $b_slave = $b_master`)
+{
+    --echo Might be pure coincidence of two randoms from master and slave table. Don not panic yet.
+}
+
+# cleanup BUG#11754117
+connection master;
+drop table test.t5;
+drop table test.t1;
+
+--sync_slave_with_master
+drop table test.t_slave;
+
 --source include/rpl_end.inc

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2012-04-12 05:37:39 +0000
+++ b/sql/log_event.cc	2012-04-21 10:24:39 +0000
@@ -5372,11 +5372,12 @@ void Intvar_log_event::print(FILE* file,
 #endif
 
 
+#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
+
 /*
   Intvar_log_event::do_apply_event()
 */
 
-#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
 int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
 {
   /*
@@ -5385,6 +5386,9 @@ int Intvar_log_event::do_apply_event(Rel
    */
   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
 
+  if (rli->deferred_events_collecting)
+    return rli->deferred_events->add(this);
+
   switch (type) {
   case LAST_INSERT_ID_EVENT:
     thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
@@ -5490,6 +5494,9 @@ int Rand_log_event::do_apply_event(Relay
    */
   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
 
+  if (rli->deferred_events_collecting)
+    return rli->deferred_events->add(this);
+
   thd->rand.seed1= (ulong) seed1;
   thd->rand.seed2= (ulong) seed2;
   return 0;
@@ -5516,6 +5523,29 @@ Rand_log_event::do_shall_skip(Relay_log_
   return continue_group(rli);
 }
 
+/**
+   Exec deferred Int-, Rand- and User- var events prefixing
+   a Query-log-event event.
+
+   @param thd THD handle
+
+   @return false on success, true if a failure in an event applying occurred.
+*/
+bool slave_execute_deferred_events(THD *thd)
+{
+  bool res= false;
+  Relay_log_info *rli= thd->rli_slave;
+
+  DBUG_ASSERT(rli && (!rli->deferred_events_collecting || rli->deferred_events));
+
+  if (!rli->deferred_events_collecting || rli->deferred_events->is_empty())
+    return res;
+
+  res= rli->deferred_events->execute(rli);
+
+  return res;
+}
+
 #endif /* !MYSQL_CLIENT */
 
 
@@ -5939,6 +5969,10 @@ int User_var_log_event::do_apply_event(R
 {
   Item *it= 0;
   CHARSET_INFO *charset;
+
+  if (rli->deferred_events_collecting)
+    return rli->deferred_events->add(this);
+
   if (!(charset= get_charset(charset_number, MYF(MY_WME))))
     return 1;
   LEX_STRING user_var_name;

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2012-02-29 08:45:15 +0000
+++ b/sql/log_event.h	2012-04-21 10:24:39 +0000
@@ -4080,11 +4080,18 @@ private:
   const char* log_ident;
   uint ident_len;
 };
+
+/**
+   The function is called by slave applier in case there are
+   active table filtering rules to force gathering events associated
+   with Query-log-event into an array to execute
+   them once the fate of the Query is determined for execution.
+*/
+bool slave_execute_deferred_events(THD *thd);
 #endif
 
 int append_query_string(THD *thd, CHARSET_INFO *csinfo,
                         String const *from, String *to);
-
 /**
   @} (end of group Replication)
 */

=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc	2012-02-16 09:48:16 +0000
+++ b/sql/rpl_rli.cc	2012-04-21 10:24:39 +0000
@@ -52,8 +52,8 @@ Relay_log_info::Relay_log_info(bool is_s
    inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
    until_log_pos(0), retried_trans(0),
    tables_to_lock(0), tables_to_lock_count(0),
-   last_event_start_time(0), m_flags(0), row_stmt_start_timestamp(0),
-   long_find_row_note_printed(false)
+   last_event_start_time(0), deferred_events(NULL),m_flags(0),
+   row_stmt_start_timestamp(0), long_find_row_note_printed(false)
 {
   DBUG_ENTER("Relay_log_info::Relay_log_info");
 

=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h	2012-03-12 22:02:50 +0000
+++ b/sql/rpl_rli.h	2012-04-21 10:24:39 +0000
@@ -388,6 +388,41 @@ public:
   */
   time_t last_event_start_time;
 
+  /*
+    A container to hold on Intvar-, Rand-, Uservar- log-events in case
+    the slave is configured with table filtering rules.
+    The withhold events are executed when their parent Query destiny is
+    determined for execution as well.
+  */
+  Deferred_log_events *deferred_events;
+
+  /*
+    State of the container: true stands for IRU events gathering, 
+    false does for execution, either deferred or direct.
+  */
+  bool deferred_events_collecting;
+
+  /* 
+     Returns true if the argument event resides in the containter;
+     more specifically, the checking is done against the last added event.
+  */
+  bool is_deferred_event(Log_event * ev)
+  {
+    return deferred_events_collecting ? deferred_events->is_last(ev) : false;
+  };
+  /* The general cleanup that slave applier may need at the end of query. */
+  inline void cleanup_after_query()
+  {
+    if (deferred_events)
+      deferred_events->rewind();
+  };
+  /* The general cleanup that slave applier may need at the end of session. */
+  void cleanup_after_session()
+  {
+    if (deferred_events)
+      delete deferred_events;
+  };
+   
   /**
     Helper function to do after statement completion.
 

=== modified file 'sql/rpl_utility.cc'
--- a/sql/rpl_utility.cc	2011-06-30 15:46:53 +0000
+++ b/sql/rpl_utility.cc	2012-04-21 10:24:39 +0000
@@ -18,6 +18,7 @@
 #ifndef MYSQL_CLIENT
 #include "unireg.h"                      // REQUIRED by later includes
 #include "rpl_rli.h"
+#include "log_event.h"
 #include "sql_select.h"
 
 /**
@@ -1056,3 +1057,65 @@ table_def::~table_def()
 #endif
 }
 
+
+#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
+
+Deferred_log_events::Deferred_log_events(Relay_log_info *rli) : last_added(NULL)
+{
+  my_init_dynamic_array(&array, sizeof(Log_event *), 32, 16);
+}
+
+Deferred_log_events::~Deferred_log_events() 
+{
+  delete_dynamic(&array);
+}
+
+int Deferred_log_events::add(Log_event *ev)
+{
+  last_added= ev;
+  insert_dynamic(&array, (uchar*) &ev);
+  return 0;
+}
+
+bool Deferred_log_events::is_empty()
+{  
+  return array.elements == 0;
+}
+
+bool Deferred_log_events::execute(Relay_log_info *rli)
+{
+  bool res= false;
+
+  DBUG_ASSERT(rli->deferred_events_collecting);
+
+  rli->deferred_events_collecting= false;
+  for (uint i=  0; !res && i < array.elements; i++)
+  {
+    Log_event *ev= (* (Log_event **)
+                    dynamic_array_ptr(&array, i));
+    res= ev->apply_event(rli);
+  }
+  rli->deferred_events_collecting= true;
+  return res;
+}
+
+void Deferred_log_events::rewind()
+{
+  /*
+    Reset preceeding Query log event events which execution was
+    deferred because of slave side filtering.
+  */
+  if (!is_empty())
+  {
+    for (uint i=  0; i < array.elements; i++)
+    {
+      Log_event *ev= *(Log_event **) dynamic_array_ptr(&array, i);
+      delete ev;
+    }
+    if (array.elements > array.max_element)
+      freeze_size(&array);
+    reset_dynamic(&array);
+  }
+}
+
+#endif

=== modified file 'sql/rpl_utility.h'
--- a/sql/rpl_utility.h	2011-06-30 15:46:53 +0000
+++ b/sql/rpl_utility.h	2012-04-21 10:24:39 +0000
@@ -28,7 +28,7 @@
 #include "mysql_com.h"
 
 class Relay_log_info;
-
+class Log_event;
 
 /**
   A table definition from the master.
@@ -261,6 +261,24 @@ CPP_UNNAMED_NS_START
   };
 
 CPP_UNNAMED_NS_END
+
+class Deferred_log_events
+{
+private:
+  DYNAMIC_ARRAY array;
+  Log_event *last_added;
+
+public:
+  Deferred_log_events(Relay_log_info *rli);
+  ~Deferred_log_events();
+  /* queue for exection at Query-log-event time prior the Query */;
+  int add(Log_event *ev);
+  bool is_empty();
+  bool execute(Relay_log_info *rli);
+  void rewind();
+  bool is_last(Log_event *ev) { return ev == last_added; };
+};
+
 #endif
 
 // NB. number of printed bit values is limited to sizeof(buf) - 1

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2012-04-11 10:23:17 +0000
+++ b/sql/share/errmsg-utf8.txt	2012-04-21 10:24:39 +0000
@@ -6500,6 +6500,9 @@ ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
 ER_UNSUPPORTED_ENGINE
   eng "Storage engine '%s' does not support system tables. [%s.%s]"
 
+ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
+  eng "INSERT into autoincrement field which is not the first part in the composed primary key is unsafe."
+
 #
 #  End of 5.5 error messages.
 #

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2012-03-12 22:02:50 +0000
+++ b/sql/slave.cc	2012-04-21 10:24:39 +0000
@@ -2557,7 +2557,8 @@ static int exec_relay_log_event(THD* thd
       used to read info about the relay log's format; it will be deleted when
       the SQL thread does not need it, i.e. when this thread terminates.
     */
-    if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
+    if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT &&
+        !rli->is_deferred_event(ev))
     {
       DBUG_PRINT("info", ("Deleting the event after it has been executed"));
       delete ev;
@@ -3219,6 +3220,12 @@ pthread_handler_t handle_slave_sql(void 
     goto err;
   }
   thd->init_for_queries();
+  thd->rli_slave= rli;
+  if ((rli->deferred_events_collecting= rpl_filter->is_on()))
+  {
+    rli->deferred_events= new Deferred_log_events(rli);
+  }
+
   thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
   set_thd_in_use_temporary_tables(rli);   // (re)set sql_thd in use for saved temp tables
   mysql_mutex_lock(&LOCK_thread_count);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2012-04-02 19:05:43 +0000
+++ b/sql/sql_base.cc	2012-04-21 10:24:39 +0000
@@ -216,6 +216,7 @@ static bool
 has_write_table_with_auto_increment(TABLE_LIST *tables);
 static bool
 has_write_table_with_auto_increment_and_select(TABLE_LIST *tables);
+static bool has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables);
 
 uint cached_open_tables(void)
 {
@@ -5690,6 +5691,12 @@ bool lock_tables(THD *thd, TABLE_LIST *t
     if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables &&
         has_write_table_with_auto_increment_and_select(tables))
       thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT);
+    /* Todo: merge all has_write_table_auto_inc with decide_logging_format */
+    if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables)
+    {
+      if (has_write_table_auto_increment_not_first_in_pk(tables))
+        thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST);
+    }
 
     /* 
      INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys
@@ -9152,6 +9159,32 @@ has_write_table_with_auto_increment_and_
   return(has_select && has_auto_increment_tables);
 }
 
+/*
+  Tells if there is a table whose auto_increment column is a part
+  of a compound primary key while is not the first column in
+  the table definition.
+
+  @param tables Table list
+
+  @return true if the table exists, fais if does not.
+*/
+
+static bool
+has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables)
+{
+  for (TABLE_LIST *table= tables; table; table= table->next_global)
+  {
+    /* we must do preliminary checks as table->table may be NULL */
+    if (!table->placeholder() &&
+        table->table->found_next_number_field &&
+        (table->lock_type >= TL_WRITE_ALLOW_WRITE)
+        && table->table->s->next_number_keypart != 0)
+      return 1;
+  }
+
+  return 0;
+}
+
 
 
 /*

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2012-02-17 09:57:45 +0000
+++ b/sql/sql_class.cc	2012-04-21 10:24:39 +0000
@@ -744,7 +744,7 @@ bool Drop_table_error_handler::handle_co
 THD::THD()
    :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION,
               /* statement id */ 0),
-   rli_fake(0),
+   rli_fake(0), rli_slave(NULL),
    user_time(0), in_sub_stmt(0),
    binlog_unsafe_warning_flags(0),
    binlog_table_maps(0),
@@ -1359,6 +1359,8 @@ THD::~THD()
   }
   
   mysql_audit_free_thd(this);
+  if (rli_slave)
+    rli_slave->cleanup_after_session();
 #endif
 
   free_root(&main_mem_root, MYF(0));
@@ -1678,6 +1680,10 @@ void THD::cleanup_after_query()
   {
     delete_dynamic(&lex->mi.repl_ignore_server_ids);
   }
+#ifndef EMBEDDED_LIBRARY
+  if (rli_slave)
+    rli_slave->cleanup_after_query();
+#endif
 }
 
 

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-11-10 06:43:34 +0000
+++ b/sql/sql_class.h	2012-04-21 10:24:39 +0000
@@ -1445,6 +1445,8 @@ public:
 
   /* Used to execute base64 coded binlog events in MySQL server */
   Relay_log_info* rli_fake;
+  /* Slave applier execution context */
+  Relay_log_info* rli_slave;
 
   void reset_for_next_command();
   /*

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2012-04-18 11:15:27 +0000
+++ b/sql/sql_lex.cc	2012-04-21 10:24:39 +0000
@@ -67,7 +67,8 @@ Query_tables_list::binlog_stmt_unsafe_er
   ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT,
   ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC,
   ER_BINLOG_UNSAFE_UPDATE_IGNORE,
-  ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
+  ER_BINLOG_UNSAFE_INSERT_TWO_KEYS,
+  ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
 };
 
 

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2012-04-18 11:15:27 +0000
+++ b/sql/sql_lex.h	2012-04-21 12:06:06 +0000
@@ -1329,6 +1329,12 @@ public:
     */
     BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS,
 
+    /**
+       INSERT into auto-inc field which is not the first part of composed
+       primary key.
+    */
+    BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST,
+
     /* The last element of this enumeration type. */
     BINLOG_STMT_UNSAFE_COUNT
   };

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2012-04-18 09:12:19 +0000
+++ b/sql/sql_parse.cc	2012-04-21 10:24:39 +0000
@@ -2025,6 +2025,11 @@ mysql_execute_command(THD *thd)
       }
       DBUG_RETURN(0);
     }
+    /* 
+       Execute deferred events first
+    */
+    if (slave_execute_deferred_events(thd))
+      DBUG_RETURN(-1);
   }
   else
   {

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5 branch (andrei.elkin:3798 to 3802) Andrei Elkin23 Apr