summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/partition_mgm.result12
-rw-r--r--mysql-test/t/partition_mgm.test16
-rw-r--r--sql/ha_partition.cc15
-rw-r--r--sql/ha_partition.h1
4 files changed, 39 insertions, 5 deletions
diff --git a/mysql-test/r/partition_mgm.result b/mysql-test/r/partition_mgm.result
index 0f2c8c57872..f64ffaff495 100644
--- a/mysql-test/r/partition_mgm.result
+++ b/mysql-test/r/partition_mgm.result
@@ -24,3 +24,15 @@ hello/master-data/test/t1#P#p0.MYD
hello/master-data/test/t1#P#p0.MYI
hello/master-data/test/t1.frm
hello/master-data/test/t1.par
+drop table t1;
+create table t1 (a int)
+partition by list (a)
+subpartition by hash (a)
+(partition p11 values in (1,2),
+partition p12 values in (3,4));
+alter table t1 REORGANIZE partition p11, p12 INTO
+(partition p1 values in (1,2,3,4));
+alter table t1 REORGANIZE partition p1 INTO
+(partition p11 values in (1,2),
+partition p12 values in (3,4));
+drop table t1;
diff --git a/mysql-test/t/partition_mgm.test b/mysql-test/t/partition_mgm.test
index cfb76192de4..39512de154f 100644
--- a/mysql-test/t/partition_mgm.test
+++ b/mysql-test/t/partition_mgm.test
@@ -12,7 +12,21 @@ ALTER TABLE t1 COALESCE PARTITION 1;
SHOW CREATE TABLE t1;
--replace_result $MYSQLTEST_VARDIR "hello"
--exec ls $MYSQLTEST_VARDIR/master-data/test/t1*
+drop table t1;
+#
+# Bug 20767: REORGANIZE partition crashes
+#
+create table t1 (a int)
+partition by list (a)
+subpartition by hash (a)
+(partition p11 values in (1,2),
+ partition p12 values in (3,4));
+alter table t1 REORGANIZE partition p11, p12 INTO
+(partition p1 values in (1,2,3,4));
+alter table t1 REORGANIZE partition p1 INTO
+(partition p11 values in (1,2),
+ partition p12 values in (3,4));
-
+drop table t1;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 3d7f8fc5fb2..89078da0773 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -204,6 +204,7 @@ void ha_partition::init_handler_variables()
m_name_buffer_ptr= NULL;
m_engine_array= NULL;
m_file= NULL;
+ m_file_tot_parts= 0;
m_reorged_file= NULL;
m_new_file= NULL;
m_reorged_parts= 0;
@@ -1231,7 +1232,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
uint no_parts= m_part_info->partitions.elements;
uint no_subparts= m_part_info->no_subparts;
uint i= 0;
- uint no_remain_partitions, part_count;
+ uint no_remain_partitions, part_count, orig_count;
handler **new_file_array;
int error= 1;
bool first;
@@ -1266,10 +1267,10 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
} while (++i < no_parts);
}
if (m_reorged_parts &&
- !(m_reorged_file= (handler**)sql_calloc(sizeof(partition_element*)*
+ !(m_reorged_file= (handler**)sql_calloc(sizeof(handler*)*
(m_reorged_parts + 1))))
{
- mem_alloc_error(sizeof(partition_element*)*(m_reorged_parts+1));
+ mem_alloc_error(sizeof(handler*)*(m_reorged_parts+1));
DBUG_RETURN(ER_OUTOFMEMORY);
}
@@ -1340,6 +1341,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
ones used to be.
*/
first= FALSE;
+ DBUG_ASSERT(i + m_reorged_parts <= m_file_tot_parts);
memcpy((void*)m_reorged_file, &m_file[i*no_subparts],
sizeof(handler*)*m_reorged_parts*no_subparts);
}
@@ -1353,15 +1355,18 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
*/
i= 0;
part_count= 0;
+ orig_count= 0;
part_it.rewind();
do
{
partition_element *part_elem= part_it++;
if (part_elem->part_state == PART_NORMAL)
{
- memcpy((void*)&new_file_array[part_count], (void*)&m_file[i],
+ DBUG_ASSERT(orig_count + no_subparts <= m_file_tot_parts);
+ memcpy((void*)&new_file_array[part_count], (void*)&m_file[orig_count],
sizeof(handler*)*no_subparts);
part_count+= no_subparts;
+ orig_count+= no_subparts;
}
else if (part_elem->part_state == PART_CHANGED ||
part_elem->part_state == PART_TO_BE_ADDED)
@@ -1959,6 +1964,7 @@ bool ha_partition::create_handlers(MEM_ROOT *mem_root)
if (!(m_file= (handler **) alloc_root(mem_root, alloc_len)))
DBUG_RETURN(TRUE);
+ m_file_tot_parts= m_tot_parts;
bzero((char*) m_file, alloc_len);
for (i= 0; i < m_tot_parts; i++)
{
@@ -2008,6 +2014,7 @@ bool ha_partition::new_handlers_from_part_info(MEM_ROOT *mem_root)
mem_alloc_error(alloc_len);
goto error_end;
}
+ m_file_tot_parts= m_tot_parts;
bzero((char*) m_file, alloc_len);
DBUG_ASSERT(m_part_info->no_parts > 0);
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index b838bc599f0..21f7e1c8ddf 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -56,6 +56,7 @@ private:
char *m_name_buffer_ptr; // Pointer to first partition name
handlerton **m_engine_array; // Array of types of the handlers
handler **m_file; // Array of references to handler inst.
+ uint m_file_tot_parts; // Debug
handler **m_new_file; // Array of references to new handlers
handler **m_reorged_file; // Reorganised partitions
handler **m_added_file; // Added parts kept for errors