From: Date: December 28 2008 12:34pm Subject: bzr commit into mysql-5.1-bugteam branch (mattias.jonsson:2754) Bug#40972 List-Archive: http://lists.mysql.com/commits/62384 X-Bug: 40972 Message-Id: <20081228113401.BB1ED1A49439@witty.localhost> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7BIT #At file:///Users/mattiasj/clones/bzrroot/b40972-51-bugteam/ based on revid:sergey.glukhov@stripped 2754 Mattias Jonsson 2008-12-28 Bug#40972: some sql execution lead the whole databse crashing Problem was an errornous date that lead to end partition was before the start, leading to a crash. Solution was to check greater or equal instead of only equal between start and end partition. NOTE: partitioning pruning handles incorrect dates differently than index lookup, which can give different results in a partitioned table versus a non partitioned table for queries having 'bad' dates in the where clause. modified: mysql-test/r/partition_pruning.result mysql-test/t/partition_pruning.test sql/sql_partition.cc per-file messages: mysql-test/r/partition_pruning.result Bug#40972: some sql execution lead the whole databse crashing Updated result file mysql-test/t/partition_pruning.test Bug#40972: some sql execution lead the whole databse crashing Added test. sql/sql_partition.cc Bug#40972: some sql execution lead the whole databse crashing There can be cases where the start/cur partition is greater than the end partition, so it must not continue, since that can lead to a crash. === modified file 'mysql-test/r/partition_pruning.result' --- a/mysql-test/r/partition_pruning.result 2008-07-07 20:42:19 +0000 +++ b/mysql-test/r/partition_pruning.result 2008-12-28 11:33:49 +0000 @@ -1,4 +1,16 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +CREATE TABLE t1 +(a INT NOT NULL AUTO_INCREMENT, +b DATETIME, +PRIMARY KEY (a,b), +KEY (b)) +PARTITION BY RANGE (to_days(b)) +(PARTITION p0 VALUES LESS THAN (733681) COMMENT = 'LESS THAN 2008-10-01', +PARTITION p1 VALUES LESS THAN (733712) COMMENT = 'LESS THAN 2008-11-01', +PARTITION pX VALUES LESS THAN MAXVALUE); +SELECT a,b FROM t1 WHERE b >= '2008-12-01' AND b < '2009-12-00'; +a b +DROP TABLE t1; create table t1 ( a int not null) partition by hash(a) partitions 2; insert into t1 values (1),(2),(3); explain select * from t1 where a=5 and a=6; === modified file 'mysql-test/t/partition_pruning.test' --- a/mysql-test/t/partition_pruning.test 2007-09-14 10:18:42 +0000 +++ b/mysql-test/t/partition_pruning.test 2008-12-28 11:33:49 +0000 @@ -8,6 +8,22 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; --enable_warnings +# +# Bug#40972: some sql execution lead the whole database crashing +# +# Setup so the start is at partition pX and end is at p1 +# Pruning does handle 'bad' dates differently. +CREATE TABLE t1 +(a INT NOT NULL AUTO_INCREMENT, + b DATETIME, + PRIMARY KEY (a,b), + KEY (b)) +PARTITION BY RANGE (to_days(b)) +(PARTITION p0 VALUES LESS THAN (733681) COMMENT = 'LESS THAN 2008-10-01', + PARTITION p1 VALUES LESS THAN (733712) COMMENT = 'LESS THAN 2008-11-01', + PARTITION pX VALUES LESS THAN MAXVALUE); +SELECT a,b FROM t1 WHERE b >= '2008-12-01' AND b < '2009-12-00'; +DROP TABLE t1; # Check if we can infer from condition on partition fields that # no records will match. === modified file 'sql/sql_partition.cc' --- a/sql/sql_partition.cc 2008-12-10 08:06:58 +0000 +++ b/sql/sql_partition.cc 2008-12-28 11:33:49 +0000 @@ -6760,7 +6760,7 @@ int get_part_iter_for_interval_via_mappi store_key_image_to_rec(field, max_value, field_len); bool include_endp= !test(flags & NEAR_MAX); part_iter->part_nums.end= get_endpoint(part_info, 0, include_endp); - if (part_iter->part_nums.start == part_iter->part_nums.end && + if (part_iter->part_nums.start >= part_iter->part_nums.end && !part_iter->ret_null_part) return 0; /* No partitions */ } @@ -6938,7 +6938,7 @@ int get_part_iter_for_interval_via_walki uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter) { - if (part_iter->part_nums.cur == part_iter->part_nums.end) + if (part_iter->part_nums.cur >= part_iter->part_nums.end) { part_iter->part_nums.cur= part_iter->part_nums.start; return NOT_A_PARTITION_ID;