1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug#21136 CREATE TABLE SELECT within CREATE TABLE SELECT causes server crash

When CREATE TEMPORARY TABLE .. SELECT is invoked from a stored function
which in turn is called from CREATE TABLE SELECT causes a memory leak
because the inner create temporary table overrides the outter extra_lock
reference when locking the table.

The solution is to simply not overrride the extra_lock by only using the
extra_lock for a non-temporary table lock.
This commit is contained in:
davi@moksha.local
2007-09-28 18:25:47 -03:00
parent 2a70d6fa97
commit ae079ec427
3 changed files with 59 additions and 7 deletions

View File

@ -3427,6 +3427,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
int
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
MYSQL_LOCK *extra_lock= NULL;
DBUG_ENTER("select_create::prepare");
TABLEOP_HOOKS *hook_ptr= NULL;
@ -3496,9 +3497,21 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
if (!(table= create_table_from_items(thd, create_info, create_table,
alter_info, &values,
&thd->extra_lock, hook_ptr)))
&extra_lock, hook_ptr)))
DBUG_RETURN(-1); // abort() deletes table
if (extra_lock)
{
DBUG_ASSERT(m_plock == NULL);
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
m_plock= &m_lock;
else
m_plock= &thd->extra_lock;
*m_plock= extra_lock;
}
if (table->s->fields < values.elements)
{
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
@ -3637,10 +3650,10 @@ bool select_create::send_eof()
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
if (thd->extra_lock)
if (m_plock)
{
mysql_unlock_tables(thd, thd->extra_lock);
thd->extra_lock=0;
mysql_unlock_tables(thd, *m_plock);
m_plock= 0;
}
}
return tmp;
@ -3675,10 +3688,10 @@ void select_create::abort()
if (thd->current_stmt_binlog_row_based)
ha_rollback_stmt(thd);
if (thd->extra_lock)
if (m_plock)
{
mysql_unlock_tables(thd, thd->extra_lock);
thd->extra_lock=0;
mysql_unlock_tables(thd, *m_plock);
m_plock= 0;
}
if (table)