diff options
-rw-r--r-- | mysql-test/r/partition.result | 7 | ||||
-rw-r--r-- | mysql-test/t/partition.test | 24 | ||||
-rw-r--r-- | sql/sql_table.cc | 39 |
3 files changed, 68 insertions, 2 deletions
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index fa1baaec07e..63abaf6eda4 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1,4 +1,11 @@ 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(); create table t1 (a bigint) partition by range (a) (partition p0 values less than (0xFFFFFFFFFFFFFFFF), diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index f62bb2dcd01..7ef5f66cd9e 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -10,6 +10,30 @@ 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 procedure pz; +drop table t1; + +# +# Bug 19307: CSV engine crashes +# +--error ER_PARTITION_MERGE_ERROR +create table t1 (a int) +engine = csv +partition by list (a) +(partition p0 values in (null)); + +# # BUG 16002: Handle unsigned integer functions properly # --error 1064 diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bf0535567b4..a746e91d318 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; |