mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fix for bug #12704 "Server crashes during trigger execution".
This bug occurs when some trigger for table used by DML statement is created or changed while statement was waiting in lock_tables(). In this situation prelocking set which we have calculated becames invalid which can easily lead to errors and even in some cases to crashes. With proposed patch we no longer silently reopen tables in lock_tables(), instead caller of lock_tables() becomes responsible for reopening tables and recalculation of prelocking set.
This commit is contained in:
@ -1094,30 +1094,39 @@ static int mysql_test_update(Prepared_statement *stmt,
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
uint want_privilege;
|
||||
#endif
|
||||
bool need_reopen;
|
||||
DBUG_ENTER("mysql_test_update");
|
||||
|
||||
if (update_precheck(thd, table_list))
|
||||
goto error;
|
||||
|
||||
if (open_tables(thd, &table_list, &table_count, 0))
|
||||
goto error;
|
||||
|
||||
if (table_list->multitable_view)
|
||||
for ( ; ; )
|
||||
{
|
||||
DBUG_ASSERT(table_list->view != 0);
|
||||
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||
/* pass counter value */
|
||||
thd->lex->table_count= table_count;
|
||||
/* convert to multiupdate */
|
||||
DBUG_RETURN(2);
|
||||
if (open_tables(thd, &table_list, &table_count, 0))
|
||||
goto error;
|
||||
|
||||
if (table_list->multitable_view)
|
||||
{
|
||||
DBUG_ASSERT(table_list->view != 0);
|
||||
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||
/* pass counter value */
|
||||
thd->lex->table_count= table_count;
|
||||
/* convert to multiupdate */
|
||||
DBUG_RETURN(2);
|
||||
}
|
||||
|
||||
if (!lock_tables(thd, table_list, table_count, &need_reopen))
|
||||
break;
|
||||
if (!need_reopen)
|
||||
goto error;
|
||||
close_tables_for_reopen(thd, table_list);
|
||||
}
|
||||
|
||||
/*
|
||||
thd->fill_derived_tables() is false here for sure (because it is
|
||||
preparation of PS, so we even do not check it).
|
||||
*/
|
||||
if (lock_tables(thd, table_list, table_count) ||
|
||||
mysql_handle_derived(thd->lex, &mysql_derived_prepare))
|
||||
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare))
|
||||
goto error;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
Reference in New Issue
Block a user