List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:June 6 2008 1:27pm
Subject:bzr commit into mysql-6.0 branch (konstantin:2662) WL#3726
View as plain text  
#At file:///opt/local/work/mysql-6.0-prelocked_mode/

 2662 Konstantin Osipov	2008-06-06
      WL#3726: work on review comments.
      Remove thd->locked_tables. Always store MYSQL_LOCK instances in
      thd->lock. Use thd->prelocked_mode to determine if we 
      are under LOCK TABLES. Update the code to not assume that 
      if thd->lock is set, LOCK TABLES mode is off.
      Remove dead code in lock_tables() that would set thd->in_lock_tables
      and OPTION_LOCK_TABLES when locking tables for pre-locking.
modified:
  sql/ha_ndbcluster_binlog.cc
  sql/handler.cc
  sql/lock.cc
  sql/set_var.cc
  sql/sql_base.cc
  sql/sql_cache.cc
  sql/sql_class.cc
  sql/sql_class.h
  sql/sql_insert.cc
  sql/sql_parse.cc
  sql/sql_partition.cc
  sql/sql_rename.cc
  sql/sql_select.cc
  sql/sql_table.cc
  sql/sql_trigger.cc
  sql/sql_update.cc
  sql/sql_view.cc
  storage/myisam/ha_myisam.cc

per-file comments:
  sql/ha_ndbcluster_binlog.cc
    Don't unlock the lock under LOCK TABLES.
  sql/handler.cc
    There is no thd->locked_tables any more.
  sql/lock.cc
    There is no thd->locked_tables any more.
  sql/set_var.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_base.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
    Remove thd->locked_tables.
    Remove dead (checked with engines sources) code that tries to pretend
    that pre-locking is the same thing as LOCK TABLES. OPTION_TABLE_LOCK
    is not used in any engine. For thd->in_lock_tables most engines
    developed a workaround to only pay attention to it if 
    thd->sql_command is SQLCOM_LOCK_TABLES.
  sql/sql_cache.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_class.cc
    Avoid code duplication.
    Do not release the table locks prematurely if we're under LOCK TABLES.
    thd->locked_tables is removed.
  sql/sql_class.h
    Remove thd->locked_tables.
    Add a new mode to prelocked_mode: LOCK_TABLES. This mode is
    in power when a user issued explicit LOCK TABLES.
  sql/sql_insert.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_parse.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
    Remove thd->locked_tables.
  sql/sql_partition.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_rename.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_select.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_table.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_trigger.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_update.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  sql/sql_view.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
  storage/myisam/ha_myisam.cc
    Use thd->prelocked_mode to determine if we are under LOCK TABLES.
=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2008-06-03 17:41:59 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2008-06-06 11:27:03 +0000
@@ -2625,8 +2625,11 @@ ndb_add_ndb_binlog_index(THD *thd, ndb_b
     }
   } while (row);
 
-  mysql_unlock_tables(thd, thd->lock);
-  thd->lock= 0;
+  if (! thd->prelocked_mode)
+  {
+    mysql_unlock_tables(thd, thd->lock);
+    thd->lock= 0;
+  }
   thd->options= saved_options;
   return 0;
 add_ndb_binlog_index_err:

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2008-05-27 10:44:38 +0000
+++ b/sql/handler.cc	2008-06-06 11:27:03 +0000
@@ -5182,17 +5182,14 @@ static bool check_table_binlog_row_based
 static 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->extra_lock: %p",
