From 6f8fb41f213dd34b43ef6f3819b4be12f6b26c01 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 31 Oct 2022 16:17:17 +0300 Subject: [PATCH 1/3] MDEV-29841 More descriptive text for ER_PARTITION_WRONG_TYPE For commands (1) alter table t1 add partition (partition p2); (2) alter table t1 add partition (partition px history); It printed the same error message: Wrong partitioning type, expected type: `SYSTEM_TIME` For (1) it is not clear from the syntax that we are trying to add HASH partition. For (2) it is not clear that the table partitioning is different than SYSTEM_TIME. Now it prints what type we are trying to add to what type of partitioning. --- .../suite/versioning/r/partition.result | 4 +- sql/partition_info.h | 5 + sql/share/errmsg-utf8.txt | 6 +- sql/sql_lex.cc | 4 +- sql/sql_partition.cc | 108 +++++++++++++----- 5 files changed, 90 insertions(+), 37 deletions(-) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 3c20aff4f7f..031ad9b3f3b 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -150,7 +150,7 @@ partition by system_time limit 1; alter table t1 change x big int; create or replace table t1 (i int) engine myisam partition by hash(i) partitions 2; alter table t1 add partition (partition px history); -ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME` +ERROR HY000: Wrong partition type `SYSTEM_TIME` for partitioning by `HASH` ## INSERT, UPDATE, DELETE create or replace table t1 (x int) with system versioning @@ -1105,7 +1105,7 @@ drop table t1; create table t1 (a int) with system versioning partition by system_time (partition p1 history, partition pn current); alter table t1 add partition (partition p2); -ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME` +ERROR HY000: Wrong partition type `HASH` for partitioning by `SYSTEM_TIME` # MDEV-17891 Assertion failures in select_insert::abort_result_set and # mysql_load upon attempt to replace into a full table set @@max_heap_table_size= 1024*1024; diff --git a/sql/partition_info.h b/sql/partition_info.h index e95daec7d31..287aa6d2200 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -429,8 +429,13 @@ public: return NULL; } uint next_part_no(uint new_parts) const; + + int gen_part_type(THD *thd, String *str) const; }; +void part_type_error(THD *thd, partition_info *work_part_info, + const char *part_type, partition_info *tab_part_info); + uint32 get_next_partition_id_range(struct st_partition_iter* part_iter); bool check_partition_dirs(partition_info *part_info); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 76da0b8f598..b61bfbfc199 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -9773,9 +9773,9 @@ ER_UNUSED_23 spa "Nunca debería vd de ver esto" ER_PARTITION_WRONG_TYPE - chi "错误的分区类型,预期类型:%`s" - eng "Wrong partitioning type, expected type: %`s" - spa "Tipo de partición equivocada, tipo esperado: %`s" + chi "错误的分区类型,预期类型:%`s for partitioning by %`s" + eng "Wrong partition type %`s for partitioning by %`s" + spa "Tipo de partición equivocada, tipo esperado: %`s for partitioning by %`s" WARN_VERS_PART_FULL chi "版本化表%`s.%`s:partition%`s已满,添加更多历史分区(out of %s)" diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5a9e9ee1a62..0ba5baea1c9 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9739,7 +9739,7 @@ bool LEX::part_values_current(THD *thd) { if (unlikely(part_info->part_type != VERSIONING_PARTITION)) { - my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); + part_type_error(thd, NULL, "CURRENT", part_info); return true; } } @@ -9766,7 +9766,7 @@ bool LEX::part_values_history(THD *thd) { if (unlikely(part_info->part_type != VERSIONING_PARTITION)) { - my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); + part_type_error(thd, NULL, "HISTORY", part_info); return true; } } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 70de87afc1a..130484e4a0b 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2455,7 +2455,7 @@ end: @retval != 0 Failure */ -static int add_key_with_algorithm(String *str, partition_info *part_info) +static int add_key_with_algorithm(String *str, const partition_info *part_info) { int err= 0; err+= str->append(STRING_WITH_LEN("KEY ")); @@ -2484,6 +2484,78 @@ char *generate_partition_syntax_for_frm(THD *thd, partition_info *part_info, return res; } + +/* + Generate the partition type syntax from the partition data structure. + + @return Operation status. + @retval 0 Success + @retval > 0 Failure + @retval -1 Fatal error +*/ + +int partition_info::gen_part_type(THD *thd, String *str) const +{ + int err= 0; + switch (part_type) + { + case RANGE_PARTITION: + err+= str->append(STRING_WITH_LEN("RANGE ")); + break; + case LIST_PARTITION: + err+= str->append(STRING_WITH_LEN("LIST ")); + break; + case HASH_PARTITION: + if (linear_hash_ind) + err+= str->append(STRING_WITH_LEN("LINEAR ")); + if (list_of_part_fields) + { + err+= add_key_with_algorithm(str, this); + err+= add_part_field_list(thd, str, part_field_list); + } + else + err+= str->append(STRING_WITH_LEN("HASH ")); + break; + case VERSIONING_PARTITION: + err+= str->append(STRING_WITH_LEN("SYSTEM_TIME ")); + break; + default: + DBUG_ASSERT(0); + /* We really shouldn't get here, no use in continuing from here */ + my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATAL)); + return -1; + } + return err; +} + + +void part_type_error(THD *thd, partition_info *work_part_info, + const char *part_type, + partition_info *tab_part_info) +{ + StringBuffer<256> tab_part_type; + if (tab_part_info->gen_part_type(thd, &tab_part_type) < 0) + return; + tab_part_type.length(tab_part_type.length() - 1); + if (work_part_info) + { + DBUG_ASSERT(!part_type); + StringBuffer<256> work_part_type; + if (work_part_info->gen_part_type(thd, &work_part_type) < 0) + return; + work_part_type.length(work_part_type.length() - 1); + my_error(ER_PARTITION_WRONG_TYPE, MYF(0), work_part_type.c_ptr(), + tab_part_type.c_ptr()); + } + else + { + DBUG_ASSERT(part_type); + my_error(ER_PARTITION_WRONG_TYPE, MYF(0), part_type, + tab_part_type.c_ptr()); + } +} + + /* Generate the partition syntax from the partition data structure. Useful for support of generating defaults, SHOW CREATE TABLES @@ -2527,34 +2599,10 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info, DBUG_ENTER("generate_partition_syntax"); err+= str.append(STRING_WITH_LEN(" PARTITION BY ")); - switch (part_info->part_type) - { - case RANGE_PARTITION: - err+= str.append(STRING_WITH_LEN("RANGE ")); - break; - case LIST_PARTITION: - err+= str.append(STRING_WITH_LEN("LIST ")); - break; - case HASH_PARTITION: - if (part_info->linear_hash_ind) - err+= str.append(STRING_WITH_LEN("LINEAR ")); - if (part_info->list_of_part_fields) - { - err+= add_key_with_algorithm(&str, part_info); - err+= add_part_field_list(thd, &str, part_info->part_field_list); - } - else - err+= str.append(STRING_WITH_LEN("HASH ")); - break; - case VERSIONING_PARTITION: - err+= str.append(STRING_WITH_LEN("SYSTEM_TIME ")); - break; - default: - DBUG_ASSERT(0); - /* We really shouldn't get here, no use in continuing from here */ - my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATAL)); - DBUG_RETURN(NULL); - } + int err2= part_info->gen_part_type(thd, &str); + if (err2 < 0) + DBUG_RETURN(NULL); + err+= err2; if (part_info->part_type == VERSIONING_PARTITION) { Vers_part_info *vers_info= part_info->vers_info; @@ -5044,7 +5092,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, else if (thd->work_part_info->part_type == VERSIONING_PARTITION || tab_part_info->part_type == VERSIONING_PARTITION) { - my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); + part_type_error(thd, thd->work_part_info, NULL, tab_part_info); } else { From 2092881984117b9e10b5d2afc8d387ec90199287 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 31 Oct 2022 16:29:15 +0300 Subject: [PATCH 2/3] MDEV-29841 Partition by system_time can be converted into table but not back Wrong error code was returned because of prematurely tested condition for wrong partition type. Now the condition for CONVERT IN is tested first. --- mysql-test/suite/versioning/r/partition.result | 9 +++++++++ mysql-test/suite/versioning/t/partition.test | 10 ++++++++++ sql/sql_partition.cc | 14 +++++++------- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 031ad9b3f3b..015ceae983f 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -2049,6 +2049,15 @@ t1 CREATE TABLE `t1` ( PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) drop tables t1, tp1; # +# MDEV-29841 Partition by system_time can be converted into table but not back +# +create or replace table t (a int) with system versioning +partition by system_time limit 10 partitions 3; +alter table t convert partition p0 to table tp; +alter table t convert table tp to partition p0; +ERROR HY000: CONVERT TABLE TO PARTITION can only be used on RANGE/LIST partitions +drop tables t, tp; +# # End of 10.7 tests # set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index de00bdce524..70685205bd0 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -1677,6 +1677,16 @@ show create table t1; drop tables t1, tp1; } +--echo # +--echo # MDEV-29841 Partition by system_time can be converted into table but not back +--echo # +create or replace table t (a int) with system versioning +partition by system_time limit 10 partitions 3; +alter table t convert partition p0 to table tp; +--error ER_ONLY_ON_RANGE_LIST_PARTITION +alter table t convert table tp to partition p0; +drop tables t, tp; + --echo # --echo # End of 10.7 tests --echo # diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 130484e4a0b..d7078278557 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5057,6 +5057,13 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, if ((alter_info->partition_flags & ALTER_PARTITION_ADD) || (alter_info->partition_flags & ALTER_PARTITION_REORGANIZE)) { + if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN) && + !(tab_part_info->part_type == RANGE_PARTITION || + tab_part_info->part_type == LIST_PARTITION)) + { + my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "CONVERT TABLE TO"); + goto err; + } if (thd->work_part_info->part_type != tab_part_info->part_type) { if (thd->work_part_info->part_type == NOT_A_PARTITION) @@ -5126,13 +5133,6 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, } if (alter_info->partition_flags & ALTER_PARTITION_ADD) { - if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN) && - !(tab_part_info->part_type == RANGE_PARTITION || - tab_part_info->part_type == LIST_PARTITION)) - { - my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "CONVERT TABLE TO"); - goto err; - } if (*fast_alter_table && thd->locked_tables_mode) { MEM_ROOT *old_root= thd->mem_root; From b75ad1af91261841fdd64d0c81749319fc195940 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 7 Nov 2022 11:07:47 -0500 Subject: [PATCH 3/3] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cbe0f0b08c3..d3418c3d869 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=7 -MYSQL_VERSION_PATCH=7 +MYSQL_VERSION_PATCH=8 SERVER_MATURITY=stable