List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:June 22 2006 11:28am
Subject:bk commit into 5.1 tree (mats:1.2227) BUG#19995
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of mats. When mats 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.2227 06/06/22 13:28:04 mats@stripped +3 -0
  Patch to handle some bad situations resulting from the fix for BUG#19995.

  sql/sql_insert.cc
    1.205 06/06/22 13:27:43 mats@stripped +9 -35
    Adding member Open_tables:state::extra_lock to hold the extra lock used by select_create.
    Removing select_insert::lock.

  sql/sql_class.h
    1.301 06/06/22 13:27:43 mats@stripped +9 -4
    Adding member Open_tables:state::extra_lock to hold the extra lock used by select_create.
    Removing select_insert::lock.

  sql/handler.cc
    1.243 06/06/22 13:27:42 mats@stripped +28 -26
    Generating table maps from all locks that can be available: THD::extra_lock,
    THD::lock, and THD::locked_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:	mats
# Host:	romeo.(none)
# Root:	/home/bk/fix-mysql-5.1

--- 1.242/sql/handler.cc	2006-06-16 02:52:04 +02:00
+++ 1.243/sql/handler.cc	2006-06-22 13:27:42 +02:00
@@ -3263,37 +3263,39 @@
   int write_locked_table_maps(THD *thd)
   {
     DBUG_ENTER("write_locked_table_maps");
-    DBUG_PRINT("enter", ("thd=%p, thd->lock=%p, thd->locked_tables=%p",
-                         thd, thd->lock, thd->locked_tables));
+    DBUG_PRINT("enter", ("thd=%p, thd->lock=%p, thd->locked_tables=%p, thd->extra_lock",
+                         thd, thd->lock, thd->locked_tables, thd->extra_lock));
 
     if (thd->get_binlog_table_maps() == 0)
     {
-      /*
-        Exactly one table has to be locked, otherwise this code is not
-        guaranteed to work.
-      */
-      DBUG_ASSERT((thd->lock != NULL) + (thd->locked_tables != NULL) == 1);
-
-      MYSQL_LOCK *lock= thd->lock ? thd->lock : thd->locked_tables;
-      DBUG_ASSERT(lock->table_count > 0);
-      TABLE **const end_ptr= lock->table + lock->table_count;
-      for (TABLE **table_ptr= lock->table ; 
-           table_ptr != end_ptr ;
-           ++table_ptr)
+      MYSQL_LOCK *const locks[] = {
+        thd->extra_lock, thd->lock, thd->locked_tables
+      };
+      for (my_ptrdiff_t i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
       {
-        TABLE *const table= *table_ptr;
-        DBUG_PRINT("info", ("Checking table %s", table->s->table_name));
-        if (table->current_lock == F_WRLCK &&
-            check_table_binlog_row_based(thd, table))
+        MYSQL_LOCK const *const lock= locks[i];
+        if (lock == NULL)
+          continue;
+
+        TABLE **const end_ptr= lock->table + lock->table_count;
+        for (TABLE **table_ptr= lock->table ; 
+             table_ptr != end_ptr ;
+             ++table_ptr)
         {
-          int const has_trans= table->file->has_transactions();
-          int const error= thd->binlog_write_table_map(table, has_trans);
-          /*
-            If an error occurs, it is the responsibility of the caller to
-            roll back the transaction.
-          */
-          if (unlikely(error))
-            DBUG_RETURN(1);
+          TABLE *const table= *table_ptr;
+          DBUG_PRINT("info", ("Checking table %s", table->s->table_name));
+          if (table->current_lock == F_WRLCK &&
+              check_table_binlog_row_based(thd, table))
+          {
+            int const has_trans= table->file->has_transactions();
+            int const error= thd->binlog_write_table_map(table, has_trans);
+            /*
+              If an error occurs, it is the responsibility of the caller to
+              roll back the transaction.
+            */
+            if (unlikely(error))
+              DBUG_RETURN(1);
+          }
         }
       }
     }

--- 1.300/sql/sql_class.h	2006-06-19 12:14:22 +02:00
+++ 1.301/sql/sql_class.h	2006-06-22 13:27:43 +02:00
@@ -693,6 +693,14 @@
      THD::prelocked_mode for more info.)
   */
   MYSQL_LOCK *locked_tables;
+
+  /*
+    CREATE-SELECT keeps an extra lock for the table being
+    created. This field is used to keep the extra lock available for
+    lower level routines, which would otherwise miss that lock.
+   */
+  MYSQL_LOCK *extra_lock;
+
   /*
     prelocked_mode_type enum and prelocked_mode member are used for
     indicating whenever "prelocked mode" is on, and what type of
@@ -745,7 +753,7 @@
   void reset_open_tables_state()
   {
     open_tables= temporary_tables= handler_tables= derived_tables= 0;
-    lock= locked_tables= 0;
+    extra_lock= lock= locked_tables= 0;
     prelocked_mode= NON_PRELOCKED;
     state_flags= 0U;
   }
@@ -1591,9 +1599,6 @@
   bool send_eof();
   /* not implemented: select_insert is never re-used in prepared statements */
   void cleanup();
-
-protected:
-  MYSQL_LOCK *lock;
 };
 
 

