MySQL Lists are EOL. Please join:

List:Internals« Previous MessageNext Message »
From:Sasha Pachev Date:September 14 2005 12:31pm
Subject:bk commit into 4.1 tree (sasha:1.2409) BUG#11139
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of sasha. When sasha 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.2409 05/09/14 06:31:38 sasha@stripped +7 -0
  fix for BUG#11139 (multi-delete with alias breaking replication if table rules are
   present): the problem originally was that the tables in auxilliary_tables did not have 
  the correct real_name, which caused problems in the second call to tables_ok(). 
  The fix corrects the real_name problem, and also sets the updating flag properly, 
  which makes the second call to tables_ok() unnecessary.

  sql/sql_yacc.yy
    1.392 05/09/14 06:31:33 sasha@stripped +4 -6
    fix for BUG#11139 (multi-delete with alias breaking replication if table rules are
     present)

  sql/sql_parse.cc
    1.466 05/09/14 06:31:33 sasha@stripped +39 -11
    fix for BUG#11139 (multi-delete with alias breaking replication if table rules are
     present)

  sql/slave.cc
    1.276 05/09/14 06:31:33 sasha@stripped +1 -8
    fix for BUG#11139 (multi-delete with alias breaking replication if table rules are
     present)

  sql/mysql_priv.h
    1.367 05/09/14 06:31:32 sasha@stripped +2 -0
    fix for BUG#11139 (multi-delete with alias breaking replication if table rules are
     present)

  mysql-test/t/rpl_multi_delete2.test
    1.3 05/09/14 06:31:32 sasha@stripped +44 -1
    updates for for BUG#11139

  mysql-test/t/rpl_multi_delete2-slave.opt
    1.2 05/09/14 06:31:32 sasha@stripped +1 -1
    updates for for BUG#11139

  mysql-test/r/rpl_multi_delete2.result
    1.3 05/09/14 06:31:32 sasha@stripped +26 -3
    updates for for BUG#11139

# 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:	sasha
# Host:	mysql.sashanet.com
# Root:	/reiser-data/mysql-dev/mysql-4.1-bug11139

--- 1.366/sql/mysql_priv.h	2005-09-06 03:09:55 -06:00
+++ 1.367/sql/mysql_priv.h	2005-09-14 06:31:32 -06:00
@@ -59,6 +59,7 @@
 bool net_request_file(NET* net, const char* fname);
 char* query_table_status(THD *thd,const char *db,const char *table_name);
 
+
 #define x_free(A)	{ my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
 #define safeFree(x)	{ if(x) { my_free((gptr) x,MYF(0)); x = NULL; } }
 #define PREV_BITS(type,A)	((type) (((type) 1 << (A)) -1))
@@ -464,6 +465,7 @@
 bool mysql_new_select(LEX *lex, bool move_down);
 void create_select_for_variable(const char *var_name);
 void mysql_init_multi_delete(LEX *lex);
+void fix_multi_delete_lex(LEX* lex);
 void init_max_user_conn(void);
 void init_update_queries(void);
 void free_max_user_conn(void);

--- 1.275/sql/slave.cc	2005-08-08 15:13:46 -06:00
+++ 1.276/sql/slave.cc	2005-09-14 06:31:33 -06:00
@@ -746,14 +746,7 @@
     rules (see code below). For that reason, users should not set conflicting 
     rules because they may get unpredicted results (precedence order is
     explained in the manual).
-    If no table of the list is marked "updating" (so far this can only happen
-    if the statement is a multi-delete (SQLCOM_DELETE_MULTI) and the "tables"
-    is the tables in the FROM): then we always return 0, because there is no
-    reason we play this statement on this slave if it updates nothing. In the
-    case of SQLCOM_DELETE_MULTI, there will be a second call to tables_ok(),
-    with tables having "updating==TRUE" (those after the DELETE), so this
-    second call will make the decision (because
-    all_tables_not_ok() = !tables_ok(1st_list) && !tables_ok(2nd_list)).
+    
 
   RETURN VALUES
     0           should not be logged/replicated

