List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:June 29 2010 11:16am
Subject:bzr commit into mysql-trunk-runtime branch (kostja:3065) Bug#54811
View as plain text  
#At file:///opt/local/work/trunk-runtime-52114/ based on revid:jon.hauglid@stripped

 3065 Konstantin Osipov	2010-06-29
      A fix for Bug#54811 "Assert in mysql_lock_have_duplicate()".
      Remove mysql_lock_have_duplicate(), since now we always
      have TABLE_LIST objects for MyISAMMRG children
      in lex->query_tables and keep it till the end of the
      statement (sub-statement).
     @ sql/lock.cc
        Remove a function that is now unused.
     @ sql/lock.h
        Remove a function that is now unused.
     @ sql/sql_base.cc
        Don't try to search for duplicate table among THR_LOCK objects, TABLE_LIST list contains all used tables.

    modified:
      mysql-test/t/merge-big.test
      sql/lock.cc
      sql/lock.h
      sql/sql_base.cc
=== modified file 'mysql-test/t/merge-big.test'
--- a/mysql-test/t/merge-big.test	2009-12-02 23:09:22 +0000
+++ b/mysql-test/t/merge-big.test	2010-06-29 11:16:11 +0000
@@ -51,7 +51,7 @@ connection default;
 #--sleep 8
 #SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
 let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
-    WHERE ID = $con1_id AND STATE = 'Table lock';
+    WHERE ID = $con1_id AND STATE = 'Waiting for table';
 --source include/wait_condition.inc
 #SELECT NOW();
 --echo # Kick INSERT out of thr_multi_lock().
@@ -61,7 +61,7 @@ FLUSH TABLES;
 #--sleep 8
 #SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
 let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
-    WHERE ID = $con1_id AND STATE = 'Table lock';
+    WHERE ID = $con1_id AND STATE = 'Waiting for table';
 --source include/wait_condition.inc
 #SELECT NOW();
 --echo # Unlock and close table and wait for con1 to close too.

=== modified file 'sql/lock.cc'
--- a/sql/lock.cc	2010-06-11 15:28:18 +0000
+++ b/sql/lock.cc	2010-06-29 11:16:11 +0000
@@ -627,110 +627,6 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK 
 }
 
 
