From 2bf914b40e56e51757af6bd99dc6b24d2d00b3da Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Aug 2006 08:52:51 -0400 Subject: [PATCH] BUG#21143: mysqld hangs when using wrong number of subpartitions Rewrote if-statement a bit shorter Added check for subpartitions in REORGANIZE partitions to be of same number as in base table. mysql-test/r/partition_mgm.result: New test case mysql-test/t/partition_mgm.test: New test case sql/ha_partition.cc: Fixed stuff I should done long ago (monty comments) sql/sql_partition.cc: Rewrote if-statement a bit shorter Added check for subpartitions in REORGANIZE partitions to be of same number as in base table. --- mysql-test/r/partition_mgm.result | 10 ++++++++++ mysql-test/t/partition_mgm.test | 17 +++++++++++++++++ sql/ha_partition.cc | 6 ++---- sql/sql_partition.cc | 16 +++++++++------- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/partition_mgm.result b/mysql-test/r/partition_mgm.result index f64ffaff495..9b5a34bda50 100644 --- a/mysql-test/r/partition_mgm.result +++ b/mysql-test/r/partition_mgm.result @@ -1,4 +1,14 @@ DROP TABLE IF EXISTS t1; +create table t1 (a int) +partition by range (a) +subpartition by key (a) +(partition p0 values less than (10) (subpartition sp00, subpartition sp01), +partition p1 values less than (20) (subpartition sp10, subpartition sp11)); +alter table t1 reorganize partition p0 into +(partition p0 values less than (10) (subpartition sp00, +subpartition sp01, subpartition sp02)); +ERROR HY000: Wrong number of subpartitions defined, mismatch with previous setting +drop table t1; CREATE TABLE t1 (f_date DATE, f_varchar VARCHAR(30)) PARTITION BY HASH(CAST(YEAR(f_date) AS SIGNED INTEGER)) PARTITIONS 2; SHOW CREATE TABLE t1; diff --git a/mysql-test/t/partition_mgm.test b/mysql-test/t/partition_mgm.test index 39512de154f..f1a89b28443 100644 --- a/mysql-test/t/partition_mgm.test +++ b/mysql-test/t/partition_mgm.test @@ -2,6 +2,23 @@ --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings + +# +# Bug 21143: mysqld hang when error in number of subparts in +# REORGANIZE command +# +create table t1 (a int) +partition by range (a) +subpartition by key (a) +(partition p0 values less than (10) (subpartition sp00, subpartition sp01), + partition p1 values less than (20) (subpartition sp10, subpartition sp11)); + +-- error ER_PARTITION_WRONG_NO_SUBPART_ERROR +alter table t1 reorganize partition p0 into +(partition p0 values less than (10) (subpartition sp00, +subpartition sp01, subpartition sp02)); +drop table t1; + CREATE TABLE t1 (f_date DATE, f_varchar VARCHAR(30)) PARTITION BY HASH(CAST(YEAR(f_date) AS SIGNED INTEGER)) PARTITIONS 2; SHOW CREATE TABLE t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 615c4bfb1bf..60e838bc243 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5145,13 +5145,12 @@ void ha_partition::print_error(int error, myf errflag) DBUG_ENTER("ha_partition::print_error"); /* Should probably look for my own errors first */ - /* monty: needs to be called for the last used partition ! */ DBUG_PRINT("enter", ("error: %d", error)); if (error == HA_ERR_NO_PARTITION_FOUND) m_part_info->print_no_partition_found(table); else - m_file[0]->print_error(error, errflag); + m_file[m_last_part]->print_error(error, errflag); DBUG_VOID_RETURN; } @@ -5161,8 +5160,7 @@ bool ha_partition::get_error_message(int error, String *buf) DBUG_ENTER("ha_partition::get_error_message"); /* Should probably look for my own errors first */ - /* monty: needs to be called for the last used partition ! */ - DBUG_RETURN(m_file[0]->get_error_message(error, buf)); + DBUG_RETURN(m_file[m_last_part]->get_error_message(error, buf)); } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 73091c0994e..7e59abcd737 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -3471,14 +3471,9 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf, } table->part_info= part_info; table->file->set_part_info(part_info); - if (part_info->default_engine_type == NULL) - { + if (!part_info->default_engine_type) part_info->default_engine_type= default_db_type; - } - else - { - DBUG_ASSERT(part_info->default_engine_type == default_db_type); - } + DBUG_ASSERT(part_info->default_engine_type == default_db_type); part_info->item_free_list= thd->free_list; { @@ -4392,6 +4387,13 @@ state of p1. my_error(ER_REORG_HASH_ONLY_ON_SAME_NO, MYF(0)); DBUG_RETURN(TRUE); } + if (tab_part_info->is_sub_partitioned() && + alt_part_info->no_subparts && + alt_part_info->no_subparts != tab_part_info->no_subparts) + { + my_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR, MYF(0)); + DBUG_RETURN(TRUE); + } check_total_partitions= tab_part_info->no_parts + no_parts_new; check_total_partitions-= no_parts_reorged; if (check_total_partitions > MAX_PARTITIONS)