From 55e7f4503e60183d84f199edb2550c5b88f79dcb Mon Sep 17 00:00:00 2001 From: "holyfoot@deer.(none)" <> Date: Thu, 15 Dec 2005 15:24:35 +0400 Subject: [PATCH] bug #15521 (Cannot reorganise a partition with a new name equal to the old name) --- mysql-test/r/partition.result | 34 +++++++++++++++++ mysql-test/r/partition_mgm_err.result | 2 +- mysql-test/t/partition.test | 31 +++++++++++++++ mysql-test/t/partition_mgm_err.test | 2 +- sql/handler.h | 3 ++ sql/sql_partition.cc | 55 +++++++++++++++++++++++++++ sql/sql_table.cc | 4 +- 7 files changed, 128 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index f0500c639a3..58f02681682 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -114,3 +114,37 @@ CREATE TABLE `t1` ( SELECT * FROM t1; id drop table t1; +create table t1 +(a int) +partition by range (a) +( partition p0 values less than(10), +partition p1 values less than (20), +partition p2 values less than maxvalue); +alter table t1 reorganise partition p2 into (partition p2 values less than (30)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (10) ENGINE = MyISAM, PARTITION p1 VALUES LESS THAN (20) ENGINE = MyISAM, PARTITION p2 VALUES LESS THAN (30) ENGINE = MyISAM) +drop table t1; +CREATE TABLE t1 (a int, b int) +PARTITION BY RANGE (a) +(PARTITION x0 VALUES LESS THAN (2), +PARTITION x1 VALUES LESS THAN (4), +PARTITION x2 VALUES LESS THAN (6), +PARTITION x3 VALUES LESS THAN (8), +PARTITION x4 VALUES LESS THAN (10), +PARTITION x5 VALUES LESS THAN (12), +PARTITION x6 VALUES LESS THAN (14), +PARTITION x7 VALUES LESS THAN (16), +PARTITION x8 VALUES LESS THAN (18), +PARTITION x9 VALUES LESS THAN (20)); +ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2 INTO +(PARTITION x1 VALUES LESS THAN (6)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY RANGE (a) (PARTITION x1 VALUES LESS THAN (6) ENGINE = MyISAM, PARTITION x3 VALUES LESS THAN (8) ENGINE = MyISAM, PARTITION x4 VALUES LESS THAN (10) ENGINE = MyISAM, PARTITION x5 VALUES LESS THAN (12) ENGINE = MyISAM, PARTITION x6 VALUES LESS THAN (14) ENGINE = MyISAM, PARTITION x7 VALUES LESS THAN (16) ENGINE = MyISAM, PARTITION x8 VALUES LESS THAN (18) ENGINE = MyISAM, PARTITION x9 VALUES LESS THAN (20) ENGINE = MyISAM) +drop table t1; diff --git a/mysql-test/r/partition_mgm_err.result b/mysql-test/r/partition_mgm_err.result index ca56dc44666..01709e726bd 100644 --- a/mysql-test/r/partition_mgm_err.result +++ b/mysql-test/r/partition_mgm_err.result @@ -26,7 +26,7 @@ ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10 INTO (PARTITION x11 VALUES LESS THAN (22)); ERROR HY000: More partitions to reorganise than there are partitions ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2 INTO -(PARTITION x1 VALUES LESS THAN (6)); +(PARTITION x3 VALUES LESS THAN (6)); ERROR HY000: All partitions must have unique names in the table ALTER TABLE t1 REORGANISE PARTITION x0, x2 INTO (PARTITION x11 VALUES LESS THAN (2)); diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 8f20f7be536..8b1c3f58071 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -172,3 +172,34 @@ SELECT * FROM t1; drop table t1; +# +# BUG 15221 (Cannot reorganize with the same name) +# +create table t1 +(a int) +partition by range (a) + ( partition p0 values less than(10), + partition p1 values less than (20), + partition p2 values less than maxvalue); + +alter table t1 reorganise partition p2 into (partition p2 values less than (30)); +show create table t1; +drop table t1; + +CREATE TABLE t1 (a int, b int) +PARTITION BY RANGE (a) +(PARTITION x0 VALUES LESS THAN (2), + PARTITION x1 VALUES LESS THAN (4), + PARTITION x2 VALUES LESS THAN (6), + PARTITION x3 VALUES LESS THAN (8), + PARTITION x4 VALUES LESS THAN (10), + PARTITION x5 VALUES LESS THAN (12), + PARTITION x6 VALUES LESS THAN (14), + PARTITION x7 VALUES LESS THAN (16), + PARTITION x8 VALUES LESS THAN (18), + PARTITION x9 VALUES LESS THAN (20)); + +ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2 INTO +(PARTITION x1 VALUES LESS THAN (6)); +show create table t1; +drop table t1; diff --git a/mysql-test/t/partition_mgm_err.test b/mysql-test/t/partition_mgm_err.test index 1d9d8a79f3d..92848fc135e 100644 --- a/mysql-test/t/partition_mgm_err.test +++ b/mysql-test/t/partition_mgm_err.test @@ -43,7 +43,7 @@ ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10 INTO --error ER_SAME_NAME_PARTITION ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2 INTO -(PARTITION x1 VALUES LESS THAN (6)); +(PARTITION x3 VALUES LESS THAN (6)); --error ER_CONSECUTIVE_REORG_PARTITIONS ALTER TABLE t1 REORGANISE PARTITION x0, x2 INTO diff --git a/sql/handler.h b/sql/handler.h index b4b90cbfaa8..5674698487c 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -717,6 +717,9 @@ typedef struct st_ha_check_opt bool is_partition_in_list(char *part_name, List list_part_names); bool is_partitions_in_table(partition_info *new_part_info, partition_info *old_part_info); +bool check_reorganise_list(partition_info *new_part_info, + partition_info *old_part_info, + List list_part_names); bool set_up_defaults_for_partitioning(partition_info *part_info, handler *file, ulonglong max_rows, diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index dd4f2d9246a..8571e39d9b8 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -189,6 +189,61 @@ bool is_partitions_in_table(partition_info *new_part_info, } +/* + Check that the reorganized table will not have duplicate partitions. + + SYNOPSIS + check_reorganise_list() + new_part_info New partition info + old_part_info Old partition info + list_part_names The list of partition names that will go away and can be reused in the + new table. + + RETURN VALUES + TRUE Inacceptable name conflict detected. + FALSE New names are OK. + + DESCRIPTION + Can handle that the 'new_part_info' and 'old_part_info' the same + in which case it checks that the list of names in the partitions + doesn't contain any duplicated names. +*/ + +bool check_reorganise_list(partition_info *new_part_info, + partition_info *old_part_info, + List list_part_names) +{ + uint new_count, old_count; + uint no_new_parts= new_part_info->partitions.elements; + uint no_old_parts= old_part_info->partitions.elements; + List_iterator new_parts_it(new_part_info->partitions); + bool same_part_info= (new_part_info == old_part_info); + DBUG_ENTER("check_reorganise_list"); + + new_count= 0; + do + { + List_iterator old_parts_it(old_part_info->partitions); + char *new_name= (new_parts_it++)->partition_name; + new_count++; + old_count= 0; + do + { + char *old_name= (old_parts_it++)->partition_name; + old_count++; + if (same_part_info && old_count == new_count) + break; + if (!(my_strcasecmp(system_charset_info, old_name, new_name))) + { + if (!is_partition_in_list(old_name, list_part_names)) + DBUG_RETURN(TRUE); + } + } while (old_count < no_old_parts); + } while (new_count < no_new_parts); + DBUG_RETURN(FALSE); +} + + /* A useful routine used by update_row for partition handlers to calculate the partition ids of the old and the new record. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 275cf847a99..a74a550679f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3832,7 +3832,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "REORGANISE"); DBUG_RETURN(TRUE); } - if (is_partitions_in_table(alt_part_info, tab_part_info)) + if (check_reorganise_list(alt_part_info, tab_part_info, + alter_info->partition_names)) { my_error(ER_SAME_NAME_PARTITION, MYF(0)); DBUG_RETURN(TRUE); @@ -3901,6 +3902,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } } partition_changed= TRUE; + tab_part_info->no_parts= tab_part_info->partitions.elements; create_info->db_type= DB_TYPE_PARTITION_DB; thd->lex->part_info= tab_part_info; if (alter_info->flags == ALTER_ADD_PARTITION ||