diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 8bb895386bf..26969d1ad5d 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1082,4 +1082,43 @@ a 2 1 drop table t1; +create table t1 (a int) engine myisam +partition by range (a) +subpartition by hash (a) +(partition p0 VALUES LESS THAN (1) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx' +(SUBPARTITION subpart00, SUBPARTITION subpart01)); +t1#P#p0#SP#subpart00.MYD +t1#P#p0#SP#subpart00.MYI +t1#P#p0#SP#subpart01.MYD +t1#P#p0#SP#subpart01.MYI +t1.frm +t1.par +t1#P#p0#SP#subpart00.MYD +t1#P#p0#SP#subpart01.MYD +t1#P#p0#SP#subpart00.MYI +t1#P#p0#SP#subpart01.MYI +ALTER TABLE t1 REORGANIZE PARTITION p0 INTO +(partition p1 VALUES LESS THAN (1) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx' +(SUBPARTITION subpart10, SUBPARTITION subpart11), +partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx' +(SUBPARTITION subpart20, SUBPARTITION subpart21)); +t1#P#p1#SP#subpart10.MYD +t1#P#p1#SP#subpart10.MYI +t1#P#p1#SP#subpart11.MYD +t1#P#p1#SP#subpart11.MYI +t1#P#p2#SP#subpart20.MYD +t1#P#p2#SP#subpart20.MYI +t1#P#p2#SP#subpart21.MYD +t1#P#p2#SP#subpart21.MYI +t1.frm +t1.par +t1#P#p1#SP#subpart10.MYD +t1#P#p1#SP#subpart11.MYD +t1#P#p2#SP#subpart20.MYD +t1#P#p2#SP#subpart21.MYD +t1#P#p1#SP#subpart10.MYI +t1#P#p1#SP#subpart11.MYI +t1#P#p2#SP#subpart20.MYI +t1#P#p2#SP#subpart21.MYI +drop table t1; End of 5.1 tests 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/r/partition_order.result b/mysql-test/r/partition_order.result index 7a1ab1d6dc8..78ff7cd3121 100644 --- a/mysql-test/r/partition_order.result +++ b/mysql-test/r/partition_order.result @@ -718,7 +718,11 @@ partitions 2 partition x2 values less than (100)); INSERT into t1 values (1, 1); INSERT into t1 values (5, NULL); -INSERT into t1 values (2, 5); +INSERT into t1 values (2, 4); +INSERT into t1 values (3, 3); +INSERT into t1 values (4, 5); +INSERT into t1 values (7, 1); +INSERT into t1 values (6, 6); INSERT into t1 values (30, 4); INSERT into t1 values (35, 2); INSERT into t1 values (40, NULL); @@ -727,7 +731,55 @@ a b 5 NULL 40 NULL 1 1 +7 1 35 2 +3 3 +2 4 30 4 -2 5 +4 5 +6 6 +select * from t1 force index (b) where b < 10 ORDER BY b; +a b +1 1 +7 1 +35 2 +3 3 +2 4 +30 4 +4 5 +6 6 +select * from t1 force index (b) where b < 10 ORDER BY b DESC; +a b +6 6 +4 5 +2 4 +30 4 +3 3 +35 2 +7 1 +1 1 +drop table t1; +create table t1 (a int not null, b int, c varchar(20), key (a,b,c)) +partition by range (b) +(partition p0 values less than (5), +partition p1 values less than (10)); +INSERT into t1 values (1,1,'1'),(2,2,'2'),(1,3,'3'),(2,4,'4'),(1,5,'5'); +INSERT into t1 values (2,6,'6'),(1,7,'7'),(2,8,'8'),(1,9,'9'); +INSERT into t1 values (1, NULL, NULL), (2, NULL, '10'); +select * from t1 where a = 1 order by a desc, b desc; +a b c +1 9 9 +1 7 7 +1 5 5 +1 3 3 +1 1 1 +1 NULL NULL +select * from t1 where a = 1 order by b desc; +a b c +1 9 9 +1 7 7 +1 5 5 +1 3 3 +1 1 1 +1 NULL NULL drop table t1; diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result index 3cbb517053a..9123c894f32 100644 --- a/mysql-test/r/partition_range.result +++ b/mysql-test/r/partition_range.result @@ -519,3 +519,115 @@ partition p3 values less than (1998), partition p4 values less than (1999), partition p5 values less than (2000)); drop table t1; +CREATE TABLE t1 (a date) +PARTITION BY RANGE (TO_DAYS(a)) +(PARTITION p3xx VALUES LESS THAN (TO_DAYS('2004-01-01')), +PARTITION p401 VALUES LESS THAN (TO_DAYS('2004-02-01')), +PARTITION p402 VALUES LESS THAN (TO_DAYS('2004-03-01')), +PARTITION p403 VALUES LESS THAN (TO_DAYS('2004-04-01')), +PARTITION p404 VALUES LESS THAN (TO_DAYS('2004-05-01')), +PARTITION p405 VALUES LESS THAN (TO_DAYS('2004-06-01')), +PARTITION p406 VALUES LESS THAN (TO_DAYS('2004-07-01')), +PARTITION p407 VALUES LESS THAN (TO_DAYS('2004-08-01')), +PARTITION p408 VALUES LESS THAN (TO_DAYS('2004-09-01')), +PARTITION p409 VALUES LESS THAN (TO_DAYS('2004-10-01')), +PARTITION p410 VALUES LESS THAN (TO_DAYS('2004-11-01')), +PARTITION p411 VALUES LESS THAN (TO_DAYS('2004-12-01')), +PARTITION p412 VALUES LESS THAN (TO_DAYS('2005-01-01')), +PARTITION p501 VALUES LESS THAN (TO_DAYS('2005-02-01')), +PARTITION p502 VALUES LESS THAN (TO_DAYS('2005-03-01')), +PARTITION p503 VALUES LESS THAN (TO_DAYS('2005-04-01')), +PARTITION p504 VALUES LESS THAN (TO_DAYS('2005-05-01')), +PARTITION p505 VALUES LESS THAN (TO_DAYS('2005-06-01')), +PARTITION p506 VALUES LESS THAN (TO_DAYS('2005-07-01')), +PARTITION p507 VALUES LESS THAN (TO_DAYS('2005-08-01')), +PARTITION p508 VALUES LESS THAN (TO_DAYS('2005-09-01')), +PARTITION p509 VALUES LESS THAN (TO_DAYS('2005-10-01')), +PARTITION p510 VALUES LESS THAN (TO_DAYS('2005-11-01')), +PARTITION p511 VALUES LESS THAN (TO_DAYS('2005-12-01')), +PARTITION p512 VALUES LESS THAN (TO_DAYS('2006-01-01')), +PARTITION p601 VALUES LESS THAN (TO_DAYS('2006-02-01')), +PARTITION p602 VALUES LESS THAN (TO_DAYS('2006-03-01')), +PARTITION p603 VALUES LESS THAN (TO_DAYS('2006-04-01')), +PARTITION p604 VALUES LESS THAN (TO_DAYS('2006-05-01')), +PARTITION p605 VALUES LESS THAN (TO_DAYS('2006-06-01')), +PARTITION p606 VALUES LESS THAN (TO_DAYS('2006-07-01')), +PARTITION p607 VALUES LESS THAN (TO_DAYS('2006-08-01'))); +INSERT INTO t1 VALUES ('2003-01-13'),('2003-06-20'),('2003-08-30'); +INSERT INTO t1 VALUES ('2003-04-13'),('2003-07-20'),('2003-10-30'); +INSERT INTO t1 VALUES ('2003-05-13'),('2003-11-20'),('2003-12-30'); +INSERT INTO t1 VALUES ('2004-01-13'),('2004-01-20'),('2004-01-30'); +INSERT INTO t1 VALUES ('2004-02-13'),('2004-02-20'),('2004-02-28'); +INSERT INTO t1 VALUES ('2004-03-13'),('2004-03-20'),('2004-03-30'); +INSERT INTO t1 VALUES ('2004-04-13'),('2004-04-20'),('2004-04-30'); +INSERT INTO t1 VALUES ('2004-05-13'),('2004-05-20'),('2004-05-30'); +INSERT INTO t1 VALUES ('2004-06-13'),('2004-06-20'),('2004-06-30'); +INSERT INTO t1 VALUES ('2004-07-13'),('2004-07-20'),('2004-07-30'); +INSERT INTO t1 VALUES ('2004-08-13'),('2004-08-20'),('2004-08-30'); +INSERT INTO t1 VALUES ('2004-09-13'),('2004-09-20'),('2004-09-30'); +INSERT INTO t1 VALUES ('2004-10-13'),('2004-10-20'),('2004-10-30'); +INSERT INTO t1 VALUES ('2004-11-13'),('2004-11-20'),('2004-11-30'); +INSERT INTO t1 VALUES ('2004-12-13'),('2004-12-20'),('2004-12-30'); +INSERT INTO t1 VALUES ('2005-01-13'),('2005-01-20'),('2005-01-30'); +INSERT INTO t1 VALUES ('2005-02-13'),('2005-02-20'),('2005-02-28'); +INSERT INTO t1 VALUES ('2005-03-13'),('2005-03-20'),('2005-03-30'); +INSERT INTO t1 VALUES ('2005-04-13'),('2005-04-20'),('2005-04-30'); +INSERT INTO t1 VALUES ('2005-05-13'),('2005-05-20'),('2005-05-30'); +INSERT INTO t1 VALUES ('2005-06-13'),('2005-06-20'),('2005-06-30'); +INSERT INTO t1 VALUES ('2005-07-13'),('2005-07-20'),('2005-07-30'); +INSERT INTO t1 VALUES ('2005-08-13'),('2005-08-20'),('2005-08-30'); +INSERT INTO t1 VALUES ('2005-09-13'),('2005-09-20'),('2005-09-30'); +INSERT INTO t1 VALUES ('2005-10-13'),('2005-10-20'),('2005-10-30'); +INSERT INTO t1 VALUES ('2005-11-13'),('2005-11-20'),('2005-11-30'); +INSERT INTO t1 VALUES ('2005-12-13'),('2005-12-20'),('2005-12-30'); +INSERT INTO t1 VALUES ('2006-01-13'),('2006-01-20'),('2006-01-30'); +INSERT INTO t1 VALUES ('2006-02-13'),('2006-02-20'),('2006-02-28'); +INSERT INTO t1 VALUES ('2006-03-13'),('2006-03-20'),('2006-03-30'); +INSERT INTO t1 VALUES ('2006-04-13'),('2006-04-20'),('2006-04-30'); +INSERT INTO t1 VALUES ('2006-05-13'),('2006-05-20'),('2006-05-30'); +INSERT INTO t1 VALUES ('2006-06-13'),('2006-06-20'),('2006-06-30'); +INSERT INTO t1 VALUES ('2006-07-13'),('2006-07-20'),('2006-07-30'); +SELECT * FROM t1 +WHERE a >= '2004-07-01' AND a <= '2004-09-30'; +a +2004-07-13 +2004-07-20 +2004-07-30 +2004-08-13 +2004-08-20 +2004-08-30 +2004-09-13 +2004-09-20 +2004-09-30 +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE a >= '2004-07-01' AND a <= '2004-09-30'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p407,p408,p409 ALL NULL NULL NULL NULL 9 Using where +SELECT * from t1 +WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR +(a >= '2005-07-01' AND a <= '2005-09-30'); +a +2004-07-13 +2004-07-20 +2004-07-30 +2004-08-13 +2004-08-20 +2004-08-30 +2004-09-13 +2004-09-20 +2004-09-30 +2005-07-13 +2005-07-20 +2005-07-30 +2005-08-13 +2005-08-20 +2005-08-30 +2005-09-13 +2005-09-20 +2005-09-30 +EXPLAIN PARTITIONS SELECT * from t1 +WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR +(a >= '2005-07-01' AND a <= '2005-09-30'); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p407,p408,p409,p507,p508,p509 ALL NULL NULL NULL NULL 18 Using where +DROP TABLE t1; diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 04519800ff6..1c606c47183 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1261,4 +1261,47 @@ insert into t1 values (1),(2); select * from t1 ORDER BY a DESC; drop table t1; +# +# Bug 20770 Partitions: DATA DIRECTORY clause change in reorganize +# doesn't remove old directory +# +--disable_query_log +--exec mkdir $MYSQLTEST_VARDIR/master-data/tmpdata || true +eval SET @data_dir = 'DATA DIRECTORY = ''$MYSQLTEST_VARDIR/master-data/tmpdata'''; +let $data_directory = `select @data_dir`; + +--exec mkdir $MYSQLTEST_VARDIR/master-data/tmpinx || true +eval SET @inx_dir = 'INDEX DIRECTORY = ''$MYSQLTEST_VARDIR/master-data/tmpinx'''; +let $inx_directory = `select @inx_dir`; +--enable_query_log + +--replace_result $MYSQLTEST_VARDIR "hello" +eval create table t1 (a int) engine myisam +partition by range (a) +subpartition by hash (a) +(partition p0 VALUES LESS THAN (1) $data_directory $inx_directory + (SUBPARTITION subpart00, SUBPARTITION subpart01)); + +--replace_result $MYSQLTEST_VARDIR "hello" +--exec ls $MYSQLTEST_VARDIR/master-data/test || true +--replace_result $MYSQLTEST_VARDIR "hello" +--exec ls $MYSQLTEST_VARDIR/master-data/tmpdata || true +--replace_result $MYSQLTEST_VARDIR "hello" +--exec ls $MYSQLTEST_VARDIR/master-data/tmpinx || true +--replace_result $MYSQLTEST_VARDIR "hello" + +eval ALTER TABLE t1 REORGANIZE PARTITION p0 INTO +(partition p1 VALUES LESS THAN (1) $data_directory $inx_directory + (SUBPARTITION subpart10, SUBPARTITION subpart11), + partition p2 VALUES LESS THAN (2) $data_directory $inx_directory + (SUBPARTITION subpart20, SUBPARTITION subpart21)); + +--replace_result $MYSQLTEST_VARDIR "hello" +--exec ls $MYSQLTEST_VARDIR/master-data/test || true +--replace_result $MYSQLTEST_VARDIR "hello" +--exec ls $MYSQLTEST_VARDIR/master-data/tmpdata || true +--replace_result $MYSQLTEST_VARDIR "hello" +--exec ls $MYSQLTEST_VARDIR/master-data/tmpinx || true + +drop table t1; --echo End of 5.1 tests 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/mysql-test/t/partition_order.test b/mysql-test/t/partition_order.test index 1e1b3339d64..ad956361d00 100644 --- a/mysql-test/t/partition_order.test +++ b/mysql-test/t/partition_order.test @@ -818,11 +818,27 @@ partitions 2 # Insert a couple of tuples INSERT into t1 values (1, 1); INSERT into t1 values (5, NULL); -INSERT into t1 values (2, 5); +INSERT into t1 values (2, 4); +INSERT into t1 values (3, 3); +INSERT into t1 values (4, 5); +INSERT into t1 values (7, 1); +INSERT into t1 values (6, 6); INSERT into t1 values (30, 4); INSERT into t1 values (35, 2); INSERT into t1 values (40, NULL); select * from t1 force index (b) where b < 10 OR b IS NULL order by b; - +select * from t1 force index (b) where b < 10 ORDER BY b; +select * from t1 force index (b) where b < 10 ORDER BY b DESC; +drop table t1; + +create table t1 (a int not null, b int, c varchar(20), key (a,b,c)) +partition by range (b) +(partition p0 values less than (5), + partition p1 values less than (10)); +INSERT into t1 values (1,1,'1'),(2,2,'2'),(1,3,'3'),(2,4,'4'),(1,5,'5'); +INSERT into t1 values (2,6,'6'),(1,7,'7'),(2,8,'8'),(1,9,'9'); +INSERT into t1 values (1, NULL, NULL), (2, NULL, '10'); +select * from t1 where a = 1 order by a desc, b desc; +select * from t1 where a = 1 order by b desc; drop table t1; diff --git a/mysql-test/t/partition_range.test b/mysql-test/t/partition_range.test index 8e1e2e72e69..38142a9d485 100644 --- a/mysql-test/t/partition_range.test +++ b/mysql-test/t/partition_range.test @@ -555,3 +555,90 @@ reorganize partition p5 into drop table t1; +# +# New test cases for date based partitioning +# +CREATE TABLE t1 (a date) +PARTITION BY RANGE (TO_DAYS(a)) +(PARTITION p3xx VALUES LESS THAN (TO_DAYS('2004-01-01')), + PARTITION p401 VALUES LESS THAN (TO_DAYS('2004-02-01')), + PARTITION p402 VALUES LESS THAN (TO_DAYS('2004-03-01')), + PARTITION p403 VALUES LESS THAN (TO_DAYS('2004-04-01')), + PARTITION p404 VALUES LESS THAN (TO_DAYS('2004-05-01')), + PARTITION p405 VALUES LESS THAN (TO_DAYS('2004-06-01')), + PARTITION p406 VALUES LESS THAN (TO_DAYS('2004-07-01')), + PARTITION p407 VALUES LESS THAN (TO_DAYS('2004-08-01')), + PARTITION p408 VALUES LESS THAN (TO_DAYS('2004-09-01')), + PARTITION p409 VALUES LESS THAN (TO_DAYS('2004-10-01')), + PARTITION p410 VALUES LESS THAN (TO_DAYS('2004-11-01')), + PARTITION p411 VALUES LESS THAN (TO_DAYS('2004-12-01')), + PARTITION p412 VALUES LESS THAN (TO_DAYS('2005-01-01')), + PARTITION p501 VALUES LESS THAN (TO_DAYS('2005-02-01')), + PARTITION p502 VALUES LESS THAN (TO_DAYS('2005-03-01')), + PARTITION p503 VALUES LESS THAN (TO_DAYS('2005-04-01')), + PARTITION p504 VALUES LESS THAN (TO_DAYS('2005-05-01')), + PARTITION p505 VALUES LESS THAN (TO_DAYS('2005-06-01')), + PARTITION p506 VALUES LESS THAN (TO_DAYS('2005-07-01')), + PARTITION p507 VALUES LESS THAN (TO_DAYS('2005-08-01')), + PARTITION p508 VALUES LESS THAN (TO_DAYS('2005-09-01')), + PARTITION p509 VALUES LESS THAN (TO_DAYS('2005-10-01')), + PARTITION p510 VALUES LESS THAN (TO_DAYS('2005-11-01')), + PARTITION p511 VALUES LESS THAN (TO_DAYS('2005-12-01')), + PARTITION p512 VALUES LESS THAN (TO_DAYS('2006-01-01')), + PARTITION p601 VALUES LESS THAN (TO_DAYS('2006-02-01')), + PARTITION p602 VALUES LESS THAN (TO_DAYS('2006-03-01')), + PARTITION p603 VALUES LESS THAN (TO_DAYS('2006-04-01')), + PARTITION p604 VALUES LESS THAN (TO_DAYS('2006-05-01')), + PARTITION p605 VALUES LESS THAN (TO_DAYS('2006-06-01')), + PARTITION p606 VALUES LESS THAN (TO_DAYS('2006-07-01')), + PARTITION p607 VALUES LESS THAN (TO_DAYS('2006-08-01'))); + +INSERT INTO t1 VALUES ('2003-01-13'),('2003-06-20'),('2003-08-30'); +INSERT INTO t1 VALUES ('2003-04-13'),('2003-07-20'),('2003-10-30'); +INSERT INTO t1 VALUES ('2003-05-13'),('2003-11-20'),('2003-12-30'); + +INSERT INTO t1 VALUES ('2004-01-13'),('2004-01-20'),('2004-01-30'); +INSERT INTO t1 VALUES ('2004-02-13'),('2004-02-20'),('2004-02-28'); +INSERT INTO t1 VALUES ('2004-03-13'),('2004-03-20'),('2004-03-30'); +INSERT INTO t1 VALUES ('2004-04-13'),('2004-04-20'),('2004-04-30'); +INSERT INTO t1 VALUES ('2004-05-13'),('2004-05-20'),('2004-05-30'); +INSERT INTO t1 VALUES ('2004-06-13'),('2004-06-20'),('2004-06-30'); +INSERT INTO t1 VALUES ('2004-07-13'),('2004-07-20'),('2004-07-30'); +INSERT INTO t1 VALUES ('2004-08-13'),('2004-08-20'),('2004-08-30'); +INSERT INTO t1 VALUES ('2004-09-13'),('2004-09-20'),('2004-09-30'); +INSERT INTO t1 VALUES ('2004-10-13'),('2004-10-20'),('2004-10-30'); +INSERT INTO t1 VALUES ('2004-11-13'),('2004-11-20'),('2004-11-30'); +INSERT INTO t1 VALUES ('2004-12-13'),('2004-12-20'),('2004-12-30'); + +INSERT INTO t1 VALUES ('2005-01-13'),('2005-01-20'),('2005-01-30'); +INSERT INTO t1 VALUES ('2005-02-13'),('2005-02-20'),('2005-02-28'); +INSERT INTO t1 VALUES ('2005-03-13'),('2005-03-20'),('2005-03-30'); +INSERT INTO t1 VALUES ('2005-04-13'),('2005-04-20'),('2005-04-30'); +INSERT INTO t1 VALUES ('2005-05-13'),('2005-05-20'),('2005-05-30'); +INSERT INTO t1 VALUES ('2005-06-13'),('2005-06-20'),('2005-06-30'); +INSERT INTO t1 VALUES ('2005-07-13'),('2005-07-20'),('2005-07-30'); +INSERT INTO t1 VALUES ('2005-08-13'),('2005-08-20'),('2005-08-30'); +INSERT INTO t1 VALUES ('2005-09-13'),('2005-09-20'),('2005-09-30'); +INSERT INTO t1 VALUES ('2005-10-13'),('2005-10-20'),('2005-10-30'); +INSERT INTO t1 VALUES ('2005-11-13'),('2005-11-20'),('2005-11-30'); +INSERT INTO t1 VALUES ('2005-12-13'),('2005-12-20'),('2005-12-30'); + +INSERT INTO t1 VALUES ('2006-01-13'),('2006-01-20'),('2006-01-30'); +INSERT INTO t1 VALUES ('2006-02-13'),('2006-02-20'),('2006-02-28'); +INSERT INTO t1 VALUES ('2006-03-13'),('2006-03-20'),('2006-03-30'); +INSERT INTO t1 VALUES ('2006-04-13'),('2006-04-20'),('2006-04-30'); +INSERT INTO t1 VALUES ('2006-05-13'),('2006-05-20'),('2006-05-30'); +INSERT INTO t1 VALUES ('2006-06-13'),('2006-06-20'),('2006-06-30'); +INSERT INTO t1 VALUES ('2006-07-13'),('2006-07-20'),('2006-07-30'); + +SELECT * FROM t1 +WHERE a >= '2004-07-01' AND a <= '2004-09-30'; +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE a >= '2004-07-01' AND a <= '2004-09-30'; +SELECT * from t1 +WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR + (a >= '2005-07-01' AND a <= '2005-09-30'); +EXPLAIN PARTITIONS SELECT * from t1 +WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR + (a >= '2005-07-01' AND a <= '2005-09-30'); +DROP TABLE t1; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 2d097c34f97..2acc1f4ed7d 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1202,12 +1202,13 @@ int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key, int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len) { + DBUG_ENTER("ha_myisam::index_read_last"); DBUG_ASSERT(inited==INDEX); statistic_increment(table->in_use->status_var.ha_read_key_count, &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; - return error; + DBUG_RETURN(error); } int ha_myisam::index_next(byte * buf) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index a02971f9f66..30a3306ecd3 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; @@ -1125,13 +1126,15 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, int ha_partition::prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info, - handler *file, const char *part_name) + handler *file, const char *part_name, + partition_element *p_elem) { int error; bool create_flag= FALSE; bool open_flag= FALSE; DBUG_ENTER("prepare_new_partition"); + set_up_table_before_create(table, part_name, create_info, 0, p_elem); if ((error= file->create(part_name, table, create_info))) goto error; create_flag= TRUE; @@ -1231,7 +1234,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 +1269,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 +1343,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 +1357,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) @@ -1420,7 +1427,8 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, DBUG_PRINT("info", ("Add subpartition %s", part_name_buff)); if ((error= prepare_new_partition(table, create_info, new_file_array[part], - (const char *)part_name_buff))) + (const char *)part_name_buff, + sub_elem))) { cleanup_new_partition(part_count); DBUG_RETURN(error); @@ -1436,7 +1444,8 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, DBUG_PRINT("info", ("Add partition %s", part_name_buff)); if ((error= prepare_new_partition(table, create_info, new_file_array[i], - (const char *)part_name_buff))) + (const char *)part_name_buff, + part_elem))) { cleanup_new_partition(part_count); DBUG_RETURN(error); @@ -1648,7 +1657,7 @@ uint ha_partition::del_ren_cre_table(const char *from, error= (*file)->delete_table((const char*) from_buff); else { - set_up_table_before_create(table_arg, from_buff, create_info, i); + set_up_table_before_create(table_arg, from_buff, create_info, i, NULL); error= (*file)->create(from_buff, table_arg, create_info); } name_buffer_ptr= strend(name_buffer_ptr) + 1; @@ -1724,12 +1733,15 @@ partition_element *ha_partition::find_partition_element(uint part_id) void ha_partition::set_up_table_before_create(TABLE *table, const char *partition_name_with_path, HA_CREATE_INFO *info, - uint part_id) + uint part_id, + partition_element *part_elem) { - partition_element *part_elem= find_partition_element(part_id); - if (!part_elem) - return; // Fatal error + { + part_elem= find_partition_element(part_id); + if (!part_elem) + return; // Fatal error + } table->s->max_rows= part_elem->part_max_rows; table->s->min_rows= part_elem->part_min_rows; const char *partition_name= strrchr(partition_name_with_path, FN_LIBCHAR); @@ -1959,6 +1971,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 +2021,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); @@ -3266,6 +3280,7 @@ int ha_partition::index_read(byte * buf, const byte * key, DBUG_ENTER("ha_partition::index_read"); end_range= 0; + m_index_scan_type= partition_index_read; DBUG_RETURN(common_index_read(buf, key, key_len, find_flag)); } @@ -3283,18 +3298,24 @@ int ha_partition::common_index_read(byte *buf, const byte *key, uint key_len, enum ha_rkey_function find_flag) { int error; + bool reverse_order= FALSE; DBUG_ENTER("ha_partition::common_index_read"); memcpy((void*)m_start_key.key, key, key_len); m_start_key.length= key_len; m_start_key.flag= find_flag; - m_index_scan_type= partition_index_read; if ((error= partition_scan_set_up(buf, TRUE))) { DBUG_RETURN(error); } - + if (find_flag == HA_READ_PREFIX_LAST || + find_flag == HA_READ_PREFIX_LAST_OR_PREV || + find_flag == HA_READ_BEFORE_KEY) + { + reverse_order= TRUE; + m_ordered_scan_ongoing= TRUE; + } if (!m_ordered_scan_ongoing || (find_flag == HA_READ_KEY_EXACT && (key_len >= m_curr_key_info->key_length || @@ -3320,7 +3341,7 @@ int ha_partition::common_index_read(byte *buf, const byte *key, uint key_len, In all other cases we will use the ordered index scan. This will use the partition set created by the get_partition_set method. */ - error= handle_ordered_index_scan(buf); + error= handle_ordered_index_scan(buf, reverse_order); } DBUG_RETURN(error); } @@ -3404,7 +3425,7 @@ int ha_partition::common_first_last(byte *buf) if (!m_ordered_scan_ongoing && m_index_scan_type != partition_index_last) return handle_unordered_scan_next_partition(buf); - return handle_ordered_index_scan(buf); + return handle_ordered_index_scan(buf, FALSE); } @@ -3458,7 +3479,9 @@ int ha_partition::index_read_last(byte *buf, const byte *key, uint keylen) DBUG_ENTER("ha_partition::index_read_last"); m_ordered= TRUE; // Safety measure - DBUG_RETURN(index_read(buf, key, keylen, HA_READ_PREFIX_LAST)); + end_range= 0; + m_index_scan_type= partition_index_read_last; + DBUG_RETURN(common_index_read(buf, key, keylen, HA_READ_PREFIX_LAST)); } @@ -3598,6 +3621,7 @@ int ha_partition::read_range_first(const key_range *start_key, } else { + m_index_scan_type= partition_index_read; error= common_index_read(m_rec0, start_key->key, start_key->length, start_key->flag); @@ -3856,12 +3880,11 @@ int ha_partition::handle_unordered_scan_next_partition(byte * buf) entries. */ -int ha_partition::handle_ordered_index_scan(byte *buf) +int ha_partition::handle_ordered_index_scan(byte *buf, bool reverse_order) { uint i; uint j= 0; bool found= FALSE; - bool reverse_order= FALSE; DBUG_ENTER("ha_partition::handle_ordered_index_scan"); m_top_entry= NO_CURRENT_PART_ID; @@ -3882,7 +3905,6 @@ int ha_partition::handle_ordered_index_scan(byte *buf) m_start_key.key, m_start_key.length, m_start_key.flag); - reverse_order= FALSE; break; case partition_index_first: error= file->index_first(rec_buf_ptr); @@ -3892,6 +3914,12 @@ int ha_partition::handle_ordered_index_scan(byte *buf) error= file->index_last(rec_buf_ptr); reverse_order= TRUE; break; + case partition_index_read_last: + error= file->index_read_last(rec_buf_ptr, + m_start_key.key, + m_start_key.length); + reverse_order= TRUE; + break; default: DBUG_ASSERT(FALSE); DBUG_RETURN(HA_ERR_END_OF_FILE); diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 4c627cd50f8..d16cfe59f2a 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -46,7 +46,8 @@ private: partition_index_read= 0, partition_index_first= 1, partition_index_last= 2, - partition_no_index_scan= 3 + partition_index_read_last= 3, + partition_no_index_scan= 4 }; /* Data for the partition handler */ int m_mode; // Open mode @@ -55,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 @@ -202,7 +204,8 @@ private: int copy_partitions(ulonglong *copied, ulonglong *deleted); void cleanup_new_partition(uint part_count); int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info, - handler *file, const char *part_name); + handler *file, const char *part_name, + partition_element *p_elem); /* delete_table, rename_table and create uses very similar logic which is packed into this routine. @@ -222,7 +225,8 @@ private: void set_up_table_before_create(TABLE *table_arg, const char *partition_name_with_path, HA_CREATE_INFO *info, - uint part_id); + uint part_id, + partition_element *p_elem); partition_element *find_partition_element(uint part_id); public: @@ -429,7 +433,7 @@ private: return (queue_buf(part_id) + PARTITION_BYTES_IN_POS); } - int handle_ordered_index_scan(byte * buf); + int handle_ordered_index_scan(byte * buf, bool reverse_order); int handle_ordered_next(byte * buf, bool next_same); int handle_ordered_prev(byte * buf); void return_top_record(byte * buf); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0632e2298cd..0001676aab4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3716,14 +3716,15 @@ sub_part_definition: { LEX *lex= Lex; partition_info *part_info= lex->part_info; - partition_element *p_elem= new partition_element(); - if (!p_elem || - part_info->current_partition->subpartitions.push_back(p_elem)) + partition_element *curr_part= part_info->current_partition; + partition_element *sub_p_elem= new partition_element(curr_part); + if (!sub_p_elem || + curr_part->subpartitions.push_back(sub_p_elem)) { mem_alloc_error(sizeof(partition_element)); YYABORT; } - part_info->curr_part_elem= p_elem; + part_info->curr_part_elem= sub_p_elem; part_info->use_default_subpartitions= FALSE; part_info->use_default_no_subpartitions= FALSE; part_info->count_curr_subparts++;