--- 1.465/sql/sql_parse.cc	2005-09-06 12:38:48 -06:00
+++ 1.466/sql/sql_parse.cc	2005-09-14 06:31:33 -06:00
@@ -59,6 +59,9 @@
 static void refresh_status(void);
 static bool append_file_to_dir(THD *thd, const char **filename_ptr,
 			       const char *table_name);
+             
+static TABLE_LIST* get_table_by_alias(TABLE_LIST* tl, const char* db,
+  const char* alias);      
 
 const char *any_db="*any*";	// Special symbol for check_access
 
@@ -125,10 +128,7 @@
 */
 inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
 {
-  return (table_rules_on && tables && !tables_ok(thd,tables) &&
-          ((thd->lex->sql_command != SQLCOM_DELETE_MULTI) ||
-           !tables_ok(thd,
-		      (TABLE_LIST *)thd->lex->auxilliary_table_list.first)));
+  return (table_rules_on && tables && !tables_ok(thd,tables));
 }
 #endif
 
@@ -4248,6 +4248,40 @@
   DBUG_VOID_RETURN;
 }
 
+static TABLE_LIST* get_table_by_alias(TABLE_LIST* tl, const char* db,
+  const char* alias)
+{
+  for (;tl;tl= tl->next)
+  {
+    if (!strcmp(db,tl->db) &&
+        tl->alias && !my_strcasecmp(table_alias_charset,tl->alias,alias))
+      return tl;
+  }
+  
+  return 0;
+}     
+
+/* Sets up lex->auxilliary_table_list */
+void fix_multi_delete_lex(LEX* lex)
+{
+  TABLE_LIST *tl;
+  TABLE_LIST *good_list= (TABLE_LIST*)lex->select_lex.table_list.first;
+  
+  for (tl= (TABLE_LIST*)lex->auxilliary_table_list.first; tl; tl= tl->next)
+  {
+    TABLE_LIST* good_table= get_table_by_alias(good_list,tl->db,tl->alias);
+    if (good_table && !good_table->derived)
+    {
+      /* 
+          real_name points to a member of Table_ident which is
+          allocated via thd->strmake() from THD memroot 
+       */
+      tl->real_name= good_table->real_name;
+      tl->real_name_length= good_table->real_name_length;
+      good_table->updating= tl->updating;
+    }
+  }
+}  
 
 void mysql_init_multi_delete(LEX *lex)
 {
@@ -5570,13 +5604,7 @@
     (*table_count)++;
     /* All tables in aux_tables must be found in FROM PART */
     TABLE_LIST *walk;
-    for (walk= delete_tables; walk; walk= walk->next)
-    {
-      if (!my_strcasecmp(table_alias_charset,
-			 target_tbl->alias, walk->alias) &&
-	  !strcmp(walk->db, target_tbl->db))
-	break;
-    }
+    walk= get_table_by_alias(delete_tables,target_tbl->db,target_tbl->alias);
     if (!walk)
     {
       my_error(ER_UNKNOWN_TABLE, MYF(0), target_tbl->real_name,

--- 1.391/sql/sql_yacc.yy	2005-09-06 07:47:04 -06:00
+++ 1.392/sql/sql_yacc.yy	2005-09-14 06:31:33 -06:00
@@ -4295,12 +4295,10 @@
 	}
 	where_clause opt_order_clause
 	delete_limit_clause {}
-	| table_wild_list
-	  { mysql_init_multi_delete(Lex); }
-          FROM join_table_list where_clause
-	| FROM table_wild_list
-	  { mysql_init_multi_delete(Lex); }
-	  USING join_table_list where_clause
+	| table_wild_list {mysql_init_multi_delete(Lex);}
+          FROM join_table_list {fix_multi_delete_lex(Lex);} where_clause
+	| FROM table_wild_list { mysql_init_multi_delete(Lex);}
+	  USING join_table_list {fix_multi_delete_lex(Lex);} where_clause
 	  {}
 	;
 

--- 1.2/mysql-test/r/rpl_multi_delete2.result	2004-05-05 12:24:18 -06:00
+++ 1.3/mysql-test/r/rpl_multi_delete2.result	2005-09-14 06:31:32 -06:00
@@ -4,6 +4,26 @@
 reset slave;
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 start slave;
+set sql_log_bin=0;
+create database mysqltest_from;
+set sql_log_bin=1;
+create database mysqltest_to;
+use mysqltest_from;
+drop table if exists a;
+CREATE TABLE a (i INT);
+INSERT INTO a VALUES(1);
+DELETE alias FROM a alias WHERE alias.i=1;
+SELECT * FROM a;
+i
+insert into a values(2),(3);
+delete a alias FROM a alias where alias.i=2;
+select * from a;
+i
+3
+use mysqltest_to;
+select * from a;
+i
+3
 create table t1 (a int);
 create table t2 (a int);
 insert into t1 values (1);
@@ -15,7 +35,10 @@
 a
 1
 select * from t1;
-ERROR 42S02: Table 'test.t1' doesn't exist
+ERROR 42S02: Table 'mysqltest_to.t1' doesn't exist
 select * from t2;
-ERROR 42S02: Table 'test.t2' doesn't exist
-drop table t1,t2;
+ERROR 42S02: Table 'mysqltest_to.t2' doesn't exist
+set sql_log_bin=0;
+drop database mysqltest_from;
+set sql_log_bin=1;
+drop database mysqltest_to;

--- 1.1/mysql-test/t/rpl_multi_delete2-slave.opt	2004-04-13 14:40:11 -06:00
+++ 1.2/mysql-test/t/rpl_multi_delete2-slave.opt	2005-09-14 06:31:32 -06:00
@@ -1 +1 @@
---replicate-wild-ignore-table=test.%
+"--replicate-rewrite-db=mysqltest_from->mysqltest_to" --replicate-do-table=mysqltest_to.a

--- 1.2/mysql-test/t/rpl_multi_delete2.test	2005-07-27 18:21:48 -06:00
+++ 1.3/mysql-test/t/rpl_multi_delete2.test	2005-09-14 06:31:32 -06:00
@@ -1,4 +1,41 @@
+#multi delete replication bugs 
+
+
 source include/master-slave.inc;
+
+#BUG#11139 - improper wild-table and table rules
+#checking for multi deletes with an alias
+
+connection master;
+set sql_log_bin=0;
+create database mysqltest_from;
+set sql_log_bin=1;
+
+connection slave;
+create database mysqltest_to;
+
+
+connection master;
+use mysqltest_from;
+--disable_warnings
+drop table if exists a;
+--enable_warnings
+CREATE TABLE a (i INT);
+INSERT INTO a VALUES(1);
+DELETE alias FROM a alias WHERE alias.i=1;
+SELECT * FROM a;
+insert into a values(2),(3);
+delete a alias FROM a alias where alias.i=2;
+select * from a;
+save_master_pos;
+connection slave;
+
+use mysqltest_to;
+sync_with_master;
+select * from a;
+
+# BUG#3461
+connection master;
 create table t1 (a int);
 create table t2 (a int);
 
@@ -19,7 +56,13 @@
 error 1146;
 select * from t2;
 
+# cleanup
 connection master;
-drop table t1,t2;
+set sql_log_bin=0;
+drop database mysqltest_from;
+set sql_log_bin=1;
+connection slave;
+drop database mysqltest_to;
 
 # End of 4.1 tests
+
Thread
bk commit into 4.1 tree (sasha:1.2409) BUG#11139Sasha Pachev14 Sep