From 95efef097ef2f5f69eb882fb8cada3c87b4f1a6f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 Mar 2006 16:00:58 -0500 Subject: [PATCH] BUG #16806: ALTER TABLE fails when creating new field not last in table Moved some code to else path to avoid delete, create, delete, create scenarios. Fixed up the partition info object for some cases where we move from default partitioning in NDB to default partitioning using partitioning. sql/sql_partition.cc: Added a new parameter for partition default handling This is to avoid calling get_no_parts on tables not yet created. Ensure that we don't reuse the old part_info object for any other operation than CREATE TABLE after reading up the frm file. sql/sql_table.cc: Moved some code to else path to avoid delete, create, delete, create scenarios. Fixed up the partition info object for some cases where we move from default partitioning in NDB to default partitioning using partitioning. --- sql/sql_partition.cc | 17 +++++++++++----- sql/sql_table.cc | 46 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 62c48ba37dc..6819920c9e4 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -199,13 +199,15 @@ bool is_name_in_list(char *name, */ bool partition_default_handling(TABLE *table, partition_info *part_info, + bool is_create_table_ind, const char *normalized_path) { DBUG_ENTER("partition_default_handling"); if (part_info->use_default_no_partitions) { - if (table->file->get_no_parts(normalized_path, &part_info->no_parts)) + if (!is_create_table_ind && + table->file->get_no_parts(normalized_path, &part_info->no_parts)) { DBUG_RETURN(TRUE); } @@ -214,7 +216,8 @@ bool partition_default_handling(TABLE *table, partition_info *part_info, part_info->use_default_no_subpartitions) { uint no_parts; - if (table->file->get_no_parts(normalized_path, &no_parts)) + if (!is_create_table_ind && + (table->file->get_no_parts(normalized_path, &no_parts))) { DBUG_RETURN(TRUE); } @@ -1737,9 +1740,12 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table, db_name= &db_name_string[home_dir_length]; tables.db= db_name; - if (!is_create_table_ind) + if (!is_create_table_ind || + (is_create_table_ind && + thd->lex->sql_command != SQLCOM_CREATE_TABLE)) { if (partition_default_handling(table, part_info, + is_create_table_ind, table->s->normalized_path.str)) { DBUG_RETURN(TRUE); @@ -3742,7 +3748,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf, DBUG_PRINT("info", ("default engine = %d, default_db_type = %d", ha_legacy_type(part_info->default_engine_type), ha_legacy_type(default_db_type))); - if (is_create_table_ind) + if (is_create_table_ind && old_lex->sql_command == SQLCOM_CREATE_TABLE) { if (old_lex->like_name) { @@ -3756,7 +3762,8 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf, char *src_table= table_ident->table.str; char buf[FN_REFLEN]; build_table_filename(buf, sizeof(buf), src_db, src_table, ""); - if (partition_default_handling(table, part_info, buf)) + if (partition_default_handling(table, part_info, + FALSE, buf)) { result= TRUE; goto end; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index de7b273d57e..bfec7a56352 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2130,15 +2130,6 @@ bool mysql_create_table_internal(THD *thd, goto err; part_info->part_info_string= part_syntax_buf; part_info->part_info_len= syntax_len; - if (create_info->db_type != engine_type) - { - delete file; - if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, engine_type))) - { - mem_alloc_error(sizeof(handler)); - DBUG_RETURN(TRUE); - } - } if ((!(engine_type->partition_flags && engine_type->partition_flags() & HA_CAN_PARTITION)) || create_info->db_type == &partition_hton) @@ -2155,6 +2146,43 @@ bool mysql_create_table_internal(THD *thd, { DBUG_RETURN(TRUE); } + /* + If we have default number of partitions or subpartitions we + might require to set-up the part_info object such that it + creates a proper .par file. The current part_info object is + only used to create the frm-file and .par-file. + */ + if (part_info->use_default_no_partitions && + part_info->no_parts && + part_info->no_parts != file->get_default_no_partitions(0ULL)) + { + uint i= 0; + bool first= TRUE; + List_iterator part_it(part_info->partitions); + do + { + partition_element *part_elem= part_it++; + if (!first) + part_elem->part_state= PART_TO_BE_DROPPED; + first= FALSE; + } while (++i < part_info->partitions.elements); + } + else if (part_info->is_sub_partitioned() && + part_info->use_default_no_subpartitions && + part_info->no_subparts && + part_info->no_subparts != file->get_default_no_partitions(0ULL)) + { + part_info->no_subparts= file->get_default_no_partitions(0ULL); + } + } + else if (create_info->db_type != engine_type) + { + delete file; + if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, engine_type))) + { + mem_alloc_error(sizeof(handler)); + DBUG_RETURN(TRUE); + } } } #endif