diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2020-04-27 16:36:03 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2020-04-27 16:36:03 +0300 |
commit | 73aa78ea9d48c433ddb91ef3a7a5b62391d35ac7 (patch) | |
tree | 3a4c202d1f413f1a794e08cefd13ae04f353a23c | |
parent | e174fa9d791a1761fc8b2f92a6ab72f44a9dfc33 (diff) | |
download | mariadb-git-73aa78ea9d48c433ddb91ef3a7a5b62391d35ac7.tar.gz |
MDEV-22155 ALTER add default history partitions name clash on non-default partitions
If any of default names clashes with existing names find next large
enough name gap for the requested number of partitions.
-rw-r--r-- | mysql-test/suite/versioning/r/partition.result | 42 | ||||
-rw-r--r-- | mysql-test/suite/versioning/t/partition.test | 16 | ||||
-rw-r--r-- | sql/partition_info.cc | 13 | ||||
-rw-r--r-- | sql/partition_info.h | 46 | ||||
-rw-r--r-- | sql/sql_partition.cc | 2 |
5 files changed, 109 insertions, 10 deletions
diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 482e70fd8ec..874c617d049 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -1107,3 +1107,45 @@ t1 CREATE TABLE `t1` ( PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE, PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) drop tables t1; +# +# MDEV-22155 ALTER add default history partitions name clash on non-default partitions +# +create or replace table t1 (x int) with system versioning +partition by system_time limit 1 +(partition p2 history, partition p8 history, partition pn current); +alter table t1 add partition partitions 1; +alter table t1 add partition partitions 2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME LIMIT 1 +(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p8` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p4` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p5` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +alter table t1 add partition partitions 8; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME LIMIT 1 +(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p8` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p4` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p5` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p9` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p10` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p11` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p12` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p13` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p14` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p15` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p16` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +drop tables t1; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index c3825590ef2..e64fc09b8e7 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -904,4 +904,20 @@ show create table t1; drop tables t1; +--echo # +--echo # MDEV-22155 ALTER add default history partitions name clash on non-default partitions +--echo # +create or replace table t1 (x int) with system versioning +partition by system_time limit 1 +(partition p2 history, partition p8 history, partition pn current); +alter table t1 add partition partitions 1; +alter table t1 add partition partitions 2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +alter table t1 add partition partitions 8; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +drop tables t1; + --source suite/versioning/common_finish.inc diff --git a/sql/partition_info.cc b/sql/partition_info.cc index f4b7260f8b0..e9dbf2b49c3 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -336,7 +336,8 @@ char *partition_info::create_default_partition_names(THD *thd, uint part_no, { do { - sprintf(move_ptr, "p%u", (start_no + i)); + if (make_partition_name(move_ptr, (start_no + i))) + DBUG_RETURN(NULL); move_ptr+= MAX_PART_NAME_SIZE; } while (++i < num_parts_arg); } @@ -401,17 +402,11 @@ bool partition_info::set_up_default_partitions(THD *thd, handler *file, uint i; char *default_name; bool result= TRUE; - bool alter= false; DBUG_ENTER("partition_info::set_up_default_partitions"); if (part_type == VERSIONING_PARTITION) { - if (start_no > 0) - { - start_no--; - alter= true; - } - else if (use_default_num_partitions) + if (start_no == 0 && use_default_num_partitions) num_parts= 2; use_default_num_partitions= false; } @@ -455,7 +450,7 @@ bool partition_info::set_up_default_partitions(THD *thd, handler *file, default_name+=MAX_PART_NAME_SIZE; if (part_type == VERSIONING_PARTITION) { - if (alter || i < num_parts - 1) { + if (start_no > 0 || i < num_parts - 1) { part_elem->type= partition_element::HISTORY; } else { part_elem->type= partition_element::CURRENT; diff --git a/sql/partition_info.h b/sql/partition_info.h index eb8e53a381a..7ae2d168068 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -34,6 +34,9 @@ typedef bool (*check_constants_func)(THD *thd, partition_info *part_info); struct st_ddl_log_memory_entry; +#define MAX_PART_NAME_SIZE 8 + + struct Vers_part_info : public Sql_alloc { Vers_part_info() : @@ -415,6 +418,7 @@ public: } return NULL; } + uint next_part_no(uint new_parts) const; }; uint32 get_next_partition_id_range(struct st_partition_iter* part_iter); @@ -500,4 +504,46 @@ void partition_info::vers_update_el_ids() } } + +inline +bool make_partition_name(char *move_ptr, uint i) +{ + int res= snprintf(move_ptr, MAX_PART_NAME_SIZE + 1, "p%u", i); + return res < 0 || res > MAX_PART_NAME_SIZE; +} + + +inline +uint partition_info::next_part_no(uint new_parts) const +{ + if (part_type != VERSIONING_PARTITION) + return num_parts; + DBUG_ASSERT(new_parts > 0); + /* Choose first non-occupied name suffix */ + uint32 suffix= num_parts - 1; + DBUG_ASSERT(suffix > 0); + char part_name[MAX_PART_NAME_SIZE + 1]; + List_iterator_fast<partition_element> it(table->part_info->partitions); + for (uint cur_part= 0; cur_part < new_parts; ++cur_part, ++suffix) + { + uint32 cur_suffix= suffix; + if (make_partition_name(part_name, suffix)) + return 0; + partition_element *el; + it.rewind(); + while ((el= it++)) + { + if (0 == my_strcasecmp(&my_charset_latin1, el->partition_name, part_name)) + { + if (make_partition_name(part_name, ++suffix)) + return 0; + it.rewind(); + } + } + if (cur_part > 0 && suffix > cur_suffix) + cur_part= 0; + } + return suffix - new_parts; +} + #endif /* PARTITION_INFO_INCLUDED */ diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 66860762f08..c7b1efc89f3 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5135,7 +5135,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, alt_part_info->part_type= tab_part_info->part_type; alt_part_info->subpart_type= tab_part_info->subpart_type; if (alt_part_info->set_up_defaults_for_partitioning(thd, table->file, 0, - tab_part_info->num_parts)) + tab_part_info->next_part_no(num_new_partitions))) { goto err; } |