mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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:
165
sql/sql_base.cc
165
sql/sql_base.cc
@ -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, ¬_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user