#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, ¬_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(¶m,ER(ER_CANT_LOCK),my_errno);
@@ -1052,7 +1052,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK
update_state_info(¶m, 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);