-                       thd, thd->lock,
-                       thd->locked_tables, thd->extra_lock));
+  DBUG_PRINT("enter", ("thd: %p  thd->lock: %p thd->extra_lock: %p",
+                       thd, thd->lock, thd->extra_lock));
 
   if (thd->get_binlog_table_maps() == 0)
   {
-    MYSQL_LOCK *locks[3];
+    MYSQL_LOCK *locks[2];
     locks[0]= thd->extra_lock;
     locks[1]= thd->lock;
-    locks[2]= thd->locked_tables;
     for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
     {
       MYSQL_LOCK const *const lock= locks[i];

=== modified file 'sql/lock.cc'
--- a/sql/lock.cc	2008-06-03 17:07:58 +0000
+++ b/sql/lock.cc	2008-06-06 11:27:03 +0000
@@ -739,7 +739,7 @@ TABLE_LIST *mysql_lock_have_duplicate(TH
     goto end;
 
   /* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
-  if (! (mylock= thd->lock ? thd->lock : thd->locked_tables))
+  if (! (mylock= thd->lock))
     goto end;
 
   /* If we have less than two tables, we cannot have duplicates. */

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2008-05-23 13:54:03 +0000
+++ b/sql/set_var.cc	2008-06-06 11:27:03 +0000
@@ -4005,7 +4005,7 @@ bool sys_var_opt_readonly::update(THD *t
   DBUG_ENTER("sys_var_opt_readonly::update");
 
   /* Prevent self dead-lock */
-  if (thd->locked_tables || thd->active_transaction())
+  if (thd->prelocked_mode || thd->active_transaction())
   {
     my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
     DBUG_RETURN(true);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2008-06-05 15:33:38 +0000
+++ b/sql/sql_base.cc	2008-06-06 11:27:03 +0000
@@ -1001,7 +1001,7 @@ bool close_cached_tables(THD *thd, TABLE
   DBUG_ASSERT(!have_lock);
   pthread_mutex_unlock(&LOCK_open);
 
-  if (thd->locked_tables)
+  if (thd->prelocked_mode)
   {
     /*
       If we are under LOCK TABLES we need to reopen tables without
@@ -1115,7 +1115,7 @@ bool close_cached_tables(THD *thd, TABLE
   }
 
 err_with_reopen:
-  if (thd->locked_tables)
+  if (thd->prelocked_mode)
   {
     pthread_mutex_lock(&LOCK_open);
     /*
@@ -1328,7 +1328,6 @@ void close_thread_tables(THD *thd,
                          bool skip_mdl)
 {
   TABLE *table;
-  prelocked_mode_type prelocked_mode= thd->prelocked_mode;
   DBUG_ENTER("close_thread_tables");
 
 #ifdef EXTRA_DEBUG
@@ -1386,11 +1385,12 @@ void close_thread_tables(THD *thd,
       Reset transaction state, but only if we're not inside a
       sub-statement of a prelocked statement.
     */
-    if (! prelocked_mode || thd->lex->requires_prelocking())
+    if (! thd->prelocked_mode || thd->prelocked_mode == LOCK_TABLES ||
+        thd->lex->requires_prelocking())
       thd->transaction.stmt.reset();
   }
 
-  if (thd->locked_tables || prelocked_mode)
+  if (thd->prelocked_mode)
   {
 
     /* Ensure we are calling ha_reset() for all used tables */
@@ -1400,7 +1400,7 @@ void close_thread_tables(THD *thd,
       We are under simple LOCK TABLES or we're inside a sub-statement
       of a prelocked statement, so should not do anything else.
     */
-    if (!prelocked_mode || !thd->lex->requires_prelocking())
+    if (! thd->lex->requires_prelocking())
       DBUG_VOID_RETURN;
 
     /*
@@ -1408,18 +1408,18 @@ void close_thread_tables(THD *thd,
       so we have to leave the prelocked mode now with doing implicit
       UNLOCK TABLES if needed.
     */
-    DBUG_PRINT("info",("thd->prelocked_mode= NON_PRELOCKED"));
-    thd->prelocked_mode= NON_PRELOCKED;
+    if (thd->prelocked_mode == PRELOCKED_UNDER_LOCK_TABLES)
+      thd->prelocked_mode= LOCK_TABLES;
 
-    if (prelocked_mode == PRELOCKED_UNDER_LOCK_TABLES)
+    if (thd->prelocked_mode == LOCK_TABLES)
       DBUG_VOID_RETURN;
 
+    thd->prelocked_mode= NON_PRELOCKED;
+
     /*
       Note that we are leaving prelocked mode so we don't need
       to care about THD::locked_tables_root.
     */
-    thd->lock= thd->locked_tables;
-    thd->locked_tables= 0;
     /* Fallthrough */
   }
 
@@ -1454,16 +1454,6 @@ void close_thread_tables(THD *thd,
     mdl_remove_all_locks(&thd->mdl_context);
   }
 
-  if (prelocked_mode == PRELOCKED)
-  {
-    /*
-      If we are here then we are leaving normal prelocked mode, so it is
-      good idea to turn off OPTION_TABLE_LOCK flag.
-    */
-    DBUG_ASSERT(thd->lex->requires_prelocking());
-    thd->options&= ~(OPTION_TABLE_LOCK);
-  }
-
   DBUG_VOID_RETURN;
 }
 
@@ -1928,7 +1918,7 @@ int drop_temporary_table(THD *thd, TABLE
     If LOCK TABLES list is not empty and contains this table,
     unlock the table and remove the table from this list.
   */
-  mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
+  mysql_lock_remove(thd, thd->lock, table, FALSE);
   close_temporary_table(thd, table, 1, 1);
   DBUG_RETURN(0);
 }
@@ -2206,7 +2196,7 @@ bool close_cached_table(THD *thd, TABLE 
     DBUG_RETURN(TRUE);
 
   /* Close lock if this is not got with LOCK TABLES */
-  if (thd->lock)
+  if (! thd->prelocked_mode)
   {
     mysql_unlock_tables(thd, thd->lock);
     thd->lock=0;			// Start locked threads
@@ -2258,8 +2248,8 @@ void unlink_open_table(THD *thd, TABLE *
     if (list->s->table_cache_key.length == key_length &&
 	!memcmp(list->s->table_cache_key.str, key, key_length))
     {
-      if (unlock && thd->locked_tables)
-        mysql_lock_remove(thd, thd->locked_tables,
+      if (unlock && thd->prelocked_mode)
+        mysql_lock_remove(thd, thd->lock,
                           list->parent ? list->parent : list, TRUE);
 
       /* Prepare MERGE table for close. Close parent if necessary. */
@@ -2629,7 +2619,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *
     open not pre-opened tables in pre-locked/LOCK TABLES mode.
     TODO: move this block into a separate function.
   */
-  if (thd->locked_tables || thd->prelocked_mode)
+  if (thd->prelocked_mode)
   {						// Using table locks
     TABLE *best_table= 0;
     int best_distance= INT_MIN;
@@ -2660,7 +2650,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *
         */
         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 == LOCK_TABLES || table->query_id == 0) &&
             !table->parent)
         {
           int distance= ((int) table->reginfo.lock_type -
@@ -3271,7 +3261,7 @@ void close_data_files_and_leave_as_place
 
   safe_mutex_assert_owner(&LOCK_open);
 
-  if (thd->lock)
+  if (! thd->prelocked_mode)
   {
     /*
       If we are not under LOCK TABLES we should have only one table
@@ -3286,7 +3276,7 @@ void close_data_files_and_leave_as_place
     if (!strcmp(table->s->table_name.str, table_name) &&
 	!strcmp(table->s->db.str, db))
     {
-      if (thd->locked_tables)
+      if (thd->prelocked_mode)
       {
         if (table->parent)
         {
@@ -3296,11 +3286,11 @@ void close_data_files_and_leave_as_place
             the parent and close it. OTOH in most cases a MERGE table
             won't have multiple children with the same db.table_name.
           */
-          mysql_lock_remove(thd, thd->locked_tables, table->parent, TRUE);
+          mysql_lock_remove(thd, thd->lock, table->parent, TRUE);
           close_handle_and_leave_table_as_placeholder(table->parent);
         }
         else
-          mysql_lock_remove(thd, thd->locked_tables, table, TRUE);
+          mysql_lock_remove(thd, thd->lock, table, TRUE);
       }
       table->s->version= 0;
       close_handle_and_leave_table_as_placeholder(table);
@@ -3496,7 +3486,7 @@ bool reopen_tables(THD *thd, bool get_lo
     if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
                                  flags, &not_used)))
     {
-      thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
+      thd->lock= mysql_lock_merge(thd->lock, lock);
     }
     else
     {
@@ -3529,10 +3519,9 @@ void unlock_locked_tables(THD *thd)
   DBUG_ASSERT(!thd->in_sub_stmt &&
               !(thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
 
-  if (thd->locked_tables)
+  if (thd->prelocked_mode == LOCK_TABLES)
   {
-    thd->lock= thd->locked_tables;
-    thd->locked_tables=0;
+    thd->prelocked_mode= NON_PRELOCKED;
     close_thread_tables(thd);
     /*
       After closing tables we can free memory used for storing lock
@@ -4436,10 +4425,10 @@ int open_tables(THD *thd, TABLE_LIST **s
     If we are not already executing prelocked statement and don't have
     statement for which table list for prelocking is already built, let
     us cache routines and try to build such table list.
-
   */
 
-  if (!thd->prelocked_mode && !thd->lex->requires_prelocking()
&&
+  if ( (!thd->prelocked_mode || thd->prelocked_mode == LOCK_TABLES) &&
+      !thd->lex->requires_prelocking() &&
       thd->lex->uses_stored_routines())
   {
     bool first_no_prelocking, need_prelocking;
@@ -4653,7 +4642,8 @@ int open_tables(THD *thd, TABLE_LIST **s
         If we lock table for reading we won't update it so there is no need to
         process its triggers since they never will be activated.
       */
-      if (!thd->prelocked_mode && !thd->lex->requires_prelocking()
&&
+      if ((!thd->prelocked_mode || thd->prelocked_mode == LOCK_TABLES) &&
+          !thd->lex->requires_prelocking() &&
           tables->trg_event_map && tables->table->triggers &&
           tables->lock_type >= TL_WRITE_ALLOW_WRITE)
       {
@@ -4674,7 +4664,7 @@ int open_tables(THD *thd, TABLE_LIST **s
       free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
     }
 
-    if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
+    if (tables->lock_type != TL_UNLOCK && ! thd->prelocked_mode)
     {
       if (tables->lock_type == TL_WRITE_DEFAULT)
         tables->table->reginfo.lock_type= thd->update_lock_default;
@@ -4694,10 +4684,7 @@ int open_tables(THD *thd, TABLE_LIST **s
     DBUG_PRINT("tcache", ("is parent: %d  is child: %d",
                           test(tables->table->child_l),
                           test(tables->parent_l)));
-    DBUG_PRINT("tcache", ("in lock tables: %d  in prelock mode: %d",
-                          test(thd->locked_tables), test(thd->prelocked_mode)));
-    if (((!thd->locked_tables && !thd->prelocked_mode) ||
-         tables->table->s->tmp_table) &&
+    if ((!thd->prelocked_mode || tables->table->s->tmp_table) &&
         ((tables->table->child_l &&
           add_merge_table_list(tables)) ||
          (tables->parent_l &&
@@ -4713,7 +4700,8 @@ process_view_routines:
       Again we may need cache all routines used by this view and add
       tables used by them to table list.
     */
-    if (tables->view && !thd->prelocked_mode &&
+    if (tables->view &&
+        (!thd->prelocked_mode || thd->prelocked_mode == LOCK_TABLES) &&
         !thd->lex->requires_prelocking() &&
         tables->view->uses_stored_routines())
     {
@@ -4921,7 +4909,7 @@ retry:
     table_list->lock_type= lock_type;
     table_list->table=	   table;
     table->grant= table_list->grant;
-    if (thd->locked_tables)
+    if (thd->prelocked_mode)
     {
       if (check_lock_and_start_stmt(thd, table, lock_type))
 	table= 0;
@@ -5242,7 +5230,8 @@ int lock_tables(THD *thd, TABLE_LIST *ta
     We can't meet statement requiring prelocking if we already
     in prelocked mode.
   */
-  DBUG_ASSERT(!thd->prelocked_mode || !thd->lex->requires_prelocking());
+  DBUG_ASSERT(!thd->prelocked_mode || thd->prelocked_mode == LOCK_TABLES ||
+              !thd->lex->requires_prelocking());
   *need_reopen= FALSE;
 
   if (!tables && !thd->lex->requires_prelocking())
@@ -5250,14 +5239,14 @@ int lock_tables(THD *thd, TABLE_LIST *ta
 
   /*
     We need this extra check for thd->prelocked_mode because we want to avoid
-    attempts to lock tables in substatements. Checking for thd->locked_tables
+    attempts to lock tables in substatements. Checking for thd->lock
     is not enough in some situations. For example for SP containing
     "drop table t3; create temporary t3 ..; insert into t3 ...;"
-    thd->locked_tables may be 0 after drop tables, and without this extra
+    thd->lock may be 0 after drop tables, and without this extra
     check insert will try to lock temporary table t3, that will lead
     to memory leak...
   */
-  if (!thd->locked_tables && !thd->prelocked_mode)
+  if (!thd->prelocked_mode)
   {
     DBUG_ASSERT(thd->lock == 0);	// You must lock everything at once
     TABLE **start,**ptr;
@@ -5273,8 +5262,6 @@ int lock_tables(THD *thd, TABLE_LIST *ta
     /* We have to emulate LOCK TABLES if we are statement needs prelocking. */
     if (thd->lex->requires_prelocking())
     {
-      thd->in_lock_tables=1;
-      thd->options|= OPTION_TABLE_LOCK;
       /*
         If we have >= 2 different tables to update with auto_inc columns,
         statement-based binlogging won't work. We can solve this problem in
@@ -5290,32 +5277,12 @@ int lock_tables(THD *thd, TABLE_LIST *ta
 
     if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
                                         flags, need_reopen)))
-    {
-      if (thd->lex->requires_prelocking())
-      {
-        thd->options&= ~(OPTION_TABLE_LOCK);
-        thd->in_lock_tables=0;
-      }
       DBUG_RETURN(-1);
-    }
 
     if (thd->lex->requires_prelocking() &&
         thd->lex->sql_command != SQLCOM_LOCK_TABLES)
     {
       TABLE_LIST *first_not_own= thd->lex->first_not_own_table();
-      /*
-        We just have done implicit LOCK TABLES, and now we have
-        to emulate first open_and_lock_tables() after it.
-
-        Note that "LOCK TABLES" can also be marked as requiring prelocking
-        (e.g. if one locks view which uses functions). We should not emulate
-        such open_and_lock_tables() in this case. We also should not set
-        THD::prelocked_mode or first close_thread_tables() call will do
-        "UNLOCK TABLES".
-      */
-      thd->locked_tables= thd->lock;
-      thd->lock= 0;
-      thd->in_lock_tables=0;
 
       /*
         When open_and_lock_tables() is called for a single table out of
@@ -5338,9 +5305,7 @@ int lock_tables(THD *thd, TABLE_LIST *ta
               This was an attempt to enter prelocked mode so there is no
               need to care about THD::locked_tables_root here.
             */
-            mysql_unlock_tables(thd, thd->locked_tables);
-            thd->locked_tables= 0;
-            thd->options&= ~(OPTION_TABLE_LOCK);
+            mysql_unlock_tables(thd, thd->lock);
             DBUG_RETURN(-1);
           }
         }

=== modified file 'sql/sql_cache.cc'
--- a/sql/sql_cache.cc	2008-05-08 16:01:15 +0000
+++ b/sql/sql_cache.cc	2008-06-06 11:27:03 +0000
@@ -993,7 +993,7 @@ void Query_cache::store_query(THD *thd, 
 
     See also a note on double-check locking usage above.
   */
-  if (thd->locked_tables || query_cache_size == 0)
+  if (thd->prelocked_mode || query_cache_size == 0)
     DBUG_VOID_RETURN;
   uint8 tables_type= 0;
 
@@ -1205,7 +1205,7 @@ Query_cache::send_result_to_client(THD *
 
     See also a note on double-check locking usage above.
   */
-  if (thd->locked_tables || thd->variables.query_cache_type == 0 ||
+  if (thd->prelocked_mode || thd->variables.query_cache_type == 0 ||
       query_cache_size == 0)
     goto err;
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2008-05-23 13:54:03 +0000
+++ b/sql/sql_class.cc	2008-06-06 11:27:03 +0000
@@ -846,11 +846,7 @@ void THD::cleanup(void)
     ha_rollback(this);
     xid_cache_delete(&transaction.xid_state);
   }
-  if (locked_tables)
-  {
-    lock=locked_tables; locked_tables=0;
-    close_thread_tables(this);
-  }
+  unlock_locked_tables(this);
   mysql_ha_cleanup(this);
   delete_dynamic(&user_var_events);
   hash_free(&user_vars);
@@ -1645,7 +1641,7 @@ bool select_send::send_eof()
   ha_release_temporary_latches(thd);
 
   /* Unlock tables before sending packet to gain some speed */
-  if (thd->lock)
+  if (thd->lock && ! thd->prelocked_mode)
   {
     mysql_unlock_tables(thd, thd->lock);
     thd->lock=0;
@@ -2853,7 +2849,7 @@ void THD::restore_backup_open_tables_sta
   */
   DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
               handler_tables == 0 && derived_tables == 0 &&
-              lock == 0 && locked_tables == 0 &&
+              lock == 0 &&
               prelocked_mode == NON_PRELOCKED &&
               m_reprepare_observer == NULL);
   mdl_context_destroy(&mdl_context);

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2008-05-23 13:54:03 +0000
+++ b/sql/sql_class.h	2008-06-06 11:27:03 +0000
@@ -877,8 +877,8 @@ typedef I_List<Item_change_record> Item_
   See comment for THD::prelocked_mode for complete description.
 */
 
-enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1,
-                          PRELOCKED_UNDER_LOCK_TABLES= 2};
+enum prelocked_mode_type { NON_PRELOCKED= 0, PRELOCKED= 1,
+                           PRELOCKED_UNDER_LOCK_TABLES= 2, LOCK_TABLES= 3 };
 
 
 /**
@@ -937,13 +937,6 @@ public:
     See also lock_tables() for details.
   */
   MYSQL_LOCK *lock;
-  /*
-    Tables that were locked with explicit or implicit LOCK TABLES.
-    (Implicit LOCK TABLES happens when we are prelocking tables for
-     execution of statement which uses stored routines. See description
-     THD::prelocked_mode for more info.)
-  */
-  MYSQL_LOCK *locked_tables;
 
   /*
     CREATE-SELECT keeps an extra lock for the table being
@@ -1007,7 +1000,7 @@ public:
   void reset_open_tables_state(THD *thd)
   {
     open_tables= temporary_tables= handler_tables= derived_tables= 0;
-    extra_lock= lock= locked_tables= 0;
+    extra_lock= lock= 0;
     prelocked_mode= NON_PRELOCKED;
     state_flags= 0U;
     m_reprepare_observer= NULL;

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2008-06-04 12:27:06 +0000
+++ b/sql/sql_insert.cc	2008-06-06 11:27:03 +0000
@@ -597,7 +597,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
     never be able to get a lock on the table. QQQ: why not
     upgrade the lock here instead?
   */
-  if (table_list->lock_type == TL_WRITE_DELAYED && thd->locked_tables
&&
+  if (table_list->lock_type == TL_WRITE_DELAYED && thd->prelocked_mode
&&
       find_locked_table(thd->open_tables, table_list->db,
                         table_list->table_name))
   {

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2008-06-04 12:27:06 +0000
+++ b/sql/sql_parse.cc	2008-06-06 11:27:03 +0000
@@ -115,7 +115,7 @@ bool end_active_trans(THD *thd)
   {
     DBUG_PRINT("info",("options: 0x%llx", thd->options));
     /* Safety if one did "drop table" on locked tables */
-    if (!thd->locked_tables)
+    if (!thd->prelocked_mode)
       thd->options&= ~OPTION_TABLE_LOCK;
     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
     if (ha_commit(thd))
@@ -1202,7 +1202,7 @@ bool dispatch_command(enum enum_server_c
       }
       if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str)))
 	break;
-      if (thd->locked_tables || thd->active_transaction())
+      if (thd->prelocked_mode || thd->active_transaction())
       {
 	my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                    ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -2324,7 +2324,7 @@ mysql_execute_command(THD *thd)
       created during a gobal read lock.
     */
     DDL_blocker->check_DDL_blocker(thd);
-    if (!thd->locked_tables &&
+    if (!thd->prelocked_mode &&
         !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
     {
       res= 1;
@@ -2517,7 +2517,7 @@ end_with_restore_list:
     To prevent that, refuse SLAVE STOP if the
     client thread has locked tables
   */
-  if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
+  if (thd->prelocked_mode || thd->active_transaction() || thd->global_read_lock)
   {
     my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -2601,7 +2601,7 @@ end_with_restore_list:
       if (end_active_trans(thd))
 	goto error;
 
-      if (!thd->locked_tables &&
+      if (!thd->prelocked_mode &&
           !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
       {
         res= 1;
@@ -2926,7 +2926,7 @@ end_with_restore_list:
     if ((res= insert_precheck(thd, all_tables)))
       break;
 
-    if (!thd->locked_tables &&
+    if (!thd->prelocked_mode &&
         !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
     {
       res= 1;
@@ -2966,7 +2966,7 @@ end_with_restore_list:
 
     unit->set_limit(select_lex);
 
-    if (! thd->locked_tables &&
+    if (! thd->prelocked_mode &&
         ! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
     {
       res= 1;
@@ -3036,7 +3036,7 @@ end_with_restore_list:
       Don't allow this within a transaction because we want to use
       re-generate table
     */
-    if (thd->locked_tables || thd->active_transaction())
+    if (thd->prelocked_mode || thd->active_transaction())
     {
       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -3056,7 +3056,7 @@ end_with_restore_list:
     DBUG_ASSERT(select_lex->offset_limit == 0);
     unit->set_limit(select_lex);
 
-    if (!thd->locked_tables &&
+    if (!thd->prelocked_mode &&
         !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
     {
       res= 1;
@@ -3076,7 +3076,7 @@ end_with_restore_list:
       (TABLE_LIST *)thd->lex->auxiliary_table_list.first;
     multi_delete *del_result;
 
-    if (!thd->locked_tables &&
+    if (!thd->prelocked_mode &&
         !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
     {
       res= 1;
@@ -3289,13 +3289,13 @@ end_with_restore_list:
     /*
       We try to take transactional locks if
       - only transactional locks are requested (lex->lock_transactional) and
-      - no non-transactional locks exist (!thd->locked_tables).
+      - no non-transactional locks exist (!thd->prelocked_mode).
     */
     DBUG_PRINT("lock_info", ("lex->lock_transactional: %d  "
-                             "thd->locked_tables: %p",
+                             "thd->lock: %p",
                              lex->lock_transactional,
-                             thd->locked_tables));
-    if (lex->lock_transactional && !thd->locked_tables)
+                             thd->lock));
+    if (lex->lock_transactional && !thd->prelocked_mode)
     {
       int rc;
       /*
@@ -3341,11 +3341,8 @@ end_with_restore_list:
       if (thd->variables.query_cache_wlock_invalidate)
 	query_cache.invalidate_locked_for_write(first_table);
 #endif /*HAVE_QUERY_CACHE*/
-      thd->locked_tables=thd->lock;
-      thd->lock=0;
+      thd->prelocked_mode= LOCK_TABLES;
       (void) set_handler_table_locks(thd, all_tables, FALSE);
-      DBUG_PRINT("lock_info", ("thd->locked_tables: %p",
-                               thd->locked_tables));
       my_ok(thd);
     }
     else
@@ -3438,7 +3435,7 @@ end_with_restore_list:
     if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
                      is_schema_db(lex->name.str)))
       break;
-    if (thd->locked_tables || thd->active_transaction())
+    if (thd->prelocked_mode || thd->active_transaction())
     {
       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -3479,7 +3476,7 @@ end_with_restore_list:
       res= 1;
       break;
     }
-    if (thd->locked_tables || thd->active_transaction())
+    if (thd->prelocked_mode || thd->active_transaction())
     {
       res= 1;
       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
@@ -3521,7 +3518,7 @@ end_with_restore_list:
 #endif
     if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
       break;
-    if (thd->locked_tables || thd->active_transaction())
+    if (thd->prelocked_mode || thd->active_transaction())
     {
       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -4480,7 +4477,7 @@ create_sp_error:
                xa_state_names[thd->transaction.xid_state.xa_state]);
       break;
     }
-    if (thd->active_transaction() || thd->locked_tables)
+    if (thd->prelocked_mode || thd->active_transaction())
     {
       my_error(ER_XAER_OUTSIDE, MYF(0));
       break;
@@ -6676,7 +6673,7 @@ bool reload_acl_and_cache(THD *thd, ulon
         if we have a write locked table as this would lead to a deadlock
         when trying to reopen (and re-lock) the table after the flush.
       */
-      if (thd->locked_tables)
+      if (thd->prelocked_mode)
       {
         my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
         return 1;
@@ -6699,7 +6696,7 @@ bool reload_acl_and_cache(THD *thd, ulon
     }
     else
     {
-      if (thd && thd->locked_tables)
+      if (thd && thd->prelocked_mode)
       {
         /*
           If we are under LOCK TABLES we should have a write

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2008-06-05 06:48:36 +0000
+++ b/sql/sql_partition.cc	2008-06-06 11:27:03 +0000
@@ -5782,7 +5782,7 @@ static void release_log_entries(partitio
 static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
 {
   int err;
-  if (lpt->thd->locked_tables)
+  if (lpt->thd->prelocked_mode)
   {
     /*
       When we have the table locked, it is necessary to reopen the table

=== modified file 'sql/sql_rename.cc'
--- a/sql/sql_rename.cc	2008-05-23 13:54:03 +0000
+++ b/sql/sql_rename.cc	2008-06-06 11:27:03 +0000
@@ -44,7 +44,7 @@ bool mysql_rename_tables(THD *thd, TABLE
     if the user is trying to to do this in a transcation context
   */
 
-  if (thd->locked_tables || thd->active_transaction())
+  if (thd->prelocked_mode || thd->active_transaction())
   {
     my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2008-05-16 16:30:05 +0000
+++ b/sql/sql_select.cc	2008-06-06 11:27:03 +0000
@@ -1523,7 +1523,7 @@ JOIN::optimize()
     error= -1;
     DBUG_RETURN(1);
   }
-  if (const_tables && !thd->locked_tables &&
+  if (const_tables && !thd->prelocked_mode &&
       !(select_options & SELECT_NO_UNLOCK))
     mysql_unlock_some_tables(thd, table, const_tables);
   if (!conds && outer_join)
@@ -8492,7 +8492,7 @@ void JOIN::join_free()
     We are not using tables anymore
     Unlock all tables. We may be in an INSERT .... SELECT statement.
   */
-  if (can_unlock && lock && thd->lock &&
+  if (can_unlock && lock && thd->lock && !
thd->prelocked_mode &&
       !(select_options & SELECT_NO_UNLOCK) &&
       !select_lex->subquery_in_having &&
       (select_lex == (thd->lex->unit.fake_select_lex ?

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2008-06-05 15:33:38 +0000
+++ b/sql/sql_table.cc	2008-06-06 11:27:03 +0000
@@ -1481,7 +1481,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST 
 
   if (!drop_temporary)
   {
-    if (!thd->locked_tables &&
+    if (!thd->prelocked_mode &&
         !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
       DBUG_RETURN(TRUE);
   }
@@ -1582,7 +1582,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
 
   if (!drop_temporary)
   {
-    if (!thd->locked_tables)
+    if (!thd->prelocked_mode)
     {
       if (lock_table_names(thd, tables))
         DBUG_RETURN(1);
@@ -1591,7 +1591,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
         expel_table_from_cache(0, table->db, table->table_name);
       pthread_mutex_unlock(&LOCK_open);
     }
-    else if (thd->locked_tables)
+    else
     {
       for (table= tables; table; table= table->next_local)
         if (find_temporary_table(thd, table->db, table->table_name))
@@ -1676,7 +1676,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
     table_type= table->db_type;
     if (!drop_temporary)
     {
-      if (thd->locked_tables)
+      if (thd->prelocked_mode)
       {
         if (close_cached_table(thd, table->table))
         {
@@ -1837,7 +1837,7 @@ err_with_placeholders:
       locked. Additional check for 'non_temp_tables_count' is to avoid
       leaving LOCK TABLES mode if we have dropped only temporary tables.
     */
-    if (thd->locked_tables && thd->locked_tables->table_count == 0
&&
+    if (thd->prelocked_mode && thd->lock &&
thd->lock->table_count == 0 &&
         non_temp_tables_count > 0)
     {
       unlock_locked_tables(thd);
@@ -6364,7 +6364,7 @@ bool mysql_alter_table(THD *thd,char *ne
       if the user is trying to to do this in a transcation context
     */
 
-    if (thd->locked_tables || thd->active_transaction())
+    if (thd->prelocked_mode || thd->active_transaction())
     {
       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -6412,7 +6412,7 @@ view_err:
     set of tables from the old table or to open a new TABLE object for
     an extended list and verify that they belong to locked tables.
   */
-  if (thd->locked_tables &&
+  if (thd->prelocked_mode &&
       (create_info->used_fields & HA_CREATE_USED_UNION) &&
       (table->s->tmp_table == NO_TMP_TABLE))
   {
@@ -6626,7 +6626,7 @@ view_err:
     table_list->table= NULL;                    // For query cache
     query_cache_invalidate3(thd, table_list, 0);
 
-    if (thd->locked_tables)
+    if (thd->prelocked_mode)
     {
       /*
         Under LOCK TABLES we should adjust meta-data locks before finishing
@@ -6809,7 +6809,7 @@ view_err:
                                               &ha_alter_info,
                                               &ha_alter_flags,
                                               alter_info->keys_onoff);
-      if (thd->lock)
+      if (thd->lock && !thd->prelocked_mode)
       {
         mysql_unlock_tables(thd, thd->lock);
         thd->lock=0;
@@ -6913,7 +6913,7 @@ view_err:
   if (table->s->tmp_table != NO_TMP_TABLE)
   {
     /* Close lock if this is a transactional table */
-    if (thd->lock)
+    if (thd->lock && ! thd->prelocked_mode)
     {
       mysql_unlock_tables(thd, thd->lock);
       thd->lock=0;
@@ -7012,7 +7012,7 @@ view_err:
   (void) quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
 
 end_online:
-  if (thd->locked_tables && new_name == table_name && new_db == db)
+  if (thd->prelocked_mode && new_name == table_name && new_db == db)
   {
     thd->in_lock_tables= 1;
     error= reopen_tables(thd, 1);
@@ -7059,7 +7059,7 @@ end_online:
   table_list->table=0;				// For query cache
   query_cache_invalidate3(thd, table_list, 0);
 
-  if (thd->locked_tables)
+  if (thd->prelocked_mode)
   {
     if ((new_name != table_name || new_db != db))
     {

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2008-06-05 06:48:36 +0000
+++ b/sql/sql_trigger.cc	2008-06-06 11:27:03 +0000
@@ -383,7 +383,7 @@ bool mysql_create_or_drop_trigger(THD *t
     LOCK_open is not enough because global read lock is held without holding
     LOCK_open).
   */
-  if (!thd->locked_tables &&
+  if (!thd->prelocked_mode &&
       !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
     DBUG_RETURN(TRUE);
 
@@ -444,7 +444,7 @@ bool mysql_create_or_drop_trigger(THD *t
   /* Keep consistent with respect to other DDL statements */
   mysql_ha_rm_tables(thd, tables);
 
-  if (thd->locked_tables)
+  if (thd->prelocked_mode)
   {
     /* Under LOCK TABLES we must only accept write locked tables. */
     if (!(tables->table= find_write_locked_table(thd->open_tables, tables->db,
@@ -493,7 +493,7 @@ bool mysql_create_or_drop_trigger(THD *t
            table->triggers->drop_trigger(thd, tables, &stmt_query));
 
   /* Under LOCK TABLES we must reopen the table to activate the trigger. */
-  if (!result && thd->locked_tables)
+  if (!result && thd->prelocked_mode)
   {
     /* Make table suitable for reopening */
     close_data_files_and_leave_as_placeholders(thd, tables->db,
@@ -527,7 +527,7 @@ end:
     locks. Otherwise call to close_thread_tables() will take care about both
     TABLE instance created by reopen_name_locked_table() and metadata lock.
   */
-  if (thd->locked_tables && tables && tables->table)
+  if (thd->prelocked_mode && tables && tables->table)
     mdl_downgrade_exclusive_lock(&thd->mdl_context,
                                  tables->table->mdl_lock_data);
 

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2008-05-27 17:31:53 +0000
+++ b/sql/sql_update.cc	2008-06-06 11:27:03 +0000
@@ -962,7 +962,7 @@ int mysql_multi_update_prepare(THD *thd)
     count in open_tables()
   */
   uint  table_count= lex->table_count;
-  const bool using_lock_tables= thd->locked_tables != 0;
+  const bool using_lock_tables= thd->prelocked_mode != NON_PRELOCKED;
   bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
   bool need_reopen= FALSE;
   DBUG_ENTER("mysql_multi_update_prepare");

=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc	2008-06-04 12:27:06 +0000
+++ b/sql/sql_view.cc	2008-06-06 11:27:03 +0000
@@ -383,7 +383,7 @@ bool mysql_create_view(THD *thd, TABLE_L
     alteration of views under LOCK TABLES.
   */
 
-  if (thd->locked_tables)
+  if (thd->prelocked_mode)
   {
     my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
     res= TRUE;
@@ -1573,7 +1573,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
     TABLES we have to simply prohibit dropping of views.
   */
 
-  if (thd->locked_tables)
+  if (thd->prelocked_mode)
   {
     my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
     DBUG_RETURN(TRUE);

=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc	2008-05-27 12:15:44 +0000
+++ b/storage/myisam/ha_myisam.cc	2008-06-06 11:27:03 +0000
@@ -942,7 +942,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK
   strmov(fixed_name,file->filename);
 
   // Don't lock tables if we have used LOCK TABLE
-  if (!thd->locked_tables && 
+  if (! thd->prelocked_mode &&
       mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
   {
     mi_check_print_error(&param,ER(ER_CANT_LOCK),my_errno);
@@ -1052,7 +1052,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK
     update_state_info(&param, file, 0);
   }
   thd_proc_info(thd, old_proc_info);
-  if (!thd->locked_tables)
+  if (! thd->prelocked_mode)
     mi_lock_database(file,F_UNLCK);
   DBUG_RETURN(error ? HA_ADMIN_FAILED :
 	      !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);

Thread
bzr commit into mysql-6.0 branch (konstantin:2662) WL#3726Konstantin Osipov6 Jun
  • Re: bzr commit into mysql-6.0 branch (konstantin:2662) WL#3726Dmitry Lenev6 Jun