--- 1.204/sql/sql_insert.cc	2006-06-21 13:51:07 +02:00
+++ 1.205/sql/sql_insert.cc	2006-06-22 13:27:43 +02:00
@@ -2188,7 +2188,6 @@
                              bool ignore_check_option_errors)
   :table_list(table_list_par), table(table_par), fields(fields_par),
    last_insert_id(0),
-   lock(0),
    insert_into_view(table_list_par && table_list_par->view != 0)
 {
   bzero((char*) &info,sizeof(info));
@@ -2356,6 +2355,7 @@
 {
   DBUG_ENTER("select_insert::send_data");
   bool error=0;
+
   if (unit->offset_limit_cnt)
   {						// using limit offset,count
     unit->offset_limit_cnt--;
@@ -2377,34 +2377,8 @@
     }
   }
 
-  /*
-    The thd->lock lock contain the locks for the select part of the
-    statement and the 'lock' variable contain the write lock for the
-    currently locked table that is being created or inserted
-    into. However, the row-based replication will investigate the
-    thd->lock to decide what table maps are to be written, so this one
-    has to contain the tables locked for writing.  To be able to write
-    table map for the table being created, we temporarily set
-    THD::lock to select_insert::lock while writing the record to the
-    storage engine. We cannot set this elsewhere, since the execution
-    of a stored function inside the select expression might cause the
-    lock structures to be NULL.
-   */
-  
-  {
-    MYSQL_LOCK *saved_lock= NULL;
-    if (lock)
-    {
-      saved_lock= thd->lock;
-      thd->lock= lock;
-    }
-
-    error= write_record(thd, table, &info);
+  error= write_record(thd, table, &info);
     
-    if (lock)
-      thd->lock= saved_lock;
-  }
-
   if (!error)
   {
     if (table->triggers || info.handle_duplicates == DUP_UPDATE)
@@ -2776,8 +2750,8 @@
 
   unit= u;
   if (!(table= create_table_from_items(thd, create_info, create_table,
-                                       extra_fields, keys, &values, &lock,
-                                       hook_ptr)))
+                                       extra_fields, keys, &values,
+                                       &thd->extra_lock, hook_ptr)))
     DBUG_RETURN(-1);				// abort() deletes table
 
   if (table->s->fields < values.elements)
@@ -2884,13 +2858,13 @@
   {
     table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
     VOID(pthread_mutex_lock(&LOCK_open));
-    mysql_unlock_tables(thd, lock);
+    mysql_unlock_tables(thd, thd->extra_lock);
     if (!table->s->tmp_table)
     {
       if (close_thread_table(thd, &table))
         VOID(pthread_cond_broadcast(&COND_refresh));
     }
-    lock=0;
+    thd->extra_lock=0;
     table=0;
     VOID(pthread_mutex_unlock(&LOCK_open));
   }
@@ -2900,10 +2874,10 @@
 void select_create::abort()
 {
   VOID(pthread_mutex_lock(&LOCK_open));
-  if (lock)
+  if (thd->extra_lock)
   {
-    mysql_unlock_tables(thd, lock);
-    lock=0;
+    mysql_unlock_tables(thd, thd->extra_lock);
+    thd->extra_lock=0;
   }
   if (table)
   {
Thread
bk commit into 5.1 tree (mats:1.2227) BUG#19995Mats Kindahl22 Jun