summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2020-04-27 16:36:03 +0300
committerAleksey Midenkov <midenok@gmail.com>2020-04-27 16:36:03 +0300
commit73aa78ea9d48c433ddb91ef3a7a5b62391d35ac7 (patch)
tree3a4c202d1f413f1a794e08cefd13ae04f353a23c
parente174fa9d791a1761fc8b2f92a6ab72f44a9dfc33 (diff)
downloadmariadb-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.result42
-rw-r--r--mysql-test/suite/versioning/t/partition.test16
-rw-r--r--sql/partition_info.cc13
-rw-r--r--sql/partition_info.h46
-rw-r--r--sql/sql_partition.cc2
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;
}