-/**
-  Find duplicate lock in tables.
-
-  Temporary tables are ignored here like they are ignored in
-  get_lock_data(). If we allow two opens on temporary tables later,
-  both functions should be checked.
-
-  @param thd                 The current thread.
-  @param needle              The table to check for duplicate lock.
-  @param haystack            The list of tables to search for the dup lock.
-
-  @note
-    This is mainly meant for MERGE tables in INSERT ... SELECT
-    situations. The 'real', underlying tables can be found only after
-    the MERGE tables are opened. This function assumes that the tables are
-    already locked.
-
-  @retval
-    NULL    No duplicate lock found.
-  @retval
-    !NULL   First table from 'haystack' that matches a lock on 'needle'.
-*/
-
-TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
-                                      TABLE_LIST *haystack)
-{
-  MYSQL_LOCK            *mylock;
-  TABLE                 **lock_tables;
-  TABLE                 *table;
-  TABLE                 *table2;
-  THR_LOCK_DATA         **lock_locks;
-  THR_LOCK_DATA         **table_lock_data;
-  THR_LOCK_DATA         **end_data;
-  THR_LOCK_DATA         **lock_data2;
-  THR_LOCK_DATA         **end_data2;
-  DBUG_ENTER("mysql_lock_have_duplicate");
-
-  /*
-    Table may not be defined for derived or view tables.
-    Table may not be part of a lock for delayed operations.
-  */
-  if (! (table= needle->table) || ! table->lock_count)
-    goto end;
-
-  /* A temporary table does not have locks. */
-  if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
-    goto end;
-
-  /* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
-  if (! (mylock= thd->lock))
-    goto end;
-
-  /* If we have less than two tables, we cannot have duplicates. */
-  if (mylock->table_count < 2)
-    goto end;
-
-  lock_locks=  mylock->locks;
-  lock_tables= mylock->table;
-
-  /* Prepare table related variables that don't change in loop. */
-  DBUG_ASSERT((table->lock_position < mylock->table_count) &&
-              (table == lock_tables[table->lock_position]));
-  table_lock_data= lock_locks + table->lock_data_start;
-  end_data= table_lock_data + table->lock_count;
-
-  for (; haystack; haystack= haystack->next_global)
-  {
-    if (haystack->placeholder())
-      continue;
-    table2= haystack->table;
-    if (table2->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
-      continue;
-
-    /* All tables in list must be in lock. */
-    DBUG_ASSERT((table2->lock_position < mylock->table_count) &&
-                (table2 == lock_tables[table2->lock_position]));
-
-    for (lock_data2=  lock_locks + table2->lock_data_start,
-           end_data2= lock_data2 + table2->lock_count;
-         lock_data2 < end_data2;
-         lock_data2++)
-    {
-      THR_LOCK_DATA **lock_data;
-      THR_LOCK *lock2= (*lock_data2)->lock;
-
-      for (lock_data= table_lock_data;
-           lock_data < end_data;
-           lock_data++)
-      {
-        if ((*lock_data)->lock == lock2)
-        {
-          DBUG_PRINT("info", ("haystack match: '%s'", haystack->table_name));
-          DBUG_RETURN(haystack);
-        }
-      }
-    }
-  }
-
- end:
-  DBUG_PRINT("info", ("no duplicate found"));
-  DBUG_RETURN(NULL);
-}
-
-
 /** Unlock a set of external. */
 
 static int unlock_external(THD *thd, TABLE **table,uint count)

=== modified file 'sql/lock.h'
--- a/sql/lock.h	2010-06-06 11:19:29 +0000
+++ b/sql/lock.h	2010-06-29 11:16:11 +0000
@@ -60,8 +60,6 @@ void mysql_lock_remove(THD *thd, MYSQL_L
 void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock);
 bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
 MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
-TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
-                                      TABLE_LIST *haystack);
 void broadcast_refresh(void);
 /* Lock based on name */
 bool lock_table_names(THD *thd, TABLE_LIST *table_list);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-06-25 07:07:18 +0000
+++ b/sql/sql_base.cc	2010-06-29 11:16:11 +0000
@@ -2008,8 +2008,7 @@ TABLE_LIST* unique_table(THD *thd, TABLE
       Table is unique if it is present only once in the global list
       of tables and once in the list of table locks.
     */
-    if (! (res= find_table_in_global_list(table_list, d_name, t_name)) &&
-        ! (res= mysql_lock_have_duplicate(thd, table, table_list)))
+    if (! (res= find_table_in_global_list(table_list, d_name, t_name)))
       break;
 
     /* Skip if same underlying table. */
@@ -3204,8 +3203,7 @@ bool open_table(THD *thd, TABLE_LIST *ta
   table_list->table= table;
   DBUG_ASSERT(table->key_read == 0);
   /* Tables may be reused in a sub statement. */
-  if (table->file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN))
-    table->file->extra(HA_EXTRA_DETACH_CHILDREN);
+  DBUG_ASSERT(! table->file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN));
   DBUG_RETURN(FALSE);
 
 err_lock:
@@ -5563,11 +5561,25 @@ bool open_normal_and_derived_tables(THD 
     or schema tables) as free for reuse.
 */
 
-static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
+static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table_list)
 {
-  for (; table; table= table->next_global)
+  TABLE_LIST *table;
+  for (table= table_list; table; table= table->next_global)
     if (!table->placeholder())
+    {
       table->table->query_id= 0;
+    }
+  for (table= table_list; table; table= table->next_global)
+    if (!table->placeholder())
+    {
+      /*
+        Detach children of MyISAMMRG tables used in
+        sub-statements, they will be reattached at open.
+        This has to be done in a separate loop to make sure
+        that children have had their query_id cleared.
+      */
+      table->table->file->extra(HA_EXTRA_DETACH_CHILDREN);
+    }
 }
 
 


Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20100629111611-pfdtq6dnuzvxr4an.bundle
Thread
bzr commit into mysql-trunk-runtime branch (kostja:3065) Bug#54811Konstantin Osipov29 Jun