BUG#19309: Crash if double procedural alter

parent 2746b739
drop table if exists t1; drop table if exists t1;
create table t1 (a int) create table t1 (a int)
partition by list (a)
(partition p0 values in (1));
create procedure pz()
alter table t1 engine = myisam;
call pz();
call pz();
drop table t1;
create table t1 (a int)
engine = csv engine = csv
partition by list (a) partition by list (a)
(partition p0 values in (null)); (partition p0 values in (null));
......
...@@ -9,6 +9,20 @@ ...@@ -9,6 +9,20 @@
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
#
# Bug 19309 Partitions: Crash if double procedural alter
#
create table t1 (a int)
partition by list (a)
(partition p0 values in (1));
create procedure pz()
alter table t1 engine = myisam;
call pz();
call pz();
drop table t1;
# #
# Bug 19307: CSV engine crashes # Bug 19307: CSV engine crashes
# #
......
...@@ -3001,6 +3001,31 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) ...@@ -3001,6 +3001,31 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field)
} }
/*
Copy HA_CREATE_INFO struct
SYNOPSIS
copy_create_info()
lex_create_info The create_info struct setup by parser
RETURN VALUES
> 0 A pointer to a copy of the lex_create_info
0 Memory allocation error
DESCRIPTION
Allocate memory for copy of HA_CREATE_INFO structure from parser
to ensure we can reuse the parser struct in stored procedures
and prepared statements.
*/
static HA_CREATE_INFO *copy_create_info(HA_CREATE_INFO *lex_create_info)
{
HA_CREATE_INFO *create_info;
if (!(create_info= (HA_CREATE_INFO*)sql_alloc(sizeof(HA_CREATE_INFO))))
mem_alloc_error(sizeof(HA_CREATE_INFO));
else
memcpy((void*)create_info, (void*)lex_create_info, sizeof(HA_CREATE_INFO));
return create_info;
}
/* /*
Create a table Create a table
...@@ -3030,7 +3055,7 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) ...@@ -3030,7 +3055,7 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field)
bool mysql_create_table_internal(THD *thd, bool mysql_create_table_internal(THD *thd,
const char *db, const char *table_name, const char *db, const char *table_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *lex_create_info,
List<create_field> &fields, List<create_field> &fields,
List<Key> &keys,bool internal_tmp_table, List<Key> &keys,bool internal_tmp_table,
uint select_field_count) uint select_field_count)
...@@ -3040,10 +3065,15 @@ bool mysql_create_table_internal(THD *thd, ...@@ -3040,10 +3065,15 @@ bool mysql_create_table_internal(THD *thd,
const char *alias; const char *alias;
uint db_options, key_count; uint db_options, key_count;
KEY *key_info_buffer; KEY *key_info_buffer;
HA_CREATE_INFO *create_info;
handler *file; handler *file;
bool error= TRUE; bool error= TRUE;
DBUG_ENTER("mysql_create_table_internal"); DBUG_ENTER("mysql_create_table_internal");
if (!(create_info= copy_create_info(lex_create_info)))
{
DBUG_RETURN(TRUE);
}
/* Check for duplicate fields and check type of table to create */ /* Check for duplicate fields and check type of table to create */
if (!fields.elements) if (!fields.elements)
{ {
...@@ -4889,7 +4919,7 @@ static uint compare_tables(TABLE *table, List<create_field> *create_list, ...@@ -4889,7 +4919,7 @@ static uint compare_tables(TABLE *table, List<create_field> *create_list,
*/ */
bool mysql_alter_table(THD *thd,char *new_db, char *new_name, bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *lex_create_info,
TABLE_LIST *table_list, TABLE_LIST *table_list,
List<create_field> &fields, List<Key> &keys, List<create_field> &fields, List<Key> &keys,
uint order_num, ORDER *order, uint order_num, ORDER *order,
...@@ -4907,6 +4937,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -4907,6 +4937,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
ulonglong next_insert_id; ulonglong next_insert_id;
uint db_create_options, used_fields; uint db_create_options, used_fields;
handlerton *old_db_type, *new_db_type; handlerton *old_db_type, *new_db_type;
HA_CREATE_INFO *create_info;
uint need_copy_table= 0; uint need_copy_table= 0;
bool no_table_reopen= FALSE, varchar= FALSE; bool no_table_reopen= FALSE, varchar= FALSE;
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
...@@ -4932,6 +4963,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -4932,6 +4963,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
LINT_INIT(index_drop_buffer); LINT_INIT(index_drop_buffer);
thd->proc_info="init"; thd->proc_info="init";
if (!(create_info= copy_create_info(lex_create_info)))
{
DBUG_RETURN(TRUE);
}
table_name=table_list->table_name; table_name=table_list->table_name;
alias= (lower_case_table_names == 2) ? table_list->alias : table_name; alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
db=table_list->db; db=table_list->db;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment