List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:October 10 2007 6:37pm
Subject:Re: bk commit into 5.0 tree (aelkin:1.2541) BUG#29136
View as plain text  
Andrei Elkin wrote:
> Mats, good evening.
>
>   
>> Some comments below.
>>     
>
> You must have confused my 5.0 with 5.1 offering
>   

Yup. Seems like that.

That was my only comment, so patch it OK to push.

Just my few cents,
Mats Kindahl

>   
>> Please use THD::binlog_query() instead of writing directly to the
>> binary log.
>>
>>     
>
>   
>>> +    */
>>> +    if (mysql_bin_log.is_open())
>>> +    {
>>> +      Query_log_event qinfo(thd, thd->query, thd->query_length,
>>> +                            transactional_tables, FALSE);
>>> +      mysql_bin_log.write(&qinfo);
>>> +    }
>>> +    thd->transaction.all.modified_non_trans_table= true;
>>>   
>>>       
>
> There are no more words from you which means for me you are on it
> still.
>
> cheers,
>
> Andrei
>
>   
>> Just my few cents,
>> Mats Kindahl
>>
>> Andrei Elkin wrote:
>>     
>>> Below is the list of changes that have just been committed into a local
>>> 5.0 repository of elkin. When elkin 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@stripped, 2007-10-09 15:19:53+03:00,
> aelkin@stripped +10 -0
>>>   Bug #29136 erred multi-delete on trans table does not rollback the
> statement
>>>     similar to bug_27716, but it was stressed on in the synopsis on
>>> that there is another
>>>   side of the artifact affecting behaviour in transaction.
>>>     Fixed with deploying multi_delete::send_error() - otherwise
>>> never called - and refining its logic
>>>   to perform binlogging job if needed.
>>>     The changeset includes the following side effects:
>>>   - added tests to check bug_23333's scenarios on the mixture of tables for
> multi_update;
>>>   - fixes bug@30763 with two-liner patch and a test coinciding to one added
> for bug_23333.
>>>
>>>   mysql-test/r/innodb.result@stripped, 2007-10-09 15:19:49+03:00,
> aelkin@stripped +15 -2
>>>     results changed
>>>
>>>   mysql-test/r/mix_innodb_myisam_binlog.result@stripped, 2007-10-09
> 15:19:49+03:00, aelkin@stripped +48 -4
>>>     results changed
>>>
>>>   mysql-test/r/multi_update.result@stripped, 2007-10-09 15:19:49+03:00,
> aelkin@stripped +22 -2
>>>     results changed
>>>
>>>   mysql-test/t/innodb.test@stripped, 2007-10-09 15:19:49+03:00,
> aelkin@stripped +32 -0
>>>     trans table specific test added
>>>
>>>   mysql-test/t/mix_innodb_myisam_binlog.test@stripped, 2007-10-09 15:19:50+03:00,
> aelkin@stripped +70 -6
>>>     multi-update  and multi-delete of mixure of ta and not-ta tables tests
> added (relates to bug_23333).
>>>
>>>   mysql-test/t/multi_update.test@stripped, 2007-10-09 15:19:50+03:00,
> aelkin@stripped +34 -0
>>>     testing another branch of mult-delete: send_eof() (binloggin there),
> send_error (early return)
>>>
>>>   sql/sql_class.h@stripped, 2007-10-09 15:19:50+03:00,
> aelkin@stripped +10 -0
>>>     a new flag to designate the fact the statement's error has been handled.
>>>     The flag is checked by ::send_error() methods (multi_update and _delete
> classes)
>>>
>>>   sql/sql_delete.cc@stripped, 2007-10-09 15:19:50+03:00,
> aelkin@stripped +26 -5
>>>     expanding multi_delete::send_error to     1. early return if
>>> error_handled == t
>>>     2. binlogging locally if there was a non-trans table modified side
> effect
>>>
>>>   sql/sql_parse.cc@stripped, 2007-10-09 15:19:50+03:00,
> aelkin@stripped +7 -0
>>>     adding multi_update::send_error which can perform binlogging and rollback
> job in needed
>>>
>>>   sql/sql_update.cc@stripped, 2007-10-09 15:19:50+03:00,
> aelkin@stripped +11 -11
>>>     issues relating to
>>>          1. bug_27716 with zeroing of `updated' to serve as the flag
>>> of early return from send_error().
>>>        The flag is changed to be a new member error_handled; also moved
> outside binlogging branch.
>>>        The reason for this change is that bug_23333 fixes were pushed after
> the bug_27716's and they
>>>        left this flaw (also no test coverage).
>>>     2. bug_30763 with assertion on trans_safe. I decide to make 2 liner fix
> for that bug here instead of to remove
>>>        those two assertions. This new bug test case is the same as for
> multi-update on the mixure of tables.
>>>        The rational for this fix:
>>>        presumption for mutli_update::trans_safe to be set to zero at
>>>        multi_update::multi_update or multi_update::initialize_tables() is
> incorrect.
>>>            trans_safe := false should happen only when a
>>> non-transactional table gets modified.        Therefore, at
>>> initialization the member must be be set to true.
>>>
>>> diff -Nrup a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
>>> --- a/mysql-test/r/innodb.result	2007-07-18 15:22:00 +03:00
>>> +++ b/mysql-test/r/innodb.result	2007-10-09 15:19:49 +03:00
>>> @@ -1119,6 +1119,19 @@ show master status /* there must be no U
>>>  File	Position	Binlog_Do_DB	Binlog_Ignore_DB
>>>  master-bin.000001	98		
>>>  drop table t1, t2;
>>> +drop table if exists t1, t2;
>>> +CREATE TABLE t1 (a int, PRIMARY KEY (a));
>>> +CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
>>> +create trigger trg_del_t2 after  delete on t2 for each row
>>> +insert into t1 values (1);
>>> +insert into t1 values (1);
>>> +insert into t2 values (1),(2);
>>> +delete t2 from t2;
>>> +ERROR 23000: Duplicate entry '1' for key 1
>>> +select count(*) from t2 /* must be 2 as restored after rollback caused by
> the error */;
>>> +count(*)
>>> +2
>>> +drop table t1, t2;
>>>  create table t1 (a int, b int) engine=innodb;
>>>  insert into t1 values(20,null);
>>>  select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3
> on
>>> @@ -1792,10 +1805,10 @@ Variable_name	Value
>>>  Innodb_page_size	16384
>>>  show status like "Innodb_rows_deleted";
>>>  Variable_name	Value
>>> -Innodb_rows_deleted	72
>>> +Innodb_rows_deleted	73
>>>  show status like "Innodb_rows_inserted";
>>>  Variable_name	Value
>>> -Innodb_rows_inserted	29732
>>> +Innodb_rows_inserted	29734
>>>  show status like "Innodb_rows_updated";
>>>  Variable_name	Value
>>>  Innodb_rows_updated	29532
>>> diff -Nrup a/mysql-test/r/mix_innodb_myisam_binlog.result
> b/mysql-test/r/mix_innodb_myisam_binlog.result
>>> --- a/mysql-test/r/mix_innodb_myisam_binlog.result	2007-08-22 10:40:35
> +03:00
>>> +++ b/mysql-test/r/mix_innodb_myisam_binlog.result	2007-10-09 15:19:49
> +03:00
>>> @@ -351,7 +351,7 @@ drop function if exists bug27417;
>>>  drop table if exists t1,t2;
>>>  CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
>>>  CREATE TABLE t2 (a int NOT NULL auto_increment, PRIMARY KEY (a));
>>> -create function bug27417(n int) +create function bug27417(n int)
>>>  RETURNS int(11)
>>>  begin
>>>  insert into t1 values (null);
>>> @@ -393,7 +393,9 @@ count(*)
>>>  drop table t1,t2;
>>>  CREATE TABLE t1 (a int  NOT NULL auto_increment primary key) ENGINE=MyISAM;
>>>  CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
>>> -CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
>>> +CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM;
>>> +CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb;
>>> +CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
>>>  insert into t2 values (1);
>>>  reset master;
>>>  insert into t2 values (bug27417(1));
>>> @@ -427,6 +429,31 @@ master-bin.000001	190		
>>>  select count(*) from t1 /* must be 2 */;
>>>  count(*)
>>>  2
>>> +delete from t3;
>>> +delete from t4;
>>> +insert into t3 values (1,1);
>>> +insert into t4 values (1,1),(2,2);
>>> +reset master;
>>> +UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
>>> +ERROR 23000: Duplicate entry '2' for key 1
>>> +show master status /* the offset must denote there is the query */;
>>> +File	Position	Binlog_Do_DB	Binlog_Ignore_DB
>>> +master-bin.000001	301		
>>> +select count(*) from t1 /* must be 2 */;
>>> +count(*)
>>> +4
>>> +delete from t1;
>>> +delete from t3;
>>> +delete from t4;
>>> +insert into t3 values (1,1),(2,2);
>>> +insert into t4 values (1,1),(2,2);
>>> +reset master;
>>> +UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
>>> +ERROR 23000: Duplicate entry '2' for key 1
>>> +select count(*) from t1 /* must be 1 */;
>>> +count(*)
>>> +1
>>> +drop table t4;
>>>  delete from t1;
>>>  delete from t2;
>>>  delete from t3;
>>> @@ -443,6 +470,23 @@ master-bin.000001	246		
>>>  select count(*) from t1 /* must be 1 */;
>>>  count(*)
>>>  1
>>> +drop trigger trg_del;
>>> +delete from t1;
>>> +delete from t2;
>>> +delete from t5;
>>> +create trigger trg_del_t2 after  delete on t2 for each row
>>> +insert into t1 values (1);
>>> +insert into t2 values (2),(3);
>>> +insert into t5 values (1),(2);
>>> +reset master;
>>> +delete t2.* from t2,t5 where t2.a=t5.a + 1;
>>> +ERROR 23000: Duplicate entry '1' for key 1
>>> +show master status /* the offset must denote there is the query */;
>>> +File	Position	Binlog_Do_DB	Binlog_Ignore_DB
>>> +master-bin.000001	274		
>>> +select count(*) from t1 /* must be 1 */;
>>> +count(*)
>>> +1
>>>  delete from t1;
>>>  create table t4 (a int default 0, b int primary key) engine=innodb;
>>>  insert into t4 values (0, 17);
>>> @@ -458,7 +502,7 @@ count(*)
>>>  show master status /* the offset must denote there is the query */;
>>>  File	Position	Binlog_Do_DB	Binlog_Ignore_DB
>>>  master-bin.000001	376		
>>> -drop trigger trg_del;
>>> -drop table t1,t2,t3,t4;
>>> +drop trigger trg_del_t2;
>>> +drop table t1,t2,t3,t4,t5;
>>>  drop function bug27417;
>>>  end of tests
>>> diff -Nrup a/mysql-test/r/multi_update.result
> b/mysql-test/r/multi_update.result
>>> --- a/mysql-test/r/multi_update.result	2007-06-01 11:14:01 +03:00
>>> +++ b/mysql-test/r/multi_update.result	2007-10-09 15:19:49 +03:00
>>> @@ -545,7 +545,7 @@ a	b
>>>  4	4
>>>  show master status /* there must be the UPDATE query event */;
>>>  File	Position	Binlog_Do_DB	Binlog_Ignore_DB
>>> -master-bin.000001	189		
>>> +master-bin.000001	260		
>>>  delete from t1;
>>>  delete from t2;
>>>  insert into t1 values (1,2),(3,4),(4,4);
>>> @@ -555,6 +555,26 @@ UPDATE t2,t1  SET t2.a=t2.b where t2.a=t
>>>  ERROR 23000: Duplicate entry '4' for key 1
>>>  show master status /* there must be the UPDATE query event */;
>>>  File	Position	Binlog_Do_DB	Binlog_Ignore_DB
>>> -master-bin.000001	204		
>>> +master-bin.000001	275		
>>>  drop table t1, t2;
>>> +drop table if exists t1, t2, t3;
>>> +CREATE TABLE t1 (a int, PRIMARY KEY (a));
>>> +CREATE TABLE t2 (a int, PRIMARY KEY (a));
>>> +CREATE TABLE t3 (a int, PRIMARY KEY (a)) ENGINE=MyISAM;
>>> +create trigger trg_del_t3 before  delete on t3 for each row insert into t1
> values (1);
>>> +insert into t2 values (1),(2);
>>> +insert into t3 values (1),(2);
>>> +reset master;
>>> +delete t3.* from t2,t3 where t2.a=t3.a;
>>> +ERROR 23000: Duplicate entry '1' for key 1
>>> +select count(*) from t1 /* must be 1 */;
>>> +count(*)
>>> +1
>>> +select count(*) from t3 /* must be 1 */;
>>> +count(*)
>>> +1
>>> +show binlog events from 98;
>>> +Log_name	Pos	Event_type	Server_id	End_log_pos	Info
>>> +master-bin.000001	98	Query	1	#	use `test`; delete t3.* from t2,t3 where
> t2.a=t3.a
>>> +drop table t1, t2, t3;
>>>  end of tests
>>> diff -Nrup a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
>>> --- a/mysql-test/t/innodb.test	2007-07-18 15:22:00 +03:00
>>> +++ b/mysql-test/t/innodb.test	2007-10-09 15:19:49 +03:00
>>> @@ -793,6 +793,38 @@ show master status /* there must be no U
>>>  drop table t1, t2;
>>>   #
>>> +# Bug #29136  	erred multi-delete on trans table does not
>>> rollback +#
>>> +
>>> +# prepare
>>> +--disable_warnings
>>> +drop table if exists t1, t2;
>>> +--enable_warnings
>>> +CREATE TABLE t1 (a int, PRIMARY KEY (a));
>>> +CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
>>> +create trigger trg_del_t2 after  delete on t2 for each row
>>> +       insert into t1 values (1);
>>> +insert into t1 values (1);
>>> +insert into t2 values (1),(2);
>>> +
>>> +
>>> +# exec cases A, B - see multi_update.test
>>> +
>>> +# A. send_error() w/o send_eof() branch
>>> +
>>> +--error ER_DUP_ENTRY
>>> +delete t2 from t2;
>>> +
>>> +# check
>>> +
>>> +select count(*) from t2 /* must be 2 as restored after rollback caused by
> the error */;
>>> +
>>> +# cleanup bug#29136
>>> +
>>> +drop table t1, t2;
>>> +
>>> +
>>> +#
>>>  # Testing of IFNULL
>>>  #
>>>  create table t1 (a int, b int) engine=innodb;
>>> diff -Nrup a/mysql-test/t/mix_innodb_myisam_binlog.test
> b/mysql-test/t/mix_innodb_myisam_binlog.test
>>> --- a/mysql-test/t/mix_innodb_myisam_binlog.test	2007-08-22 10:40:35 +03:00
>>> +++ b/mysql-test/t/mix_innodb_myisam_binlog.test	2007-10-09 15:19:50 +03:00
>>> @@ -347,7 +347,7 @@ CREATE TABLE t1 (a int NOT NULL auto_inc
>>>  CREATE TABLE t2 (a int NOT NULL auto_increment, PRIMARY KEY (a));
>>>   delimiter |;
>>> -create function bug27417(n int) +create function bug27417(n int)
>>>  RETURNS int(11)
>>>  begin
>>>    insert into t1 values (null);
>>> @@ -385,13 +385,17 @@ drop table t1,t2;
>>>   #
>>>  # Bug#23333 using the patch (and the test) for bug#27471
>>> +#
>>>  # throughout the bug tests  # t1 - non-trans side effects gatherer;
>>>  # t2 - transactional table;
>>>  #
>>> +
>>>  CREATE TABLE t1 (a int  NOT NULL auto_increment primary key) ENGINE=MyISAM;
>>>  CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
>>> -CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
>>> +CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM;
>>> +CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb;
>>> +CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
>>>    #
>>> @@ -434,7 +438,7 @@ CREATE TABLE t3 (a int, PRIMARY KEY (a),
>>>   select count(*) from t1 /* must be 2 */;
>>>   #
>>> -# UPDATE (multi-update see bug#27716)
>>> +# UPDATE inc multi-update
>>>  #
>>>   # prepare
>>> @@ -450,9 +454,48 @@ CREATE TABLE t3 (a int, PRIMARY KEY (a),
>>>   show master status /* the offset must denote there is the query */;
>>>   select count(*) from t1 /* must be 2 */;
>>>  +## multi_update::send_eof() branch
>>> +
>>> +# prepare
>>> + delete from t3;
>>> + delete from t4;
>>> + insert into t3 values (1,1);
>>> + insert into t4 values (1,1),(2,2);
>>> +
>>> + reset master;
>>> +
>>> +# execute
>>> + --error ER_DUP_ENTRY
>>> + UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
>>> +
>>> +# check
>>> + show master status /* the offset must denote there is the query */;
>>> + select count(*) from t1 /* must be 2 */;
>>> +
>>> +## send_error() branch of multi_update
>>> +
>>> +# prepare
>>> + delete from t1;
>>> + delete from t3;
>>> + delete from t4;
>>> + insert into t3 values (1,1),(2,2);
>>> + insert into t4 values (1,1),(2,2);
>>> +
>>> + reset master;
>>> +
>>> +# execute
>>> + --error ER_DUP_ENTRY
>>> + UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
>>> +
>>> +# check
>>> + select count(*) from t1 /* must be 1 */;
>>> +
>>> +# cleanup
>>> + drop table t4;
>>> +
>>>   #
>>> -# DELETE (for multi-delete see Bug #29136)
>>> +# DELETE incl multi-delete
>>>  #
>>>   # prepare
>>> @@ -472,6 +515,27 @@ CREATE TABLE t3 (a int, PRIMARY KEY (a),
>>>   show master status /* the offset must denote there is the query */;
>>>   select count(*) from t1 /* must be 1 */;
>>>  +# cleanup
>>> + drop trigger trg_del;
>>> +
>>> +# prepare
>>> + delete from t1;
>>> + delete from t2;
>>> + delete from t5;
>>> + create trigger trg_del_t2 after  delete on t2 for each row
>>> +   insert into t1 values (1);
>>> + insert into t2 values (2),(3);
>>> + insert into t5 values (1),(2);
>>> + reset master;
>>> +
>>> +# execute
>>> + --error ER_DUP_ENTRY
>>> + delete t2.* from t2,t5 where t2.a=t5.a + 1;
>>> +
>>> +# check
>>> + show master status /* the offset must denote there is the query */;
>>> + select count(*) from t1 /* must be 1 */;
>>> +
>>>   #
>>>  # LOAD DATA
>>> @@ -496,8 +560,8 @@ CREATE TABLE t3 (a int, PRIMARY KEY (a),
>>>  #
>>>   -drop trigger trg_del;
>>> -drop table t1,t2,t3,t4;
>>> +drop trigger trg_del_t2;
>>> +drop table t1,t2,t3,t4,t5;
>>>  drop function bug27417;
>>>   diff -Nrup a/mysql-test/t/multi_update.test
>>> b/mysql-test/t/multi_update.test
>>> --- a/mysql-test/t/multi_update.test	2007-06-01 11:14:01 +03:00
>>> +++ b/mysql-test/t/multi_update.test	2007-10-09 15:19:50 +03:00
>>> @@ -574,4 +574,38 @@ show master status /* there must be the  #
>>> cleanup bug#27716
>>>  drop table t1, t2;
>>>  +#
>>> +# Bug #29136  	erred multi-delete on trans table does not
>>> rollback +#
>>> +
>>> +# prepare
>>> +--disable_warnings
>>> +drop table if exists t1, t2, t3;
>>> +--enable_warnings
>>> +CREATE TABLE t1 (a int, PRIMARY KEY (a));
>>> +CREATE TABLE t2 (a int, PRIMARY KEY (a));
>>> +CREATE TABLE t3 (a int, PRIMARY KEY (a)) ENGINE=MyISAM;
>>> +create trigger trg_del_t3 before  delete on t3 for each row insert into t1
> values (1);
>>> +
>>> +insert into t2 values (1),(2);
>>> +insert into t3 values (1),(2);
>>> +reset master;
>>> +
>>> +# exec cases B, A - see innodb.test
>>> +
>>> +# B. send_eof() and send_error() afterward
>>> +
>>> +--error ER_DUP_ENTRY
>>> +delete t3.* from t2,t3 where t2.a=t3.a;
>>> +
>>> +# check
>>> +select count(*) from t1 /* must be 1 */;
>>> +select count(*) from t3 /* must be 1 */;
>>> +# the query must be in binlog (no surprise though)
>>> +source include/show_binlog_events.inc;
>>> +
>>> +# cleanup bug#29136
>>> +drop table t1, t2, t3;
>>> +
>>> +
>>>  --echo end of tests
>>> diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
>>> --- a/sql/sql_class.h	2007-10-03 12:57:12 +03:00
>>> +++ b/sql/sql_class.h	2007-10-09 15:19:50 +03:00
>>> @@ -2356,6 +2356,11 @@ class multi_delete :public select_result
>>>    /* True if at least one table we delete from is not transactional */
>>>    bool normal_tables;
>>>    bool delete_while_scanning;
>>> +  /*
>>> +     error handling (rollback and binlogging) can happen in send_eof()
>>> +     so that afterward send_error() needs to find out that.
>>> +  */
>>> +  bool error_handled;
>>>   public:
>>>    multi_delete(TABLE_LIST *dt, uint num_of_tables);
>>> @@ -2391,6 +2396,11 @@ class multi_update :public select_result
>>>    /* True if the update operation has made a change in a transactional table
> */
>>>    bool transactional_tables;
>>>    bool ignore;
>>> +  /* +     error handling (rollback and binlogging) can happen in
>>> send_eof()
>>> +     so that afterward send_error() needs to find out that.
>>> +  */
>>> +  bool error_handled;
>>>   public:
>>>    multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list,
>>> diff -Nrup a/sql/sql_delete.cc b/sql/sql_delete.cc
>>> --- a/sql/sql_delete.cc	2007-08-21 15:16:52 +03:00
>>> +++ b/sql/sql_delete.cc	2007-10-09 15:19:50 +03:00
>>> @@ -504,7 +504,7 @@ bool mysql_multi_delete_prepare(THD *thd
>>>  multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
>>>    : delete_tables(dt), deleted(0), found(0),
>>>      num_of_tables(num_of_tables_arg), error(0),
>>> -    do_delete(0), transactional_tables(0), normal_tables(0)
>>> +    do_delete(0), transactional_tables(0), normal_tables(0),
> error_handled(0)
>>>  {
>>>    tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
>>>  }
>>> @@ -685,12 +685,14 @@ void multi_delete::send_error(uint errco
>>>    /* First send error what ever it is ... */
>>>    my_message(errcode, err, MYF(0));
>>>  -  /* If nothing deleted return */
>>> -  if (!deleted)
>>> +  /* the error was handled or nothing deleted and no side effects return */
>>> +  if (error_handled ||
>>> +      !thd->transaction.stmt.modified_non_trans_table &&
> !deleted)
>>>      DBUG_VOID_RETURN;
>>>     /* Something already deleted so we have to invalidate cache */
>>> -  query_cache_invalidate3(thd, delete_tables, 1);
>>> +  if (deleted)
>>> +    query_cache_invalidate3(thd, delete_tables, 1);
>>>     /*
>>>      If rows from the first table only has been deleted and it is
>>> @@ -709,13 +711,30 @@ void multi_delete::send_error(uint errco
>>>        error log
>>>      */
>>>      error= 1;
>>> -    send_eof();
>>> +    send_eof(); // will reset deleted to zero
>>> +    DBUG_ASSERT(error_handled);
>>> +    DBUG_VOID_RETURN;
>>> +  }
>>> +  +  if (thd->transaction.stmt.modified_non_trans_table)
>>> +  {
>>> +    /* +       there is only side effects; to binlog with the error
>>> +    */
>>> +    if (mysql_bin_log.is_open())
>>> +    {
>>> +      Query_log_event qinfo(thd, thd->query, thd->query_length,
>>> +                            transactional_tables, FALSE);
>>> +      mysql_bin_log.write(&qinfo);
>>> +    }
>>> +    thd->transaction.all.modified_non_trans_table= true;
>>>   
>>>       
>> Please use THD::binlog_query() instead of writing directly to the
>> binary log.
>>
>>     
>>>    }
>>>    DBUG_ASSERT(!normal_tables || !deleted ||
> thd->transaction.stmt.modified_non_trans_table);
>>>    DBUG_VOID_RETURN;
>>>  }
>>>   +
>>>  /*
>>>    Do delete from other tables.
>>>    Returns values:
>>> @@ -832,6 +851,8 @@ bool multi_delete::send_eof()
>>>      if (thd->transaction.stmt.modified_non_trans_table)
>>>        thd->transaction.all.modified_non_trans_table= TRUE;
>>>    }
>>> +  if (local_error != 0)
>>> +    error_handled= TRUE; // to force early leave from ::send_error()
>>>     /* Commit or rollback the current SQL statement */
>>>    if (transactional_tables)
>>> diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
>>> --- a/sql/sql_parse.cc	2007-10-03 13:43:51 +03:00
>>> +++ b/sql/sql_parse.cc	2007-10-09 15:19:50 +03:00
>>> @@ -3701,6 +3701,13 @@ end_with_restore_list:
>>>  			SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
>>>                          OPTION_SETUP_TABLES_DONE,
>>>  			del_result, unit, select_lex);
>>> +      res|= thd->net.report_error;
>>> +      if (unlikely(res))
>>> +      {
>>> +        /* If we had a another error reported earlier then this will be
> ignored */
>>> +        del_result->send_error(ER_UNKNOWN_ERROR, "Execution of the query
> failed");
>>> +        del_result->abort();
>>> +      }
>>>        delete del_result;
>>>      }
>>>      else
>>> diff -Nrup a/sql/sql_update.cc b/sql/sql_update.cc
>>> --- a/sql/sql_update.cc	2007-08-21 15:16:52 +03:00
>>> +++ b/sql/sql_update.cc	2007-10-09 15:19:50 +03:00
>>> @@ -994,8 +994,8 @@ multi_update::multi_update(TABLE_LIST *t
>>>    :all_tables(table_list), leaves(leaves_list), update_tables(0),
>>>     tmp_tables(0), updated(0), found(0), fields(field_list),
>>>     values(value_list), table_count(0), copy_field(0),
>>> -   handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(0),
>>> -   transactional_tables(1), ignore(ignore_arg)
>>> +   handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
>>> +   transactional_tables(1), ignore(ignore_arg), error_handled(0)
>>>  {}
>>>   @@ -1202,7 +1202,6 @@ multi_update::initialize_tables(JOIN *jo
>>>    if ((thd->options & OPTION_SAFE_UPDATES) &&
> error_if_full_join(join))
>>>      DBUG_RETURN(1);
>>>    main_table=join->join_tab->table;
>>> -  trans_safe= transactional_tables=
> main_table->file->has_transactions();
>>>    table_to_update= 0;
>>>     /* Any update has at least one pair (field, value) */
>>> @@ -1484,12 +1483,14 @@ void multi_update::send_error(uint errco
>>>    /* First send error what ever it is ... */
>>>    my_error(errcode, MYF(0), err);
>>>  -  /* If nothing updated return */
>>> -  if (updated == 0) /* the counter might be reset in send_eof */
>>> -    return;         /* and then the query has been binlogged */
>>> +  /* the error was handled or nothing deleted and no side effects return */
>>> +  if (error_handled ||
>>> +      !thd->transaction.stmt.modified_non_trans_table &&
> !updated)
>>> +    return;
>>>     /* Something already updated so we have to invalidate cache */
>>> -  query_cache_invalidate3(thd, update_tables, 1);
>>> +  if (updated)
>>> +    query_cache_invalidate3(thd, update_tables, 1);
>>>    /*
>>>      If all tables that has been updated are trans safe then just do
> rollback.
>>>      If not attempt to do remaining updates.
>>> @@ -1525,8 +1526,7 @@ void multi_update::send_error(uint errco
>>>                              transactional_tables, FALSE);
>>>        mysql_bin_log.write(&qinfo);
>>>      }
>>> -    if (!trans_safe)
>>> -      thd->transaction.all.modified_non_trans_table= TRUE;
>>> +    thd->transaction.all.modified_non_trans_table= TRUE;
>>>    }
>>>    DBUG_ASSERT(trans_safe || !updated ||
> thd->transaction.stmt.modified_non_trans_table);
>>>    @@ -1739,8 +1739,6 @@ bool multi_update::send_eof()
>>>      {
>>>        if (local_error == 0)
>>>          thd->clear_error();
>>> -      else
>>> -        updated= 0; /* if there's an error binlog it here not in
> ::send_error */
>>>        Query_log_event qinfo(thd, thd->query, thd->query_length,
>>>  			    transactional_tables, FALSE);
>>>        if (mysql_bin_log.write(&qinfo) && trans_safe)
>>> @@ -1749,6 +1747,8 @@ bool multi_update::send_eof()
>>>      if (thd->transaction.stmt.modified_non_trans_table)
>>>        thd->transaction.all.modified_non_trans_table= TRUE;
>>>    }
>>> +  if (local_error != 0)
>>> +    error_handled= TRUE; // to force early leave from ::send_error()
>>>     if (transactional_tables)
>>>    {
>>>
>>>   
>>>       
>> -- 
>> Mats Kindahl
>> Lead Software Developer
>> Replication Team
>> MySQL AB, www.mysql.com
>>
>>
>>
>> -- 
>> MySQL Code Commits Mailing List
>> For list archives: http://lists.mysql.com/commits
>> To unsubscribe:    http://lists.mysql.com/commits?unsub=1
>>     


-- 
Mats Kindahl
Lead Software Developer
Replication Team
MySQL AB, www.mysql.com


Thread
bk commit into 5.0 tree (aelkin:1.2541) BUG#29136Andrei Elkin9 Oct
  • Re: bk commit into 5.0 tree (aelkin:1.2541) BUG#29136Mats Kindahl10 Oct
    • Re: bk commit into 5.0 tree (aelkin:1.2541) BUG#29136Andrei Elkin10 Oct
      • Re: bk commit into 5.0 tree (aelkin:1.2541) BUG#29136Mats Kindahl10 Oct
  • RE: bk commit into 5.0 tree (aelkin:1.2541) BUG#29136Chuck Bell12 Oct