MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:March 23 2007 7:56pm
Subject:bk commit into 5.0 tree (aelkin:1.2491) BUG#23333
View as plain text  
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-03-23 21:54:11+02:00, aelkin@andrepl.(none) +7 -0
  Bug #23333  	stored function + non-transac table + transac table = breaks stmt-based binlog
  Bug #13270  	INSERT,UPDATE,etc that calls func with side-effect does not go into binlog
  
  The query was not binlogged if top-level table was transactional or unmodified while
  implicitly involved via stored function  non-ta table was modified.
  
  Fixed with checking thd->no_trans_update.all flag (refactored after thd->options' 
  OPTION_STATUS_NO_TRANS_UPDATE eliminated in
  Bug#27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF)
  at binlog recording time, and regardless of whether top level table got modified or not the query
  gets binlogged if the flag was set.
  
  
  

  mysql-test/r/sp_trans.result@stripped, 2007-03-23 21:54:09+02:00, aelkin@andrepl.(none) +73 -14
    results changed

  mysql-test/t/sp_trans.test@stripped, 2007-03-23 21:54:09+02:00, aelkin@andrepl.(none) +44 -3
    regression tests for bugs

  sql/mysql_priv.h@stripped, 2007-03-23 21:54:09+02:00, aelkin@andrepl.(none) +0 -3
    removal, as part of Bug#27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF()

  sql/sql_delete.cc@stripped, 2007-03-23 21:54:09+02:00, aelkin@andrepl.(none) +9 -7
    binlogging even if not updated because of modified non-ta tables

  sql/sql_insert.cc@stripped, 2007-03-23 21:54:10+02:00, aelkin@andrepl.(none) +16 -14
    binlogging even if not updated because of modified non-ta tables

  sql/sql_load.cc@stripped, 2007-03-23 21:54:10+02:00, aelkin@andrepl.(none) +11 -10
    binlogging even if not updated because of modified non-ta tables

  sql/sql_update.cc@stripped, 2007-03-23 21:54:10+02:00, aelkin@andrepl.(none) +6 -4
    binlogging even if not updated because of modified non-ta tables

# 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:	aelkin
# Host:	andrepl.(none)
# Root:	/home/elkin/MySQL/MAIN/5.0-marvel-bug23333_sf_side_eff_binlog

--- 1.438/sql/mysql_priv.h	2007-03-16 10:47:51 +02:00
+++ 1.439/sql/mysql_priv.h	2007-03-23 21:54:09 +02:00
@@ -347,9 +347,6 @@ MY_LOCALE *my_locale_by_number(uint numb
    in the user query has requested */
 #define SELECT_ALL              (ULL(1) << 24)    // SELECT, user, parser
 
-/* Set if we are updating a non-transaction safe table */
-#define OPTION_STATUS_NO_TRANS_UPDATE   (ULL(1) << 25) // THD, intern
-
 /* The following can be set when importing tables in a 'wrong order'
    to suppress foreign key checks */
 #define OPTION_NO_FOREIGN_KEY_CHECKS    (ULL(1) << 26) // THD, user, binlog

--- 1.194/sql/sql_delete.cc	2007-03-23 17:12:56 +02:00
+++ 1.195/sql/sql_delete.cc	2007-03-23 21:54:09 +02:00
@@ -299,7 +299,8 @@ cleanup:
   delete select;
   transactional_table= table->file->has_transactions();
   /* See similar binlogging code in sql_update.cc, for comments */
-  if ((error < 0) || (deleted && !transactional_table))
+  if ((error < 0) || (deleted && !transactional_table) ||
+      thd->no_trans_update.all)
   {
     if (mysql_bin_log.is_open())
     {
@@ -308,7 +309,7 @@ cleanup:
       Query_log_event qinfo(thd, thd->query, thd->query_length,
 			    transactional_table, FALSE);
       if (mysql_bin_log.write(&qinfo) && transactional_table)
-	error=1;
+        error=1;
     }
     if (!transactional_table)
       thd->no_trans_update.all= TRUE;
@@ -779,7 +780,8 @@ bool multi_delete::send_eof()
     query_cache_invalidate3(thd, delete_tables, 1);
   }
 
-  if ((local_error == 0) || (deleted && normal_tables))
+  if ((local_error == 0) || (deleted && normal_tables) ||
+      thd->no_trans_update.all)
   {
     if (mysql_bin_log.is_open())
     {
@@ -788,7 +790,7 @@ bool multi_delete::send_eof()
       Query_log_event qinfo(thd, thd->query, thd->query_length,
 			    transactional_tables, FALSE);
       if (mysql_bin_log.write(&qinfo) && !normal_tables)
-	local_error=1;  // Log write failed: roll back the SQL statement
+        local_error=1;  // Log write failed: roll back the SQL statement
     }
     if (!transactional_tables)
       thd->no_trans_update.all= TRUE;
@@ -891,9 +893,9 @@ end:
       if (mysql_bin_log.is_open())
       {
         thd->clear_error();
-	Query_log_event qinfo(thd, thd->query, thd->query_length,
-			      0, FALSE);
-	mysql_bin_log.write(&qinfo);
+        Query_log_event qinfo(thd, thd->query, thd->query_length,
+                              0, FALSE);
+        mysql_bin_log.write(&qinfo);
       }
       send_ok(thd);		// This should return record count
     }

--- 1.226/sql/sql_insert.cc	2007-03-23 17:12:56 +02:00
+++ 1.227/sql/sql_insert.cc	2007-03-23 21:54:10 +02:00
@@ -719,20 +719,21 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
         before binlog writing and ha_autocommit_or_rollback
       */
       query_cache_invalidate3(thd, table_list, 1);
-      if (error <= 0 || !transactional_table)
+    }
+    if (changed && (error <= 0 || !transactional_table) ||
+        thd->no_trans_update.all)
+    {
+      if (mysql_bin_log.is_open())
       {
-        if (mysql_bin_log.is_open())
-        {
-          if (error <= 0)
-            thd->clear_error();
-          Query_log_event qinfo(thd, thd->query, thd->query_length,
-                                transactional_table, FALSE);
-          if (mysql_bin_log.write(&qinfo) && transactional_table)
-            error=1;
-        }
-        if (!transactional_table)
-          thd->no_trans_update.all= TRUE;
+        if (error <= 0)
+          thd->clear_error();
+        Query_log_event qinfo(thd, thd->query, thd->query_length,
+                              transactional_table, FALSE);
+        if (mysql_bin_log.write(&qinfo) && transactional_table)
+          error=1;
       }
+      if (!transactional_table)
+        thd->no_trans_update.all= TRUE;
     }
     if (transactional_table)
       error=ha_autocommit_or_rollback(thd,error);
@@ -2665,7 +2666,8 @@ void select_insert::send_error(uint errc
     the error code will make the slave stop).
   */
   if ((info.copied || info.deleted || info.updated) &&
-      !table->file->has_transactions())
+      !table->file->has_transactions() ||
+      thd->no_trans_update.all)
   {
     if (last_insert_id)
       thd->insert_id(last_insert_id);		// For binary log
@@ -2716,7 +2718,7 @@ bool select_insert::send_eof()
     if (!error)
       thd->clear_error();
     Query_log_event qinfo(thd, thd->query, thd->query_length,
-			  table->file->has_transactions(), FALSE);
+                          table->file->has_transactions(), FALSE);
     mysql_bin_log.write(&qinfo);
   }
   if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)

