diff --git a/mysql-test/r/partition_hash.result b/mysql-test/r/partition_hash.result index 72f036be099..94fefe77a77 100644 --- a/mysql-test/r/partition_hash.result +++ b/mysql-test/r/partition_hash.result @@ -1,4 +1,16 @@ drop table if exists t1; +CREATE TABLE t1 (c1 INT) +PARTITION BY HASH (c1) +PARTITIONS 15; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +ALTER TABLE t1 COALESCE PARTITION 13; +DROP TABLE t1; +CREATE TABLE t1 (c1 INT) +PARTITION BY LINEAR HASH (c1) +PARTITIONS 5; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +ALTER TABLE t1 COALESCE PARTITION 3; +DROP TABLE t1; create table t1 (a int unsigned) partition by hash(a div 2) partitions 4; diff --git a/mysql-test/t/partition_hash.test b/mysql-test/t/partition_hash.test index 52caaa8c8e9..362d5f747e9 100644 --- a/mysql-test/t/partition_hash.test +++ b/mysql-test/t/partition_hash.test @@ -9,6 +9,22 @@ drop table if exists t1; --enable_warnings +# +# Bug#30822: crash when COALESCE +# +CREATE TABLE t1 (c1 INT) + PARTITION BY HASH (c1) + PARTITIONS 15; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +ALTER TABLE t1 COALESCE PARTITION 13; +DROP TABLE t1; +CREATE TABLE t1 (c1 INT) + PARTITION BY LINEAR HASH (c1) + PARTITIONS 5; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +ALTER TABLE t1 COALESCE PARTITION 3; +DROP TABLE t1; + # # More partition pruning tests, especially on interval walking # diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 5abdf873c81..95eae4378c3 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1531,6 +1531,14 @@ int ha_partition::copy_partitions(ulonglong *copied, ulonglong *deleted) longlong func_value; DBUG_ENTER("ha_partition::copy_partitions"); + if (m_part_info->linear_hash_ind) + { + if (m_part_info->part_type == HASH_PARTITION) + set_linear_hash_mask(m_part_info, m_part_info->no_parts); + else + set_linear_hash_mask(m_part_info, m_part_info->no_subparts); + } + while (reorg_part < m_reorged_parts) { handler *file= m_reorged_file[reorg_part]; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 06b45e3e62a..04b7703ef88 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1402,7 +1402,7 @@ static void set_up_partition_func_pointers(partition_info *part_info) NONE */ -static void set_linear_hash_mask(partition_info *part_info, uint no_parts) +void set_linear_hash_mask(partition_info *part_info, uint no_parts) { uint mask; diff --git a/sql/sql_partition.h b/sql/sql_partition.h index 56f24181b93..282e24f1853 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -65,6 +65,7 @@ int get_part_for_delete(const uchar *buf, const uchar *rec0, void prune_partition_set(const TABLE *table, part_id_range *part_spec); bool check_partition_info(partition_info *part_info,handlerton **eng_type, TABLE *table, handler *file, HA_CREATE_INFO *info); +void set_linear_hash_mask(partition_info *part_info, uint no_parts); bool fix_partition_func(THD *thd, TABLE *table, bool create_table_ind); char *generate_partition_syntax(partition_info *part_info, uint *buf_length, bool use_sql_alloc,