summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2007-02-27 22:01:03 +0300
committerunknown <sergefp@mysql.com>2007-02-27 22:01:03 +0300
commitb68a22019e63dbaf7d1918b86c8a456a48dcdc3c (patch)
tree6dca6a83507a775256db33191e2be2b82ddae332
parent5b64b12c7fec848c07475d26a6923dac93a1e5bc (diff)
downloadmariadb-git-b68a22019e63dbaf7d1918b86c8a456a48dcdc3c.tar.gz
BUG#26117 "index_merge sort-union over partitioned table crashes"
Before the fix: ha_partition objects had ha_partition::m_part_info==NULL and that caused crash After: - The new ha_partition::clone() function makes the clones use parent's m_part_info value. - The parent ha_partition object remains responsible for deallocation of m_part_info. mysql-test/r/partition_innodb.result: BUG#26117 "index_merge sort-union over partitioned table crashes" - Testcase mysql-test/t/partition_innodb.test: BUG#26117 "index_merge sort-union over partitioned table crashes" - Testcase
-rw-r--r--mysql-test/r/partition_innodb.result54
-rw-r--r--mysql-test/t/partition_innodb.test58
-rw-r--r--sql/ha_partition.cc21
-rw-r--r--sql/ha_partition.h6
4 files changed, 135 insertions, 4 deletions
diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result
index 8619d0909ee..ffc39820340 100644
--- a/mysql-test/r/partition_innodb.result
+++ b/mysql-test/r/partition_innodb.result
@@ -74,3 +74,57 @@ t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (0) ENGINE = InnoDB) */
drop table t1;
+create table t1
+(
+id int unsigned auto_increment,
+time datetime not null,
+first_name varchar(40),
+last_name varchar(50),
+primary key (id, time),
+index first_index (first_name),
+index last_index (last_name)
+) engine=Innodb partition by range (to_days(time)) (
+partition p1 values less than (to_days('2007-02-07')),
+partition p2 values less than (to_days('2007-02-08')),
+partition p3 values less than MAXVALUE
+);
+insert into t1 (time, first_name, last_name) values ('2007-02-07', 'Q', 'Robert'),
+('2007-02-07', 'Mark', 'Nate'), ('2007-02-07', 'Nate', 'Oscar'),
+('2007-02-07', 'Zack', 'Alice'), ('2007-02-07', 'Jack', 'Kathy'),
+('2007-02-06', 'Alice', 'Alice'), ('2007-02-06', 'Brian', 'Charles'),
+('2007-02-06', 'Charles', 'David'), ('2007-02-06', 'David', 'Eric'),
+('2007-02-07', 'Hector', 'Isaac'), ('2007-02-07', 'Oscar', 'Patricia'),
+('2007-02-07', 'Patricia', 'Q'), ('2007-02-07', 'X', 'Yuri'),
+('2007-02-07', 'Robert', 'Shawn'), ('2007-02-07', 'Kathy', 'Lois'),
+('2007-02-07', 'Eric', 'Francis'), ('2007-02-06', 'Shawn', 'Theron'),
+('2007-02-06', 'U', 'Vincent'), ('2007-02-06', 'Francis', 'George'),
+('2007-02-06', 'George', 'Hector'), ('2007-02-06', 'Vincent', 'Walter'),
+('2007-02-06', 'Walter', 'X'), ('2007-02-07', 'Lois', 'Mark'),
+('2007-02-07', 'Yuri', 'Zack'), ('2007-02-07', 'Isaac', 'Jack'),
+('2007-02-07', 'Sharon', 'Mark'), ('2007-02-07', 'Michael', 'Michelle'),
+('2007-02-07', 'Derick', 'Nathan'), ('2007-02-07', 'Peter', 'Xavier'),
+('2007-02-07', 'Fred', 'Harold'), ('2007-02-07', 'Katherine', 'Lisa'),
+('2007-02-07', 'Tom', 'Rina'), ('2007-02-07', 'Jerry', 'Victor'),
+('2007-02-07', 'Alexander', 'Terry'), ('2007-02-07', 'Justin', 'John'),
+('2007-02-07', 'Greg', 'Ernest'), ('2007-02-07', 'Robert', 'Q'),
+('2007-02-07', 'Nate', 'Mark'), ('2007-02-07', 'Oscar', 'Nate'),
+('2007-02-07', 'Alice', 'Zack'), ('2007-02-07', 'Kathy', 'Jack'),
+('2007-02-06', 'Alice', 'Alice'), ('2007-02-06', 'Charles', 'Brian'),
+('2007-02-06', 'David', 'Charles'), ('2007-02-06', 'Eric', 'David'),
+('2007-02-07', 'Isaac', 'Hector'), ('2007-02-07', 'Patricia', 'Oscar'),
+('2007-02-07', 'Q', 'Patricia'), ('2007-02-07', 'Yuri', 'X'),
+('2007-02-07', 'Shawn', 'Robert'), ('2007-02-07', 'Lois', 'Kathy'),
+('2007-02-07', 'Francis', 'Eric'), ('2007-02-06', 'Theron', 'Shawn'),
+('2007-02-06', 'Vincent', 'U'), ('2007-02-06', 'George', 'Francis'),
+('2007-02-06', 'Hector', 'George'), ('2007-02-06', 'Walter', 'Vincent'),
+('2007-02-06', 'X', 'Walter'), ('2007-02-07', 'Mark', 'Lois'),
+('2007-02-07', 'Zack', 'Yuri'), ('2007-02-07', 'Jack', 'Isaac'),
+('2007-02-07', 'Mark', 'Sharon'), ('2007-02-07', 'Michelle', 'Michael'),
+('2007-02-07', 'Nathan', 'Derick'), ('2007-02-07', 'Xavier', 'Peter'),
+('2007-02-07', 'Harold', 'Fred'), ('2007-02-07', 'Lisa', 'Katherine'),
+('2007-02-07', 'Rina', 'Tom'), ('2007-02-07', 'Victor', 'Jerry'),
+('2007-02-07', 'Terry', 'Alexander'), ('2007-02-07', 'John', 'Justin'),
+('2007-02-07', 'Ernest', 'Greg');
+SELECT * FROM t1 WHERE first_name='Andy' OR last_name='Jake';
+id time first_name last_name
+drop table t1;
diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test
index 782e204742f..f4320c5c56a 100644
--- a/mysql-test/t/partition_innodb.test
+++ b/mysql-test/t/partition_innodb.test
@@ -75,4 +75,62 @@ alter table t1 engine = x;
show create table t1;
drop table t1;
+# BUG#26117: index_merge sort-union over partitioned table crashes
+
+create table t1
+(
+ id int unsigned auto_increment,
+ time datetime not null,
+ first_name varchar(40),
+ last_name varchar(50),
+ primary key (id, time),
+ index first_index (first_name),
+ index last_index (last_name)
+) engine=Innodb partition by range (to_days(time)) (
+ partition p1 values less than (to_days('2007-02-07')),
+ partition p2 values less than (to_days('2007-02-08')),
+ partition p3 values less than MAXVALUE
+);
+
+insert into t1 (time, first_name, last_name) values ('2007-02-07', 'Q', 'Robert'),
+('2007-02-07', 'Mark', 'Nate'), ('2007-02-07', 'Nate', 'Oscar'),
+('2007-02-07', 'Zack', 'Alice'), ('2007-02-07', 'Jack', 'Kathy'),
+('2007-02-06', 'Alice', 'Alice'), ('2007-02-06', 'Brian', 'Charles'),
+('2007-02-06', 'Charles', 'David'), ('2007-02-06', 'David', 'Eric'),
+('2007-02-07', 'Hector', 'Isaac'), ('2007-02-07', 'Oscar', 'Patricia'),
+('2007-02-07', 'Patricia', 'Q'), ('2007-02-07', 'X', 'Yuri'),
+('2007-02-07', 'Robert', 'Shawn'), ('2007-02-07', 'Kathy', 'Lois'),
+('2007-02-07', 'Eric', 'Francis'), ('2007-02-06', 'Shawn', 'Theron'),
+('2007-02-06', 'U', 'Vincent'), ('2007-02-06', 'Francis', 'George'),
+('2007-02-06', 'George', 'Hector'), ('2007-02-06', 'Vincent', 'Walter'),
+('2007-02-06', 'Walter', 'X'), ('2007-02-07', 'Lois', 'Mark'),
+('2007-02-07', 'Yuri', 'Zack'), ('2007-02-07', 'Isaac', 'Jack'),
+('2007-02-07', 'Sharon', 'Mark'), ('2007-02-07', 'Michael', 'Michelle'),
+('2007-02-07', 'Derick', 'Nathan'), ('2007-02-07', 'Peter', 'Xavier'),
+('2007-02-07', 'Fred', 'Harold'), ('2007-02-07', 'Katherine', 'Lisa'),
+('2007-02-07', 'Tom', 'Rina'), ('2007-02-07', 'Jerry', 'Victor'),
+('2007-02-07', 'Alexander', 'Terry'), ('2007-02-07', 'Justin', 'John'),
+('2007-02-07', 'Greg', 'Ernest'), ('2007-02-07', 'Robert', 'Q'),
+('2007-02-07', 'Nate', 'Mark'), ('2007-02-07', 'Oscar', 'Nate'),
+('2007-02-07', 'Alice', 'Zack'), ('2007-02-07', 'Kathy', 'Jack'),
+('2007-02-06', 'Alice', 'Alice'), ('2007-02-06', 'Charles', 'Brian'),
+('2007-02-06', 'David', 'Charles'), ('2007-02-06', 'Eric', 'David'),
+('2007-02-07', 'Isaac', 'Hector'), ('2007-02-07', 'Patricia', 'Oscar'),
+('2007-02-07', 'Q', 'Patricia'), ('2007-02-07', 'Yuri', 'X'),
+('2007-02-07', 'Shawn', 'Robert'), ('2007-02-07', 'Lois', 'Kathy'),
+('2007-02-07', 'Francis', 'Eric'), ('2007-02-06', 'Theron', 'Shawn'),
+('2007-02-06', 'Vincent', 'U'), ('2007-02-06', 'George', 'Francis'),
+('2007-02-06', 'Hector', 'George'), ('2007-02-06', 'Walter', 'Vincent'),
+('2007-02-06', 'X', 'Walter'), ('2007-02-07', 'Mark', 'Lois'),
+('2007-02-07', 'Zack', 'Yuri'), ('2007-02-07', 'Jack', 'Isaac'),
+('2007-02-07', 'Mark', 'Sharon'), ('2007-02-07', 'Michelle', 'Michael'),
+('2007-02-07', 'Nathan', 'Derick'), ('2007-02-07', 'Xavier', 'Peter'),
+('2007-02-07', 'Harold', 'Fred'), ('2007-02-07', 'Lisa', 'Katherine'),
+('2007-02-07', 'Rina', 'Tom'), ('2007-02-07', 'Victor', 'Jerry'),
+('2007-02-07', 'Terry', 'Alexander'), ('2007-02-07', 'John', 'Justin'),
+('2007-02-07', 'Ernest', 'Greg');
+
+SELECT * FROM t1 WHERE first_name='Andy' OR last_name='Jake';
+
+drop table t1;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 87d24207dcd..d54e65c804a 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -158,7 +158,7 @@ static uint alter_table_flags(uint flags __attribute__((unused)))
ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share)
:handler(hton, share), m_part_info(NULL), m_create_handler(FALSE),
- m_is_sub_partitioned(0)
+ m_is_sub_partitioned(0), is_clone(FALSE)
{
DBUG_ENTER("ha_partition::ha_partition(table)");
init_handler_variables();
@@ -180,8 +180,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share)
ha_partition::ha_partition(handlerton *hton, partition_info *part_info)
:handler(hton, NULL), m_part_info(part_info),
m_create_handler(TRUE),
- m_is_sub_partitioned(m_part_info->is_sub_partitioned())
-
+ m_is_sub_partitioned(m_part_info->is_sub_partitioned()), is_clone(FALSE)
{
DBUG_ENTER("ha_partition::ha_partition(part_info)");
init_handler_variables();
@@ -2320,6 +2319,19 @@ err_handler:
DBUG_RETURN(error);
}
+handler *ha_partition::clone(MEM_ROOT *mem_root)
+{
+ handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type);
+ ((ha_partition*)new_handler)->m_part_info= m_part_info;
+ ((ha_partition*)new_handler)->is_clone= TRUE;
+ if (new_handler && !new_handler->ha_open(table,
+ table->s->normalized_path.str,
+ table->db_stat,
+ HA_OPEN_IGNORE_IF_LOCKED))
+ return new_handler;
+ return NULL;
+}
+
/*
Close handler object
@@ -2346,7 +2358,8 @@ int ha_partition::close(void)
DBUG_ENTER("ha_partition::close");
delete_queue(&m_queue);
- bitmap_free(&(m_part_info->used_partitions));
+ if (!is_clone)
+ bitmap_free(&(m_part_info->used_partitions));
file= m_file;
repeat:
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 4fdf325fa06..1069dd058d5 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -132,7 +132,13 @@ private:
THR_LOCK_DATA lock; /* MySQL lock */
PARTITION_SHARE *share; /* Shared lock info */
+ /*
+ TRUE <=> this object was created with ha_partition::clone and doesn't
+ "own" the m_part_info structure.
+ */
+ bool is_clone;
public:
+ handler *clone(MEM_ROOT *mem_root);
virtual void set_part_info(partition_info *part_info)
{
m_part_info= part_info;