Backport of:

----------------------------------------------------------
revno: 2630.4.26
committer: Konstantin Osipov <konstantin@mysql.com>
branch nick: mysql-6.0-prelocked_mode-to-push
timestamp: Fri 2008-06-06 23:19:04 +0400
message:
  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.


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.
This commit is contained in:
Konstantin Osipov 2009-12-01 17:39:03 +03:00
parent 1b078b3f2d
commit 5969dcda21
22 changed files with 208 additions and 213 deletions

View File

@ -264,7 +264,7 @@ static void run_query(THD *thd, char *buf, char *end,
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);
@ -2429,8 +2429,12 @@ int ndb_add_ndb_binlog_index(THD *thd, void *_row)
goto add_ndb_binlog_index_err;
}
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:

View File

@ -4527,9 +4527,7 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
DESCRIPTION
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'.
RETURN VALUE
0 All OK
@ -4537,25 +4535,22 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
SEE ALSO
THD::lock
THD::locked_tables
*/
static int write_locked_table_maps(THD *thd)
{
DBUG_ENTER("write_locked_table_maps");
DBUG_PRINT("enter", ("thd: 0x%lx thd->lock: 0x%lx thd->locked_tables: 0x%lx "
DBUG_PRINT("enter", ("thd: 0x%lx thd->lock: 0x%lx "
"thd->extra_lock: 0x%lx",
(long) thd, (long) thd->lock,
(long) thd->locked_tables, (long) thd->extra_lock));
(long) thd, (long) thd->lock, (long) thd->extra_lock));
DBUG_PRINT("debug", ("get_binlog_table_maps(): %d", thd->get_binlog_table_maps()));
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];

View File

@ -754,7 +754,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
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. */

View File

@ -4060,7 +4060,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
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();
if (thd->binlog_flush_pending_rows_event(end_stmt))
DBUG_RETURN(error);

View File

@ -4292,7 +4292,7 @@ bool sys_var_opt_readonly::update(THD *thd, set_var *var)
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);

View File

@ -1257,7 +1257,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);
@ -1269,7 +1269,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
@ -2740,7 +2740,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
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.

View File

@ -1025,7 +1025,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
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
@ -1141,7 +1141,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
}
err_with_reopen:
if (thd->locked_tables)
if (thd->locked_tables_mode)
{
pthread_mutex_lock(&LOCK_open);
/*
@ -1375,7 +1375,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
@ -1433,11 +1432,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 */
@ -1447,7 +1447,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;
/*
@ -1455,18 +1455,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 */
}
@ -1501,16 +1502,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;
}
@ -1951,9 +1942,10 @@ TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
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
@ -1992,7 +1984,7 @@ int drop_temporary_table(THD *thd, TABLE_LIST *table_list)
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);
}
@ -2265,7 +2257,7 @@ bool close_cached_table(THD *thd, TABLE *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
@ -2318,8 +2310,8 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock)
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. */
@ -2690,7 +2682,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
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;
@ -2705,7 +2697,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
*/
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 -
@ -2788,7 +2781,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
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);
@ -3329,7 +3322,7 @@ void close_data_files_and_leave_as_placeholders(THD *thd, const char *db,
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
@ -3344,7 +3337,7 @@ void close_data_files_and_leave_as_placeholders(THD *thd, const char *db,
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)
{
@ -3354,11 +3347,11 @@ void close_data_files_and_leave_as_placeholders(THD *thd, const char *db,
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);
@ -3554,7 +3547,7 @@ bool reopen_tables(THD *thd, bool get_locks)
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
{
@ -3587,17 +3580,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));
}
@ -4494,11 +4492,6 @@ thr_lock_type read_lock_type_for_table(THD *thd, TABLE *table)
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
@ -4543,10 +4536,10 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
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;
@ -4759,7 +4752,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
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)
{
@ -4780,7 +4774,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
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;
@ -4803,10 +4797,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
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 &&
@ -4822,7 +4813,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())
{
@ -4996,7 +4988,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
DBUG_ENTER("open_ltable");
/* should not be used in a prelocked_mode context, see NOTE above */
DBUG_ASSERT(!thd->prelocked_mode);
DBUG_ASSERT(thd->locked_tables_mode < LTM_PRELOCKED);
thd_proc_info(thd, "Opening table");
thd->current_tablenr= 0;
@ -5033,7 +5025,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;
@ -5355,9 +5347,9 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
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
@ -5374,22 +5366,24 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
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;
@ -5443,15 +5437,8 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
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
@ -5474,8 +5461,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
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);
}
@ -5486,8 +5472,8 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
and was marked as occupied during open_tables() as free for reuse.
*/
mark_real_tables_as_free_for_reuse(first_not_own);
DBUG_PRINT("info",("prelocked_mode= PRELOCKED"));
thd->prelocked_mode= PRELOCKED;
DBUG_PRINT("info",("locked_tables_mode= PRELOCKED"));
thd->locked_tables_mode= LTM_PRELOCKED;
}
}
else
@ -5512,7 +5498,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
In a stored function or trigger we should ensure that we won't change
a table that is already used by the calling statement.
*/
if (thd->prelocked_mode &&
if (thd->locked_tables_mode >= LTM_PRELOCKED &&
table->lock_type >= TL_WRITE_ALLOW_WRITE)
{
for (TABLE* opentab= thd->open_tables; opentab; opentab= opentab->next)
@ -5540,8 +5526,9 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
if (thd->lex->requires_prelocking())
{
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;
DBUG_PRINT("info",
("thd->locked_tables_mode= LTM_PRELOCKED_UNDER_LOCK_TABLES"));
thd->locked_tables_mode= LTM_PRELOCKED_UNDER_LOCK_TABLES;
}
}

View File

@ -1136,7 +1136,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
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;
@ -1364,7 +1364,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
See also a note on double-check locking usage above.
*/
if (is_disabled() || thd->locked_tables ||
if (is_disabled() || thd->locked_tables_mode ||
thd->variables.query_cache_type == 0 || query_cache_size == 0)
goto err;

View File

@ -995,11 +995,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);
#if defined(ENABLED_DEBUG_SYNC)
/* End the Debug Sync Facility. See debug_sync.cc. */
@ -1742,7 +1738,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;
@ -3036,8 +3032,8 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
*/
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);
@ -3912,7 +3908,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
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);

