diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a0832285742..d905ddcda31 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -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->locked_tables_mode == LTM_NONE) + if (thd->locked_tables_mode <= LTM_LOCK_TABLES) 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->locked_tables_mode == LTM_NONE) + if (thd->locked_tables_mode <= LTM_LOCK_TABLES) { 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->locked_tables_mode == LTM_NONE) + if (thd->locked_tables_mode <= LTM_LOCK_TABLES) { /* This statement will enter/leave prelocked mode on its own. diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e21a7aa31e5..8665cebc4ed 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1375,6 +1375,7 @@ void close_thread_tables(THD *thd, bool skip_mdl) { TABLE *table; + bool clear_table_lock_option= FALSE; DBUG_ENTER("close_thread_tables"); #ifdef EXTRA_DEBUG @@ -1446,6 +1447,11 @@ 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. + + Note that even if we are in LTM_LOCK_TABLES mode and statement + requires prelocking (e.g. when we are closing tables after + failing ot "open" all tables required for statement execution) + we will exit this function a few lines below. */ if (! thd->lex->requires_prelocking()) DBUG_VOID_RETURN; @@ -1462,7 +1468,7 @@ void close_thread_tables(THD *thd, DBUG_VOID_RETURN; thd->locked_tables_mode= LTM_NONE; - thd->options&= ~OPTION_TABLE_LOCK; + clear_table_lock_option= TRUE; /* Note that we are leaving prelocked mode so we don't need @@ -1502,6 +1508,9 @@ void close_thread_tables(THD *thd, mdl_remove_all_locks(&thd->mdl_context); } + if (clear_table_lock_option) + thd->options&= ~OPTION_TABLE_LOCK; + DBUG_VOID_RETURN; } @@ -5452,6 +5461,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, need to care about THD::locked_tables_root here. */ mysql_unlock_tables(thd, thd->lock); + thd->lock= 0; thd->options&= ~(OPTION_TABLE_LOCK); DBUG_RETURN(-1); }