diff options
-rw-r--r-- | mysql-test/r/partition.result | 8 | ||||
-rw-r--r-- | mysql-test/t/partition.test | 14 | ||||
-rw-r--r-- | sql/sql_table.cc | 39 |
3 files changed, 59 insertions, 2 deletions
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 025d9f46412..d8cb474fefc 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1,5 +1,13 @@ drop table if exists t1; 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 partition by list (a) (partition p0 values in (null)); diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index a7f2e1c0b3e..6658064c094 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -10,6 +10,20 @@ drop table if exists t1; --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 # --error ER_PARTITION_MERGE_ERROR diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4bc84521f2a..55afd7a5a04 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3002,6 +3002,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 SYNOPSIS @@ -3030,7 +3055,7 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) bool mysql_create_table_internal(THD *thd, const char *db, const char *table_name, - HA_CREATE_INFO *create_info, + HA_CREATE_INFO *lex_create_info, List<create_field> &fields, List<Key> &keys,bool internal_tmp_table, uint select_field_count) @@ -3040,10 +3065,15 @@ bool mysql_create_table_internal(THD *thd, const char *alias; uint db_options, key_count; KEY *key_info_buffer; + HA_CREATE_INFO *create_info; handler *file; bool error= TRUE; 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 */ if (!fields.elements) { @@ -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, - HA_CREATE_INFO *create_info, + HA_CREATE_INFO *lex_create_info, TABLE_LIST *table_list, List<create_field> &fields, List<Key> &keys, uint order_num, ORDER *order, @@ -4907,6 +4937,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ulonglong next_insert_id; uint db_create_options, used_fields; handlerton *old_db_type, *new_db_type; + HA_CREATE_INFO *create_info; uint need_copy_table= 0; bool no_table_reopen= FALSE, varchar= FALSE; #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -4932,6 +4963,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, LINT_INIT(index_drop_buffer); thd->proc_info="init"; + if (!(create_info= copy_create_info(lex_create_info))) + { + DBUG_RETURN(TRUE); + } table_name=table_list->table_name; alias= (lower_case_table_names == 2) ? table_list->alias : table_name; db=table_list->db; |