View File

@ -862,12 +862,17 @@ typedef I_List<Item_change_record> Item_change_list;
/**
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
};
/**
@ -920,19 +925,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
@ -942,29 +941,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.
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.
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.
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.
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.
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;
@ -996,8 +1000,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);

View File

@ -289,7 +289,6 @@ Sensitive_cursor::Sensitive_cursor(THD *thd, select_result *result_arg)
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.
*/
@ -342,7 +341,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.
*/

View File

@ -441,7 +441,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
*/
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;
@ -611,7 +611,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
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))
{
@ -741,7 +742,14 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
{
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);
}
@ -856,7 +864,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
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;
@ -3076,7 +3085,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
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
@ -3142,7 +3151,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);
}
@ -3269,7 +3278,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);
@ -3349,7 +3359,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();
/*
@ -3730,7 +3740,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
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 &

View File

@ -448,7 +448,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
(!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;
@ -469,7 +469,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
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;

View File

@ -163,7 +163,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))
@ -2211,7 +2211,7 @@ mysql_execute_command(THD *thd)
if (res)
break;
if (!thd->locked_tables && lex->protect_against_global_read_lock &&
if (!thd->locked_tables_mode && lex->protect_against_global_read_lock &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
break;
@ -2553,7 +2553,7 @@ case SQLCOM_PREPARE:
TABLE in the same way. That way we avoid that a new table is
created during a gobal read lock.
*/
if (!thd->locked_tables &&
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
res= 1;
@ -2779,7 +2779,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));
@ -2855,7 +2856,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;
@ -3089,7 +3090,7 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (update_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)))
goto error;
DBUG_ASSERT(select_lex->offset_limit == 0);
@ -3126,7 +3127,7 @@ end_with_restore_list:
Protection might have already been risen if its a fall through
from the SQLCOM_UPDATE case above.
*/
if (!thd->locked_tables &&
if (!thd->locked_tables_mode &&
lex->sql_command == SQLCOM_UPDATE_MULTI &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
goto error;
@ -3230,7 +3231,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;
@ -3270,7 +3271,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;
@ -3340,7 +3341,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));
@ -3358,7 +3359,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;
@ -3379,7 +3380,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;
@ -3526,7 +3527,7 @@ end_with_restore_list:
if (check_one_table_access(thd, privilege, all_tables))
goto error;
if (!thd->locked_tables &&
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
goto error;
@ -3615,8 +3616,7 @@ 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;
my_ok(thd);
}
else
@ -3707,7 +3707,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));
@ -3746,7 +3746,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,
@ -3786,7 +3786,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));
@ -4776,7 +4776,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;
@ -7078,7 +7078,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
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;
@ -7103,7 +7103,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
else
{
if (thd && thd->locked_tables)
if (thd && thd->locked_tables_mode)
{
/*
If we are under LOCK TABLES we should have a write

View File

@ -6216,7 +6216,7 @@ static void release_log_entries(partition_info *part_info)
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

View File

@ -44,7 +44,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
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));

View File

@ -1019,7 +1019,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, all_tables, const_tables);
if (!conds && outer_join)
@ -6930,7 +6930,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 ?

View File

@ -1786,7 +1786,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
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);
}
@ -1891,7 +1891,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if (!drop_temporary)
{
if (!thd->locked_tables)
if (!thd->locked_tables_mode)
{
if (lock_table_names(thd, tables))
DBUG_RETURN(1);
@ -1900,7 +1900,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
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))
@ -2001,7 +2001,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
table_type= table->db_type;
if (!drop_temporary)
{
if (thd->locked_tables)
if (thd->locked_tables_mode)
{
if (close_cached_table(thd, table->table))
{
@ -2192,8 +2192,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;
@ -6571,7 +6571,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
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));
@ -6620,7 +6620,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))
{
@ -6847,7 +6847,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
@ -7330,7 +7330,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;
@ -7467,7 +7467,7 @@ view_err:
if (t_table->file->ha_create_handler_files(path, NULL, CHF_INDEX_FLAG,
create_info))
goto err_with_placeholders;
if (thd->locked_tables)
if (thd->locked_tables_mode)
{
if (new_name == table_name && new_db == db)
{
@ -7489,7 +7489,7 @@ view_err:
(void) quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
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);
@ -7536,7 +7536,7 @@ view_err:
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))
{

View File

@ -383,7 +383,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
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 *thd, TABLE_LIST *tables, bool create)
/* 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 *thd, TABLE_LIST *tables, bool create)
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);

View File

@ -978,7 +978,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");

View File

@ -384,7 +384,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
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;
@ -1583,7 +1583,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
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);

View File

@ -1109,7 +1109,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool do_optimize)
ha_release_temporary_latches(thd);
// 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(&param,ER(ER_CANT_LOCK),my_errno);
@ -1219,7 +1219,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool do_optimize)
update_state_info(&param, 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);