--- 1.110/sql/sql_load.cc	2007-03-23 17:12:56 +02:00
+++ 1.111/sql/sql_load.cc	2007-03-23 21:54:10 +02:00
@@ -419,8 +419,8 @@ bool mysql_load(THD *thd,sql_exchange *e
 
     if (read_file_from_client)
       while (!read_info.next_line())
-	;
-
+        ;
+    
 #ifndef EMBEDDED_LIBRARY
     if (mysql_bin_log.is_open())
     {
@@ -449,14 +449,15 @@ bool mysql_load(THD *thd,sql_exchange *e
       /* If the file was not empty, wrote_create_file is true */
       if (lf_info.wrote_create_file)
       {
-	if ((info.copied || info.deleted) && !transactional_table)
-	  write_execute_load_query_log_event(thd, handle_duplicates,
-					     ignore, transactional_table);
-	else
-	{
-	  Delete_file_log_event d(thd, db, transactional_table);
-	  mysql_bin_log.write(&d);
-	}
+        if ((info.copied || info.deleted) && !transactional_table ||
+            thd->no_trans_update.all)
+          write_execute_load_query_log_event(thd, handle_duplicates,
+                                             ignore, transactional_table);
+        else
+        {
+          Delete_file_log_event d(thd, db, transactional_table);
+          mysql_bin_log.write(&d);
+        }
       }
     }
 #endif /*!EMBEDDED_LIBRARY*/

--- 1.213/sql/sql_update.cc	2007-03-23 17:12:56 +02:00
+++ 1.214/sql/sql_update.cc	2007-03-23 21:54:10 +02:00
@@ -534,16 +534,17 @@ int mysql_update(THD *thd,
     Sometimes we want to binlog even if we updated no rows, in case user used
     it to be sure master and slave are in same state.
   */
-  if ((error < 0) || (updated && !transactional_table))
+  if ((error < 0) || (updated && !transactional_table) ||
+      thd->no_trans_update.all)
   {
     if (mysql_bin_log.is_open())
     {
       if (error < 0)
         thd->clear_error();
       Query_log_event qinfo(thd, thd->query, thd->query_length,
-			    transactional_table, FALSE);
+                            transactional_table, FALSE);
       if (mysql_bin_log.write(&qinfo) && transactional_table)
-	error=1;				// Rollback update
+        error=1;				// Rollback update
     }
     if (!transactional_table)
       thd->no_trans_update.all= TRUE;
@@ -1532,7 +1533,8 @@ bool multi_update::send_eof()
     transactional tables.
   */
 
-  if ((local_error == 0) || (updated && !trans_safe))
+  if ((local_error == 0) || (updated && !trans_safe) ||
+      thd->no_trans_update.all)
   {
     if (mysql_bin_log.is_open())
     {

--- 1.10/mysql-test/r/sp_trans.result	2007-03-23 17:12:55 +02:00
+++ 1.11/mysql-test/r/sp_trans.result	2007-03-23 21:54:09 +02:00
@@ -531,10 +531,10 @@ drop table t3, t4|
 drop procedure bug14210|
 set @@session.max_heap_table_size=default|
 drop function if exists bug23333|
-drop table if exists t1,t2|
+drop table if exists t1,t2,t3,t4|
 CREATE TABLE t1 (a int  NOT NULL auto_increment primary key) ENGINE=MyISAM|
 CREATE TABLE t2 (a int  NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
-reset master|
+CREATE TABLE t3 (a int  NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
 insert into t2 values (1,1)|
 create function bug23333() 
 RETURNS int(11)
@@ -544,21 +544,80 @@ insert into t1 values (null);
 select count(*) from t1 into @a;
 return @a;
 end|
+reset master|
 insert into t2 values (bug23333(),1)|
 ERROR 23000: Duplicate entry '1' for key 1
-show binlog events /* must show the insert */|
+show binlog events from 98/* must show the insert */|
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	4	Format_desc	1	98	Server ver: 5.0.40-debug-log, Binlog ver: 4
-master-bin.000001	98	Query	1	90	use `test`; insert into t2 values (1,1)
-master-bin.000001	188	Xid	1	215	COMMIT /* xid=1165 */
-master-bin.000001	215	Query	1	446	use `test`; CREATE DEFINER=`root`@`localhost` function bug23333() 
-RETURNS int(11)
-DETERMINISTIC
-begin
-insert into t1 values (null);
-select count(*) from t1 into @a;
-return @a;
-end
+master-bin.000001	98	User var	1	42	@`a`=1
+master-bin.000001	140	Query	1	149	use `test`; insert into t2 values (bug23333(),1)
+master-bin.000001	247	Query	1	326	use `test`; ROLLBACK
 select count(*),@a from t1 /* must be 1,1 */|
 count(*)	@a
 1	1
+insert into t2 values (2,2)|
+update t2 set a= 1 where b = bug23333()+100 /* no records updated in t2 */|
+affected rows: 0
+info: Rows matched: 0  Changed: 0  Warnings: 0
+select count(*),@a from t1 /* must be 3,3 */|
+count(*)	@a
+3	3
+select count(*) from t2 /* nothing changed -> 2 records */|
+count(*)
+2
+delete from t2 where b = bug23333()+100 /* no record deleted in t2 */|
+affected rows: 0
+update t2,t3 set t2.a= 1 where t2.b = bug23333()+100 /* no updated rows */|
+affected rows: 0
+info: Rows matched: 0  Changed: 0  Warnings: 0
+insert into t3 values (1,1)|
+delete t2,t3 from t2,t3 where t2.b = bug23333() and t3.b = 0 /* no deleted rows */|
+affected rows: 0
+delete from t1 /* reset the function to return 1 at next call */|
+insert into t3 select bug23333(),bug23333() /* nothing must be inserted into t3 */|
+ERROR 23000: Duplicate entry '1' for key 1
+select count(*) from t3 /* must return 1 */|
+count(*)
+1
+delete from t1 /* reset the function to return 1 at next call */|
+create table t4 (a int default 0, b int primary key) engine=innodb|
+insert into t4 values (0, 17)|
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug23333()|
+ERROR 23000: Duplicate entry '17' for key 1
+select * from t4|
+a	b
+0	17
+select count(*) from t1 /* must be 2 */|
+count(*)
+2
+show binlog events from 98 /* must show inserts, updates, deletes */|
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	98	User var	1	42	@`a`=1
+master-bin.000001	140	Query	1	149	use `test`; insert into t2 values (bug23333(),1)
+master-bin.000001	247	Query	1	326	use `test`; ROLLBACK
+master-bin.000001	326	Query	1	90	use `test`; insert into t2 values (2,2)
+master-bin.000001	416	Xid	1	443	COMMIT /* xid=1174 */
+master-bin.000001	443	User var	1	42	@`a`=2
+master-bin.000001	485	Query	1	179	use `test`; update t2 set a= 1 where b = bug23333()+100 /* no records updated in t2 */
+master-bin.000001	622	Xid	1	649	COMMIT /* xid=1175 */
+master-bin.000001	649	User var	1	42	@`a`=4
+master-bin.000001	691	Query	1	174	use `test`; delete from t2 where b = bug23333()+100 /* no record deleted in t2 */
+master-bin.000001	823	Xid	1	850	COMMIT /* xid=1184 */
+master-bin.000001	850	Query	1	137	use `test`; update t2,t3 set t2.a= 1 where t2.b = bug23333()+100 /* no updated rows */
+master-bin.000001	987	Xid	1	1014	COMMIT /* xid=1191 */
+master-bin.000001	1014	Query	1	90	use `test`; insert into t3 values (1,1)
+master-bin.000001	1104	Xid	1	1131	COMMIT /* xid=1192 */
+master-bin.000001	1131	Query	1	145	use `test`; delete t2,t3 from t2,t3 where t2.b = bug23333() and t3.b = 0 /* no deleted rows */
+master-bin.000001	1276	Xid	1	1303	COMMIT /* xid=1193 */
+master-bin.000001	1303	Query	1	1430	use `test`; delete from t1 /* reset the function to return 1 at next call */
+master-bin.000001	1430	User var	1	42	@`a`=1
+master-bin.000001	1472	Query	1	187	use `test`; insert into t3 select bug23333(),bug23333() /* nothing must be inserted into t3 */
+master-bin.000001	1617	Query	1	1688	use `test`; ROLLBACK
+master-bin.000001	1688	Query	1	1815	use `test`; delete from t1 /* reset the function to return 1 at next call */
+master-bin.000001	1815	Query	1	1944	use `test`; create table t4 (a int default 0, b int primary key) engine=innodb
+master-bin.000001	1944	Query	1	92	use `test`; insert into t4 values (0, 17)
+master-bin.000001	2036	Xid	1	2063	COMMIT /* xid=1205 */
+master-bin.000001	2063	User var	1	42	@`a`=1
+master-bin.000001	2105	Begin_load_query	1	77	;file_id=1;block_len=12
+master-bin.000001	2140	User var	1	119	@`a`=1
+master-bin.000001	2182	Execute_load_query	1	290	use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug23333() ;file_id=1

--- 1.10/mysql-test/t/sp_trans.test	2007-03-23 17:12:55 +02:00
+++ 1.11/mysql-test/t/sp_trans.test	2007-03-23 21:54:09 +02:00
@@ -561,12 +561,12 @@ set @@session.max_heap_table_size=defaul
 #
 --disable_warnings
 drop function if exists bug23333|
-drop table if exists t1,t2|
+drop table if exists t1,t2,t3,t4|
 --enable_warnings
  CREATE TABLE t1 (a int  NOT NULL auto_increment primary key) ENGINE=MyISAM|
  CREATE TABLE t2 (a int  NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
+ CREATE TABLE t3 (a int  NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
 
-reset master|
 insert into t2 values (1,1)|
 
 create function bug23333() 
@@ -578,10 +578,51 @@ begin
   return @a;
 end|
 
+reset master|
+
 --error ER_DUP_ENTRY
 insert into t2 values (bug23333(),1)| 
-show binlog events /* must show the insert */|
+show binlog events from 98/* must show the insert */|
 select count(*),@a from t1 /* must be 1,1 */|
+
+insert into t2 values (2,2)|
+--enable_info
+update t2 set a= 1 where b = bug23333()+100 /* no records updated in t2 */|
+--disable_info
+select count(*),@a from t1 /* must be 3,3 */|
+select count(*) from t2 /* nothing changed -> 2 records */|
+
+
+--enable_info
+delete from t2 where b = bug23333()+100 /* no record deleted in t2 */|
+--disable_info
+
+--enable_info
+update t2,t3 set t2.a= 1 where t2.b = bug23333()+100 /* no updated rows */|
+--disable_info
+
+insert into t3 values (1,1)|
+--enable_info
+delete t2,t3 from t2,t3 where t2.b = bug23333() and t3.b = 0 /* no deleted rows */|
+--disable_info
+
+delete from t1 /* reset the function to return 1 at next call */|
+--enable_info
+--error ER_DUP_ENTRY
+insert into t3 select bug23333(),bug23333() /* nothing must be inserted into t3 */|
+--disable_info
+select count(*) from t3 /* must return 1 */|
+
+delete from t1 /* reset the function to return 1 at next call */|
+create table t4 (a int default 0, b int primary key) engine=innodb|
+insert into t4 values (0, 17)|
+--error ER_DUP_ENTRY
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug23333()|
+select * from t4|
+select count(*) from t1 /* must be 2 */|
+
+show binlog events from 98 /* must show inserts, updates, deletes */|
+
 
 #
 # BUG#NNNN: New bug synopsis
Thread
bk commit into 5.0 tree (aelkin:1.2491) BUG#23333Andrei Elkin23 Mar