#At file:///opt/local/work/mysql-6.0-prelocked_mode-to-push/
2662 Konstantin Osipov 2008-06-06
WL#3726: work on review comments.
Remove thd->locked_tables. Always store MYSQL_LOCK instances in
thd->lock.
Rename thd->prelocked_mode to thd->locked_tables_mode.
Use thd->locked_tables_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.
Review comments.
modified:
sql/ha_ndbcluster_binlog.cc
sql/handler.cc
sql/lock.cc
sql/log.cc
sql/set_var.cc
sql/sp_head.cc
sql/sql_base.cc
sql/sql_cache.cc
sql/sql_class.cc
sql/sql_class.h
sql/sql_cursor.cc
sql/sql_insert.cc
sql/sql_load.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 (safety).
sql/handler.cc
There is no thd->locked_tables any more.
Update comments.
sql/lock.cc
There is no thd->locked_tables any more.
sql/log.cc
Rename thd->prelocked_mode to thd->locked_tables_mode.
sql/set_var.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
sql/sp_head.cc
Rename thd->prelocked_mode to thd->locked_tables_mode.
sql/sql_base.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
Remove thd->locked_tables.
sql/sql_cache.cc
Use thd->locked_tables_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.
Use thd->locked_tables_mode instead of thd->locked_tables.
sql/sql_class.h
Remove thd->locked_tables.
Make prelocked mode a kind of LOCK TABLES mode.
Update comments.
sql/sql_cursor.cc
Update comments.
sql/sql_insert.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
Rename thd->prelocked_mode to thd->locked_tables_mode.
sql/sql_load.cc
Rename thd->prelocked_mode to thd->locked_tables_mode.
sql/sql_parse.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
Remove thd->locked_tables.
sql/sql_partition.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
sql/sql_rename.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
sql/sql_select.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
sql/sql_table.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
sql/sql_trigger.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
sql/sql_update.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
sql/sql_view.cc
Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
storage/myisam/ha_myisam.cc
Use thd->locked_tables_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 19:17:47 +0000
@@ -270,7 +270,7 @@ static void run_query(THD *thd, char *bu
DBUG_PRINT("query", ("%s", thd->query));
DBUG_ASSERT(!thd->in_sub_stmt);
- DBUG_ASSERT(!thd->prelocked_mode);
+ DBUG_ASSERT(!thd->locked_tables_mode);
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
@@ -2625,8 +2625,12 @@ ndb_add_ndb_binlog_index(THD *thd, ndb_b
}
} while (row);
- mysql_unlock_tables(thd, thd->lock);
- thd->lock= 0;
+
+ if (! thd->locked_tables_mode) /* Is always TRUE */
+ {
+ 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 19:17:47 +0000
@@ -5165,9 +5165,7 @@ static bool check_table_binlog_row_based
to the binary log.
This function will generate and write table maps for all tables
- that are locked by the thread 'thd'. Either manually locked
- (stored in THD::locked_tables) and automatically locked (stored
- in THD::lock) are considered.
+ that are locked by the thread 'thd'.
@param thd Pointer to THD structure
@@ -5176,23 +5174,19 @@ static bool check_table_binlog_row_based
@sa
THD::lock
- THD::locked_tables
*/
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 19:17:47 +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/log.cc'
--- a/sql/log.cc 2008-05-21 19:46:08 +0000
+++ b/sql/log.cc 2008-06-06 19:17:47 +0000
@@ -3850,7 +3850,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
this will close all tables on the slave.
*/
bool const end_stmt=
- thd->prelocked_mode && thd->lex->requires_prelocking();
+ thd->locked_tables_mode && thd->lex->requires_prelocking();
thd->binlog_flush_pending_rows_event(end_stmt);
pthread_mutex_lock(&LOCK_log);
=== 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 19:17:47 +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->locked_tables_mode || thd->active_transaction())
{
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
DBUG_RETURN(true);
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2008-05-29 12:52:56 +0000
+++ b/sql/sp_head.cc 2008-06-06 19:17:47 +0000
@@ -1233,7 +1233,7 @@ sp_head::execute(THD *thd)
Will write this SP statement into binlog separately
(TODO: consider changing the condition to "not inside event union")
*/
- if (thd->prelocked_mode == NON_PRELOCKED)
+ if (thd->locked_tables_mode == LTM_NONE)
thd->user_var_events_alloc= thd->mem_root;
err_status= i->execute(thd, &ip);
@@ -1245,7 +1245,7 @@ sp_head::execute(THD *thd)
If we've set thd->user_var_events_alloc to mem_root of this SP
statement, clean all the events allocated in it.
*/
- if (thd->prelocked_mode == NON_PRELOCKED)
+ if (thd->locked_tables_mode == LTM_NONE)
{
reset_dynamic(&thd->user_var_events);
thd->user_var_events_alloc= NULL;//DEBUG
@@ -2687,7 +2687,7 @@ sp_lex_keeper::reset_lex_and_exec_core(T
thd->query_id= next_query_id();
pthread_mutex_unlock(&LOCK_thread_count);
- if (thd->prelocked_mode == NON_PRELOCKED)
+ if (thd->locked_tables_mode == LTM_NONE)
{
/*
This statement will enter/leave prelocked mode on its own.
=== 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 19:17:47 +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->locked_tables_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->locked_tables_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->locked_tables_mode <= LTM_LOCK_TABLES ||
+ thd->lex->requires_prelocking())
thd->transaction.stmt.reset();
}
- if (thd->locked_tables || prelocked_mode)
+ if (thd->locked_tables_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,19 @@ 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->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)
+ thd->locked_tables_mode= LTM_LOCK_TABLES;
- if (prelocked_mode == PRELOCKED_UNDER_LOCK_TABLES)
+ if (thd->locked_tables_mode == LTM_LOCK_TABLES)
DBUG_VOID_RETURN;
+ thd->locked_tables_mode= LTM_NONE;
+ thd->options&= ~OPTION_TABLE_LOCK;
+
/*
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 +1455,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;
}
@@ -1887,9 +1878,10 @@ TABLE *find_temporary_table(THD *thd, TA
Try to locate the table in the list of thd->temporary_tables.
If the table is found:
- if the table is being used by some outer statement, fail.
- - if the table is in thd->locked_tables, unlock it and
- remove it from the list of locked tables. Currently only transactional
- temporary tables are present in the locked_tables list.
+ - if the table is locked with LOCK TABLES or by prelocking,
+ unlock it and remove it from the list of locked tables
+ (THD::lock). Currently only transactional temporary tables
+ are locked.
- Close the temporary table, remove its .FRM
- remove the table from the list of temporary tables
@@ -1928,7 +1920,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 +2198,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->locked_tables_mode)
{
mysql_unlock_tables(thd, thd->lock);
thd->lock=0; // Start locked threads
@@ -2258,8 +2250,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->locked_tables_mode)
+ mysql_lock_remove(thd, thd->lock,
list->parent ? list->parent : list, TRUE);
/* Prepare MERGE table for close. Close parent if necessary. */
@@ -2629,11 +2621,11 @@ 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->locked_tables_mode)
{ // Using table locks
TABLE *best_table= 0;
int best_distance= INT_MIN;
- bool check_if_used= thd->prelocked_mode &&
+ bool check_if_used= thd->locked_tables_mode > LTM_LOCK_TABLES &&
((int) table_list->lock_type >=
(int) TL_WRITE_ALLOW_WRITE);
for (table=thd->open_tables; table ; table=table->next)
@@ -2660,7 +2652,8 @@ 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->locked_tables_mode == LTM_LOCK_TABLES ||
+ table->query_id == 0) &&
!table->parent)
{
int distance= ((int) table->reginfo.lock_type -
@@ -2743,7 +2736,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *
so we may only end up here if the table did not exist when
locked tables list was created.
*/
- if (thd->prelocked_mode == PRELOCKED)
+ if (thd->locked_tables_mode == LTM_PRELOCKED)
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
else
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
@@ -3271,7 +3264,7 @@ void close_data_files_and_leave_as_place
safe_mutex_assert_owner(&LOCK_open);
- if (thd->lock)
+ if (! thd->locked_tables_mode)
{
/*
If we are not under LOCK TABLES we should have only one table
@@ -3286,7 +3279,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->locked_tables_mode)
{
if (table->parent)
{
@@ -3296,11 +3289,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 +3489,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,17 +3522,22 @@ void unlock_locked_tables(THD *thd)
DBUG_ASSERT(!thd->in_sub_stmt &&
!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
- if (thd->locked_tables)
- {
- thd->lock= thd->locked_tables;
- thd->locked_tables=0;
- close_thread_tables(thd);
- /*
- After closing tables we can free memory used for storing lock
- request objects for metadata locks
- */
- free_root(&thd->locked_tables_root, MYF(MY_MARK_BLOCKS_FREE));
- }
+ /*
+ Sic: we must be careful to not close open tables if
+ we're not in LOCK TABLES mode: unlock_locked_tables() is
+ sometimes called implicitly, expecting no effect on
+ open tables, e.g. from begin_trans().
+ */
+ if (thd->locked_tables_mode != LTM_LOCK_TABLES)
+ return;
+
+ thd->locked_tables_mode= LTM_NONE;
+ close_thread_tables(thd);
+ /*
+ After closing tables we can free memory used for storing lock
+ request objects for metadata locks
+ */
+ free_root(&thd->locked_tables_root, MYF(MY_MARK_BLOCKS_FREE));
}
@@ -4387,11 +4385,6 @@ bool fix_merge_after_open(TABLE_LIST *ol
prelocking it won't do such precaching and will simply reuse table list
which is already built.
- If any table has a trigger and start->trg_event_map is non-zero
- the final lock will end up in thd->locked_tables, otherwise, the
- lock will be placed in thd->lock. See also comments in
- st_lex::set_trg_event_type_for_tables().
-
RETURN
0 - OK
-1 - error
@@ -4436,10 +4429,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->locked_tables_mode <= LTM_LOCK_TABLES &&
+ !thd->lex->requires_prelocking() &&
thd->lex->uses_stored_routines())
{
bool first_no_prelocking, need_prelocking;
@@ -4653,7 +4646,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->locked_tables_mode <= LTM_LOCK_TABLES &&
+ !thd->lex->requires_prelocking() &&
tables->trg_event_map && tables->table->triggers &&
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
{
@@ -4674,7 +4668,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->locked_tables_mode)
{
if (tables->lock_type == TL_WRITE_DEFAULT)
tables->table->reginfo.lock_type= thd->update_lock_default;
@@ -4694,10 +4688,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->locked_tables_mode || tables->table->s->tmp_table) &&
((tables->table->child_l &&
add_merge_table_list(tables)) ||
(tables->parent_l &&
@@ -4713,7 +4704,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->locked_tables_mode <= LTM_LOCK_TABLES &&
!thd->lex->requires_prelocking() &&
tables->view->uses_stored_routines())
{
@@ -4921,7 +4913,7 @@ retry:
table_list->lock_type= lock_type;
table_list->table= table;
table->grant= table_list->grant;
- if (thd->locked_tables)
+ if (thd->locked_tables_mode)
{
if (check_lock_and_start_stmt(thd, table, lock_type))
table= 0;
@@ -5223,9 +5215,9 @@ int decide_logging_format(THD *thd, TABL
handling thr_lock gives us. You most always get all needed locks at
once.
- If query for which we are calling this function marked as requring
- prelocking, this function will do implicit LOCK TABLES and change
- thd::prelocked_mode accordingly.
+ If query for which we are calling this function marked as requiring
+ prelocking, this function will change locked_tables_mode to
+ LTM_PRELOCKED.
RETURN VALUES
0 ok
@@ -5242,22 +5234,24 @@ 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->locked_tables_mode <= LTM_LOCK_TABLES ||
+ !thd->lex->requires_prelocking());
*need_reopen= FALSE;
if (!tables && !thd->lex->requires_prelocking())
DBUG_RETURN(decide_logging_format(thd, tables));
/*
- 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
- is not enough in some situations. For example for SP containing
+ Check for thd->locked_tables_mode to avoid a redundant
+ and harmful attempt to lock the already locked tables again.
+ Checking for thd->lock is not enough in some situations. For example,
+ if a stored function contains
"drop table t3; create temporary t3 ..; insert into t3 ...;"
- thd->locked_tables 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...
+ thd->lock may be 0 after drop tables, whereas locked_tables_mode
+ is still on. In this situation an attempt to lock temporary
+ table t3 will lead to a memory leak.
*/
- if (!thd->locked_tables && !thd->prelocked_mode)
+ if (! thd->locked_tables_mode)
{
DBUG_ASSERT(thd->lock == 0); // You must lock everything at once
TABLE **start,**ptr;
@@ -5307,15 +5301,8 @@ int lock_tables(THD *thd, TABLE_LIST *ta
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;
+ thd->in_lock_tables= 0;
/*
When open_and_lock_tables() is called for a single table out of
@@ -5338,8 +5325,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;
+ mysql_unlock_tables(thd, thd->lock);
thd->options&= ~(OPTION_TABLE_LOCK);
DBUG_RETURN(-1);
}
@@ -5351,7 +5337,7 @@ int lock_tables(THD *thd, TABLE_LIST *ta
*/
mark_real_tables_as_free_for_reuse(first_not_own);
DBUG_PRINT("info",("prelocked_mode= PRELOCKED"));
- thd->prelocked_mode= PRELOCKED;
+ thd->locked_tables_mode= LTM_PRELOCKED;
}
}
else
@@ -5384,7 +5370,7 @@ int lock_tables(THD *thd, TABLE_LIST *ta
{
mark_real_tables_as_free_for_reuse(first_not_own);
DBUG_PRINT("info", ("thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES"));
- thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES;
+ thd->locked_tables_mode= LTM_PRELOCKED_UNDER_LOCK_TABLES;
}
}
=== 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 19:17:47 +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->locked_tables_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->locked_tables_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 19:17:47 +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->locked_tables_mode)
{
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
@@ -2853,8 +2849,8 @@ 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 &&
- prelocked_mode == NON_PRELOCKED &&
+ lock == 0 &&
+ locked_tables_mode == LTM_NONE &&
m_reprepare_observer == NULL);
mdl_context_destroy(&mdl_context);
mdl_context_destroy(&handler_mdl_context);
@@ -3637,7 +3633,7 @@ int THD::binlog_query(THD::enum_binlog_q
If we are in prelocked mode, the flushing will be done inside the
top-most close_thread_tables().
*/
- if (this->prelocked_mode == NON_PRELOCKED)
+ if (this->locked_tables_mode <= LTM_LOCK_TABLES)
if (int error= binlog_flush_pending_rows_event(TRUE))
DBUG_RETURN(error);
=== 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 19:17:47 +0000
@@ -873,12 +873,17 @@ typedef I_List<Item_change_record> Item_
/**
- Type of prelocked mode.
- See comment for THD::prelocked_mode for complete description.
+ Type of locked tables mode.
+ See comment for THD::locked_tables_mode for complete description.
*/
-enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1,
- PRELOCKED_UNDER_LOCK_TABLES= 2};
+enum enum_locked_tables_mode
+{
+ LTM_NONE= 0,
+ LTM_LOCK_TABLES,
+ LTM_PRELOCKED,
+ LTM_PRELOCKED_UNDER_LOCK_TABLES
+};
/**
@@ -931,19 +936,13 @@ public:
statement ends.
Manual mode comes into play when a user issues a 'LOCK TABLES'
statement. In this mode the user can only use the locked tables.
- Trying to use any other tables will give an error. The locked tables are
- stored in 'locked_tables' member. Manual locking is described in
+ Trying to use any other tables will give an error.
+ The locked tables are also stored in this member, however,
+ thd->locked_tables_mode is turned on. Manual locking is described in
the 'LOCK_TABLES' chapter of the MySQL manual.
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
@@ -953,29 +952,34 @@ public:
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
- "prelocked mode" is it.
-
- Prelocked mode is used for execution of queries which explicitly
- or implicitly (via views or triggers) use functions, thus may need
- some additional tables (mentioned in query table list) for their
- execution.
-
- First open_tables() call for such query will analyse all functions
- used by it and add all additional tables to table its list. It will
- also mark this query as requiring prelocking. After that lock_tables()
- will issue implicit LOCK TABLES for the whole table list and change
- thd::prelocked_mode to non-0. All queries called in functions invoked
- by the main query will use prelocked tables. Non-0 prelocked_mode
- will also surpress mentioned analysys in those queries thus saving
- cycles. Prelocked mode will be turned off once close_thread_tables()
- for the main query will be called.
-
- Note: Since not all "tables" present in table list are really locked
- thd::prelocked_mode does not imply thd::locked_tables.
+ Enum enum_locked_tables_mode and locked_tables_mode member are
+ used to indicate whether the so-called "locked tables mode" is on,
+ and what kind of mode is active.
+
+ Locked tables mode is used when it's necessary to open and
+ lock many tables at once, for usage across multiple
+ (sub-)statements.
+ This may be necessary either for queries that use stored functions
+ and triggers, in which case the statements inside functions and
+ triggers may be executed many times, or for implementation of
+ LOCK TABLES, in which case the opened tables are reused by all
+ subsequent statements until a call to UNLOCK TABLES.
+
+ The kind of locked tables mode employed for stored functions and
+ triggers is also called "prelocked mode".
+ In this mode, first open_tables() call to open the tables used
+ in a statement analyses all functions used by the statement
+ and adds all indirectly used tables to the list of tables to
+ open and lock.
+ It also marks the parse tree of the statement as requiring
+ prelocking. After that, lock_tables() locks the entire list
+ of tables and changes THD::locked_tables_modeto LTM_PRELOCKED.
+ All statements executed inside functions or triggers
+ use the prelocked tables, instead of opening their own ones.
+ Prelocked mode is turned off automatically once close_thread_tables()
+ of the main statement is called.
*/
- prelocked_mode_type prelocked_mode;
+ enum enum_locked_tables_mode locked_tables_mode;
ulong version;
uint current_tablenr;
@@ -1007,8 +1011,8 @@ public:
void reset_open_tables_state(THD *thd)
{
open_tables= temporary_tables= handler_tables= derived_tables= 0;
- extra_lock= lock= locked_tables= 0;
- prelocked_mode= NON_PRELOCKED;
+ extra_lock= lock= 0;
+ locked_tables_mode= LTM_NONE;
state_flags= 0U;
m_reprepare_observer= NULL;
mdl_context_init(&mdl_context, thd);
=== modified file 'sql/sql_cursor.cc'
--- a/sql/sql_cursor.cc 2008-05-21 10:17:29 +0000
+++ b/sql/sql_cursor.cc 2008-06-06 19:17:47 +0000
@@ -275,7 +275,6 @@ Sensitive_cursor::Sensitive_cursor(THD *
Save THD state into cursor.
@todo
- - XXX: thd->locked_tables is not changed.
- What problems can we have with it if cursor is open?
- TODO: must be fixed because of the prelocked mode.
*/
@@ -328,7 +327,6 @@ Sensitive_cursor::post_open(THD *thd)
}
}
/*
- XXX: thd->locked_tables is not changed.
What problems can we have with it if cursor is open?
TODO: must be fixed because of the prelocked mode.
*/
=== 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 19:17:47 +0000
@@ -427,7 +427,7 @@ void upgrade_lock_type(THD *thd, thr_loc
*/
if (specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE) ||
thd->variables.max_insert_delayed_threads == 0 ||
- thd->prelocked_mode ||
+ thd->locked_tables_mode > LTM_LOCK_TABLES ||
thd->lex->uses_stored_routines())
{
*lock_type= TL_WRITE;
@@ -597,7 +597,8 @@ 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->locked_tables_mode &&
find_locked_table(thd->open_tables, table_list->db,
table_list->table_name))
{
@@ -732,7 +733,14 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
{
if (duplic != DUP_ERROR || ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- if (!thd->prelocked_mode)
+ /**
+ This is a simple check for the case when the table has a trigger
+ that reads from it, or when the statement invokes a stored function
+ that reads from the table being inserted to.
+ Engines can't handle a bulk insert in parallel with a read form the
+ same table in the same connection.
+ */
+ if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
table->file->ha_start_bulk_insert(values_list.elements);
}
@@ -848,7 +856,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
auto_inc values from the delayed_insert thread as they share TABLE.
*/
table->file->ha_release_auto_increment();
- if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error)
+ if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
+ table->file->ha_end_bulk_insert() && !error)
{
table->file->print_error(my_errno,MYF(0));
error=1;
@@ -2989,7 +2998,7 @@ select_insert::prepare(List<Item> &value
lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
}
else if (!(lex->current_select->options & OPTION_BUFFER_RESULT) &&
- !thd->prelocked_mode)
+ thd->locked_tables_mode <= LTM_LOCK_TABLES)
{
/*
We must not yet prepare the result table if it is the same as one of the
@@ -3055,7 +3064,7 @@ int select_insert::prepare2(void)
{
DBUG_ENTER("select_insert::prepare2");
if (thd->lex->current_select->options & OPTION_BUFFER_RESULT &&
- !thd->prelocked_mode)
+ thd->locked_tables_mode <= LTM_LOCK_TABLES)
table->file->ha_start_bulk_insert((ha_rows) 0);
DBUG_RETURN(0);
}
@@ -3175,7 +3184,8 @@ bool select_insert::send_eof()
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
trans_table, table->file->table_type()));
- error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0;
+ error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ?
+ table->file->ha_end_bulk_insert() : 0);
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
@@ -3249,7 +3259,7 @@ void select_insert::abort() {
If we are not in prelocked mode, we end the bulk insert started
before.
*/
- if (!thd->prelocked_mode)
+ if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
table->file->ha_end_bulk_insert();
/*
@@ -3619,7 +3629,7 @@ select_create::prepare(List<Item> &value
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
if (info.handle_duplicates == DUP_UPDATE)
table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE);
- if (!thd->prelocked_mode)
+ if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
table->file->ha_start_bulk_insert((ha_rows) 0);
thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode &
=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc 2008-04-14 10:15:04 +0000
+++ b/sql/sql_load.cc 2008-06-06 19:17:47 +0000
@@ -408,7 +408,7 @@ int mysql_load(THD *thd,sql_exchange *ex
(!table->triggers ||
!table->triggers->has_delete_triggers()))
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
- if (!thd->prelocked_mode)
+ if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
table->file->ha_start_bulk_insert((ha_rows) 0);
table->copy_blobs=1;
@@ -429,7 +429,8 @@ int mysql_load(THD *thd,sql_exchange *ex
error= read_sep_field(thd, info, table_list, fields_vars,
set_fields, set_values, read_info,
*enclosed, skip_lines, ignore);
- if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error)
+ if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
+ table->file->ha_end_bulk_insert() && !error)
{
table->file->print_error(my_errno, MYF(0));
error= 1;
=== 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 19:17:47 +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->locked_tables_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->locked_tables_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->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
res= 1;
@@ -2517,7 +2517,8 @@ 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->locked_tables_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 +2602,7 @@ end_with_restore_list:
if (end_active_trans(thd))
goto error;
- if (!thd->locked_tables &&
+ if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
res= 1;
@@ -2926,7 +2927,7 @@ end_with_restore_list:
if ((res= insert_precheck(thd, all_tables)))
break;
- if (!thd->locked_tables &&
+ if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
res= 1;
@@ -2966,7 +2967,7 @@ end_with_restore_list:
unit->set_limit(select_lex);
- if (! thd->locked_tables &&
+ if (! thd->locked_tables_mode &&
! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
{
res= 1;
@@ -3036,7 +3037,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->locked_tables_mode || thd->active_transaction())
{
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -3056,7 +3057,7 @@ end_with_restore_list:
DBUG_ASSERT(select_lex->offset_limit == 0);
unit->set_limit(select_lex);
- if (!thd->locked_tables &&
+ if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
res= 1;
@@ -3076,7 +3077,7 @@ end_with_restore_list:
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
multi_delete *del_result;
- if (!thd->locked_tables &&
+ if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
res= 1;
@@ -3289,13 +3290,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->locked_tables_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->locked_tables_mode)
{
int rc;
/*
@@ -3341,11 +3342,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->locked_tables_mode= LTM_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 +3436,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->locked_tables_mode || thd->active_transaction())
{
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -3479,7 +3477,7 @@ end_with_restore_list:
res= 1;
break;
}
- if (thd->locked_tables || thd->active_transaction())
+ if (thd->locked_tables_mode || thd->active_transaction())
{
res= 1;
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
@@ -3521,7 +3519,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->locked_tables_mode || thd->active_transaction())
{
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -4480,7 +4478,7 @@ create_sp_error:
xa_state_names[thd->transaction.xid_state.xa_state]);
break;
}
- if (thd->active_transaction() || thd->locked_tables)
+ if (thd->locked_tables_mode || thd->active_transaction())
{
my_error(ER_XAER_OUTSIDE, MYF(0));
break;
@@ -6676,7 +6674,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->locked_tables_mode)
{
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
return 1;
@@ -6699,7 +6697,7 @@ bool reload_acl_and_cache(THD *thd, ulon
}
else
{
- if (thd && thd->locked_tables)
+ if (thd && thd->locked_tables_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 19:17:47 +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->locked_tables_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 19:17:47 +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->locked_tables_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 19:17:47 +0000
@@ -1523,7 +1523,7 @@ JOIN::optimize()
error= -1;
DBUG_RETURN(1);
}
- if (const_tables && !thd->locked_tables &&
+ if (const_tables && !thd->locked_tables_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->locked_tables_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 19:17:47 +0000
@@ -1481,7 +1481,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST
if (!drop_temporary)
{
- if (!thd->locked_tables &&
+ if (!thd->locked_tables_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->locked_tables_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->locked_tables_mode)
{
if (close_cached_table(thd, table->table))
{
@@ -1837,8 +1837,8 @@ 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 &&
- non_temp_tables_count > 0)
+ if (thd->locked_tables_mode &&
+ thd->lock && thd->lock->table_count == 0 && non_temp_tables_count > 0)
{
unlock_locked_tables(thd);
goto end;
@@ -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->locked_tables_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->locked_tables_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->locked_tables_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->locked_tables_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->locked_tables_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->locked_tables_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->locked_tables_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 19:17:47 +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->locked_tables_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->locked_tables_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->locked_tables_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->locked_tables_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 19:17:47 +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->locked_tables_mode != LTM_NONE;
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 19:17:47 +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->locked_tables_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->locked_tables_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 19:17:47 +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->locked_tables_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->locked_tables_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#3726 | Konstantin Osipov | 6 Jun |