diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-01-28 12:41:14 -0200 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-01-28 12:41:14 -0200 |
commit | d7797f51ecb1c841ba0779887bfc04a873be3a34 (patch) | |
tree | bcdabefe8c705f9ea6c0632a0f9abb92dcc3060b /sql/sql_trigger.cc | |
parent | f89f6c30368ceebc760bb26b8d81811cd2754d11 (diff) | |
download | mariadb-git-d7797f51ecb1c841ba0779887bfc04a873be3a34.tar.gz |
Bug#50423: Crash on second call of a procedure dropping a trigger
The problem was that a DROP TRIGGER statement inside a stored
procedure could cause a crash in subsequent invocations. This
was due to the addition, on the first execution, of a temporary
table reference to the stored procedure query table list. In
a subsequent invocation, there would be a attempt to reinitialize
the temporary table reference, which by then was already gone.
The solution is to backup and reset the query table list each
time a trigger needs to be dropped. This ensures that any temp
changes to the query table list are discarded. It is safe to
do so at this time as drop trigger is restricted from more
complicated scenarios (ie, not allowed within stored functions,
etc).
Diffstat (limited to 'sql/sql_trigger.cc')
-rw-r--r-- | sql/sql_trigger.cc | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index ba0515d38ad..aafb25013f6 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -327,6 +327,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) TABLE *table; bool result= TRUE; String stmt_query; + Query_tables_list backup; bool need_start_waiting= FALSE; DBUG_ENTER("mysql_create_or_drop_trigger"); @@ -393,6 +394,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) { bool if_exists= thd->lex->drop_if_exists; + /* + Protect the query table list from the temporary and potentially + destructive changes necessary to open the trigger's table. + */ + thd->lex->reset_n_backup_query_tables_list(&backup); + if (add_table_for_trigger(thd, thd->lex->spname, if_exists, & tables)) goto end; @@ -512,6 +519,10 @@ end: VOID(pthread_mutex_unlock(&LOCK_open)); + /* Restore the query table list. Used only for drop trigger. */ + if (!create) + thd->lex->restore_backup_query_tables_list(&backup); + if (need_start_waiting) start_waiting_global_read_lock(thd); @@ -1625,10 +1636,6 @@ bool add_table_for_trigger(THD *thd, if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name)) DBUG_RETURN(TRUE); - /* We need to reset statement table list to be PS/SP friendly. */ - lex->query_tables= 0; - lex->query_tables_last= &lex->query_tables; - *table= sp_add_to_query_tables(thd, lex, trg_name->m_db.str, tbl_name.str, TL_IGNORE); |