List:Commits« Previous MessageNext Message »
From:Ingo Struewing Date:September 22 2007 9:08am
Subject:bk commit into 5.1 tree (istruewing:1.2610) BUG#26379
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of istruewing. When istruewing 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-09-22 11:08:21+02:00, istruewing@stripped +3 -0
  Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
  
  Not to be pushed. These are fixes on top of the second patch.
  They fix problems detected during first coarse review.

  mysql-test/r/merge.result@stripped, 2007-09-22 11:08:17+02:00, istruewing@stripped +20 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
    Added test result.

  mysql-test/t/merge.test@stripped, 2007-09-22 11:08:17+02:00, istruewing@stripped +14 -0
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
    Added tests.

  sql/sql_base.cc@stripped, 2007-09-22 11:08:17+02:00, istruewing@stripped +26 -13
    Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
    Fixed explicit use of MERGE child under LOCK TABLES when they have not been
    locked explicitly.
    Fixed dropping a locked MERGE table by detaching children first.
    Removed children list from open_tables() TABLE_LIST list regardless of the
    type of failure in open_table(). The list might be reused in any case.

diff -Nrup a/mysql-test/r/merge.result b/mysql-test/r/merge.result
--- a/mysql-test/r/merge.result	2007-09-12 22:11:44 +02:00
+++ b/mysql-test/r/merge.result	2007-09-22 11:08:17 +02:00
@@ -953,6 +953,20 @@ c1
 1
 2
 DROP TABLE t4;
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=FIRST SELECT * FROM t3;
+SHOW CREATE TABLE t4;
+Table	Create Table
+t4	CREATE TABLE `t4` (
+  `c1` int(11) DEFAULT NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`,`t2`)
+SELECT * FROM t4;
+c1
+1
+2
+1
+2
+DROP TABLE t4;
 LOCK TABLES t1 WRITE, t2 WRITE, t3 READ;
 CREATE TABLE t4 (c1 INT);
 DROP TABLE t4;
@@ -961,6 +975,12 @@ ERROR HY000: Table 't4' was not locked w
 CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
 INSERT_METHOD=LAST SELECT * FROM t3;
 ERROR HY000: Table 't4' was not locked with LOCK TABLES
+UNLOCK TABLES;
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
+LOCK TABLES t4 READ;
+SELECT * from t1, t4;
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+DROP TABLE t4;
 UNLOCK TABLES;
 DROP TABLE t1, t2, t3;
 CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
diff -Nrup a/mysql-test/t/merge.test b/mysql-test/t/merge.test
--- a/mysql-test/t/merge.test	2007-09-12 22:11:44 +02:00
+++ b/mysql-test/t/merge.test	2007-09-22 11:08:17 +02:00
@@ -676,11 +676,18 @@ CREATE TABLE t1 (c1 INT);
 CREATE TABLE t2 (c1 INT);
 CREATE TABLE t3 (c1 INT);
 INSERT INTO t3 VALUES (1), (2);
+# Show that LAST table is opened.
 CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
   INSERT_METHOD=LAST SELECT * FROM t3;
 SHOW CREATE TABLE t4;
 SELECT * FROM t4;
 DROP TABLE t4;
+# Show that FIRST table is opened.
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+  INSERT_METHOD=FIRST SELECT * FROM t3;
+SHOW CREATE TABLE t4;
+SELECT * FROM t4;
+DROP TABLE t4;
 LOCK TABLES t1 WRITE, t2 WRITE, t3 READ;
 CREATE TABLE t4 (c1 INT);
 DROP TABLE t4;
@@ -689,6 +696,13 @@ CREATE TABLE t4 (c1 INT) SELECT * FROM t
 --error ER_TABLE_NOT_LOCKED
 CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
   INSERT_METHOD=LAST SELECT * FROM t3;
+UNLOCK TABLES;
+CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
+LOCK TABLES t4 READ;
+--error ER_TABLE_NOT_LOCKED
+SELECT * from t1, t4;
+# Show that dropping a lcked MERGE table works.
+DROP TABLE t4;
 UNLOCK TABLES;
 DROP TABLE t1, t2, t3;
 
diff -Nrup a/sql/sql_base.cc b/sql/sql_base.cc
--- a/sql/sql_base.cc	2007-09-12 22:11:44 +02:00
+++ b/sql/sql_base.cc	2007-09-22 11:08:17 +02:00
@@ -1850,6 +1850,7 @@ void close_temporary(TABLE *table, bool 
   DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
                           table->s->db.str, table->s->table_name.str));
 
+  /* Detach MERGE children, but do not clear references. It's deleted anyway. */
   if (table->child_l)
     detach_merge_children(table, FALSE);
   free_io_cache(table);
@@ -2437,9 +2438,14 @@ TABLE *open_table(THD *thd, TABLE_LIST *
                    table->s->table_name.str);
           DBUG_RETURN(0);
         }
+        /*
+          When looking for a usable TABLE, ignore MERGE children, as they
+          belong to their parent and cannot be used explicitly.
+        */
         if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
             table->query_id != thd->query_id && /* skip tables already used */
-            !(thd->prelocked_mode && table->query_id))
+            !(thd->prelocked_mode && table->query_id) &&
+            !table->parent)
         {
           int distance= ((int) table->reginfo.lock_type -
                          (int) table_list->lock_type);
@@ -3419,6 +3425,12 @@ TABLE *drop_locked_tables(THD *thd,const
         if (table->db_stat)
         {
           table->db_stat= 0;
+          /*
+            When closing a MERGE parent table, detach its children first.
+            Clear child table references in case this object is opened again.
+          */
+          if (table->child_l)
+            detach_merge_children(table, TRUE);
           table->file->close();
         }
       }
@@ -4009,6 +4021,19 @@ int open_tables(THD *thd, TABLE_LIST **s
 	goto process_view_routines;
       }
 
+      /*
+        If in a MERGE table open, we need to remove the children list
+        from statement table list before restarting. Otherwise the list
+        will be inserted another time.
+      */
+      if (tables->parent_l)
+      {
+        TABLE_LIST *parent_l= tables->parent_l;
+        /* The parent table should be correctly open at this point. */
+        DBUG_ASSERT(parent_l->table);
+        parent_l->next_global= *parent_l->table->child_last_l;
+      }
+
       if (refresh)				// Refresh in progress
       {
         /*
@@ -4027,18 +4052,6 @@ int open_tables(THD *thd, TABLE_LIST **s
         */
         if (query_tables_last_own)
           thd->lex->mark_as_requiring_prelocking(query_tables_last_own);
-        /*
-          If in a MERGE table open, we need to remove the children list
-          from statement table list before restarting. Otherwise the list
-          will be inserted another time.
-        */
-        if (tables->parent_l)
-        {
-          TABLE_LIST *parent_l= tables->parent_l;
-          /* The parent table should be correctly open at this point. */
-          DBUG_ASSERT(parent_l->table);
-          parent_l->next_global= *parent_l->table->child_last_l;
-        }
         close_tables_for_reopen(thd, start);
 	goto restart;
       }
Thread
bk commit into 5.1 tree (istruewing:1.2610) BUG#26379Ingo Struewing22 Sep