[Commits] 442a3d4: MDEV-8348: Add catchall to all table partitioning for list partitions

Oleksandr Byelkin sanja at mariadb.com
Fri Sep 2 16:09:12 EEST 2016


revision-id: 442a3d4766f9115bfd496dd4fafd38f7aeb0e273 (mariadb-10.2.1-52-g442a3d4)
parent(s): 1eb58ff3b8569d7dad1f5c180a5e55683e53d205
committer: Oleksandr Byelkin
timestamp: 2016-09-02 15:09:12 +0200
message:

MDEV-8348: Add catchall to all table partitioning for list partitions

DEFAULT partition support added to LIST and LIST COLUMN partitioning.
Partitions Prunning added for DEFAULT partititon.

---
 mysql-test/r/partition_default.result | 946 ++++++++++++++++++++++++++++++++++
 mysql-test/t/partition_default.test   | 338 ++++++++++++
 sql/partition_element.h               |   2 +-
 sql/partition_info.cc                 |  59 ++-
 sql/partition_info.h                  |   7 +
 sql/share/errmsg-utf8.txt             |   3 +
 sql/sql_partition.cc                  |  63 ++-
 sql/sql_partition.h                   |   4 +
 sql/sql_yacc.yy                       |  21 +
 9 files changed, 1434 insertions(+), 9 deletions(-)

diff --git a/mysql-test/r/partition_default.result b/mysql-test/r/partition_default.result
new file mode 100644
index 0000000..cfd214a
--- /dev/null
+++ b/mysql-test/r/partition_default.result
@@ -0,0 +1,946 @@
+create table t1 (a int, b int)
+PARTITION BY LIST (a)
+(
+PARTITION p2 VALUES IN (4,5,6),
+PARTITION p1 VALUES IN (1),
+PARTITION p0 DEFAULT
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a)
+(PARTITION p2 VALUES IN (4,5,6) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (1) ENGINE = MyISAM,
+ PARTITION p0 DEFAULT ENGINE = MyISAM) */
+insert into t1 values (10,10);
+select * from t1;
+a	b
+10	10
+drop table t1;
+create table t1 (a int, b int)
+PARTITION BY LIST (a)
+(
+PARTITION p2 VALUES IN (4,5,6),
+PARTITION p1 VALUES IN (1),
+PARTITION p0 DEFAULT,
+PARTITION p3 DEFAULT
+)
+;
+ERROR HY000: Only one DEFAULT partition allowed
+create table t1 (a int, b int)
+PARTITION BY LIST (a)
+(
+PARTITION p0 DEFAULT,
+PARTITION p2 VALUES IN (4,5,6),
+PARTITION p1 VALUES IN (1),
+PARTITION p3 DEFAULT
+)
+;
+ERROR HY000: Only one DEFAULT partition allowed
+create table t1 (a int, b int)
+PARTITION BY LIST (a)
+(
+PARTITION p0 DEFAULT,
+PARTITION p2 VALUES IN (4,5,6),
+PARTITION p1 VALUES IN (1)
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a)
+(PARTITION p0 DEFAULT ENGINE = MyISAM,
+ PARTITION p2 VALUES IN (4,5,6) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (1) ENGINE = MyISAM) */
+insert into t1 values (10,10);
+select * from t1;
+a	b
+10	10
+drop table t1;
+create table t1 (a int, b int)
+PARTITION BY LIST (a)
+(
+PARTITION p0 DEFAULT,
+PARTITION p2 VALUES IN (4,5,6),
+PARTITION p1 VALUES IN (1, 0)
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a)
+(PARTITION p0 DEFAULT ENGINE = MyISAM,
+ PARTITION p2 VALUES IN (4,5,6) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (1,0) ENGINE = MyISAM) */
+insert into t1 values (10,10);
+select * from t1;
+a	b
+10	10
+drop table t1;
+create table t1 (a int, b int)
+PARTITION BY LIST COLUMNS(a,b)
+(
+PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+PARTITION p1 VALUES IN ((1,1),(0,0)),
+PARTITION p0 DEFAULT
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN ((1,1),(0,0)) ENGINE = MyISAM,
+ PARTITION p0 DEFAULT ENGINE = MyISAM) */
+insert into t1 values (10,10);
+select * from t1;
+a	b
+10	10
+drop table t1;
+create table t1 (a int, b int)
+PARTITION BY LIST COLUMNS(a,b)
+(
+PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+PARTITION p1 VALUES IN ((1,1),(0,0)),
+PARTITION p0 DEFAULT,
+PARTITION p3 DEFAULT
+)
+;
+ERROR HY000: Only one DEFAULT partition allowed
+create table t1 (a int, b int)
+PARTITION BY LIST COLUMNS(a,b)
+(
+PARTITION p0 DEFAULT,
+PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+PARTITION p1 VALUES IN ((1,1),(0,0)),
+PARTITION p3 DEFAULT
+)
+;
+ERROR HY000: Only one DEFAULT partition allowed
+create table t1 (a int, b int)
+PARTITION BY LIST (a)
+(
+PARTITION p2 VALUES IN (4,5,6),
+PARTITION p1 VALUES IN (1,20),
+PARTITION p0 default
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a)
+(PARTITION p2 VALUES IN (4,5,6) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (1,20) ENGINE = MyISAM,
+ PARTITION p0 DEFAULT ENGINE = MyISAM) */
+insert into t1 values (10,10);
+select * from t1 where a=10;
+a	b
+10	10
+select * from t1 where a<=10;
+a	b
+10	10
+select * from t1 where a<=20;
+a	b
+10	10
+select * from t1 where a>=10;
+a	b
+10	10
+select * from t1 where a>=5;
+a	b
+10	10
+insert into t1 values (20,20),(5,5);
+select * from t1 where a=10;
+a	b
+10	10
+select * from t1 where a<=10;
+a	b
+5	5
+10	10
+select * from t1 where a<=20;
+a	b
+5	5
+20	20
+10	10
+select * from t1 where a>=10;
+a	b
+20	20
+10	10
+select * from t1 where a>=5;
+a	b
+5	5
+20	20
+10	10
+explain partitions select * from t1 where a=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+explain partitions select * from t1 where a=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2	system	NULL	NULL	NULL	NULL	1	
+select * from t1 where a=10 or a=5;
+a	b
+5	5
+10	10
+explain partitions select * from t1 where a=10 or a=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2,p0	ALL	NULL	NULL	NULL	NULL	2	Using where
+drop table t1;
+create table t1 (a int, b int)
+PARTITION BY LIST COLUMNS(a,b)
+(
+PARTITION p2 VALUES IN ((1,4),(2,5),(3,6),(5,5)),
+PARTITION p1 VALUES IN ((1,1),(20,20)),
+PARTITION p0 DEFAULT
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p2 VALUES IN ((1,4),(2,5),(3,6),(5,5)) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN ((1,1),(20,20)) ENGINE = MyISAM,
+ PARTITION p0 DEFAULT ENGINE = MyISAM) */
+insert into t1 values (10,10);
+select * from t1 where a=10 and b=10;
+a	b
+10	10
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+select * from t1 where a=10;
+a	b
+10	10
+explain partitions select * from t1 where a=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+select * from t1 where a<=10;
+a	b
+10	10
+select * from t1 where a>=10;
+a	b
+10	10
+insert into t1 values (20,20),(5,5);
+select * from t1 where a=10 and b=10;
+a	b
+10	10
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+select * from t1 where a=10 and b=10 or a=20 and b=20;
+a	b
+20	20
+10	10
+explain partitions select * from t1 where a=10 and b=10 or a=20 and b=20;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p1,p0	ALL	NULL	NULL	NULL	NULL	2	Using where
+drop table t1;
+create table t1 (a int, b int);
+insert into t1 values (10,10),(2,5),(0,0);
+select * from t1;
+a	b
+10	10
+2	5
+0	0
+alter table t1
+PARTITION BY LIST (a+b)
+(
+PARTITION p2 VALUES IN (1,2,3,7),
+PARTITION p1 VALUES IN (21,0),
+PARTITION p0 DEFAULT
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a+b)
+(PARTITION p2 VALUES IN (1,2,3,7) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (21,0) ENGINE = MyISAM,
+ PARTITION p0 DEFAULT ENGINE = MyISAM) */
+select * from t1;
+a	b
+2	5
+0	0
+10	10
+explain partitions select * from t1 where a=2 and b=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2	system	NULL	NULL	NULL	NULL	1	
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+drop table t1;
+create table t1 (a int, b int);
+insert into t1 values (10,10),(2,5),(0,0);
+select * from t1;
+a	b
+10	10
+2	5
+0	0
+alter table t1
+PARTITION BY LIST (a+5)
+(
+PARTITION p2 VALUES IN (1,2,3,7),
+PARTITION p1 VALUES IN (0),
+PARTITION p0 DEFAULT
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a+5)
+(PARTITION p2 VALUES IN (1,2,3,7) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (0) ENGINE = MyISAM,
+ PARTITION p0 DEFAULT ENGINE = MyISAM) */
+select * from t1;
+a	b
+2	5
+10	10
+0	0
+explain partitions select * from t1 where a>=2;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2,p1,p0	ALL	NULL	NULL	NULL	NULL	3	Using where
+explain partitions select * from t1 where a>=2 and a<=3;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2,p0	ALL	NULL	NULL	NULL	NULL	3	Using where
+explain partitions select * from t1 where a=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	ALL	NULL	NULL	NULL	NULL	2	Using where
+drop table t1;
+CREATE TABLE t1 (a DATE, KEY(a))
+PARTITION BY LIST (TO_DAYS(a))
+(PARTITION `pDEF` DEFAULT,
+PARTITION `p2001-01-01` VALUES IN (TO_DAYS('2001-01-01')),
+PARTITION `pNULL` VALUES IN (NULL),
+PARTITION `p0000-01-02` VALUES IN (TO_DAYS('0000-01-02')),
+PARTITION `p1001-01-01` VALUES IN (TO_DAYS('1001-01-01')));
+INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'),
+('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01');
+SELECT * FROM t1 WHERE a < '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+SELECT * FROM t1 WHERE a <= '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+SELECT * FROM t1 WHERE a >= '1001-01-01';
+a
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a > '1001-01-01';
+a
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a = '1001-01-01';
+a
+1001-01-01
+SELECT * FROM t1 WHERE a < '1001-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+SELECT * FROM t1 WHERE a <= '1001-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+SELECT * FROM t1 WHERE a >= '1001-00-00';
+a
+1001-00-00
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a > '1001-00-00';
+a
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a = '1001-00-00';
+a
+1001-00-00
+# Disabling warnings for the invalid date
+SELECT * FROM t1 WHERE a < '1999-02-31';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a <= '1999-02-31';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a >= '1999-02-31';
+a
+2001-01-01
+SELECT * FROM t1 WHERE a > '1999-02-31';
+a
+2001-01-01
+SELECT * FROM t1 WHERE a = '1999-02-31';
+a
+SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
+a
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01';
+a
+0001-01-01
+1001-00-00
+1001-01-01
+# test without index
+ALTER TABLE t1 DROP KEY a;
+SELECT * FROM t1 WHERE a < '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+SELECT * FROM t1 WHERE a <= '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+SELECT * FROM t1 WHERE a >= '1001-01-01';
+a
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a > '1001-01-01';
+a
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a = '1001-01-01';
+a
+1001-01-01
+SELECT * FROM t1 WHERE a < '1001-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+SELECT * FROM t1 WHERE a <= '1001-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+SELECT * FROM t1 WHERE a >= '1001-00-00';
+a
+1001-00-00
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a > '1001-00-00';
+a
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a = '1001-00-00';
+a
+1001-00-00
+# Disabling warnings for the invalid date
+SELECT * FROM t1 WHERE a < '1999-02-31';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a <= '1999-02-31';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a >= '1999-02-31';
+a
+2001-01-01
+SELECT * FROM t1 WHERE a > '1999-02-31';
+a
+2001-01-01
+SELECT * FROM t1 WHERE a = '1999-02-31';
+a
+SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
+a
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01';
+a
+0001-01-01
+1001-00-00
+1001-01-01
+DROP TABLE t1;
+# TO_SECONDS, test of LIST and index
+CREATE TABLE t1 (a DATE, KEY(a))
+PARTITION BY LIST (TO_SECONDS(a))
+(PARTITION `pDEF` DEFAULT,
+PARTITION `p2001-01-01` VALUES IN (TO_SECONDS('2001-01-01')),
+PARTITION `pNULL` VALUES IN (NULL),
+PARTITION `p0000-01-02` VALUES IN (TO_SECONDS('0000-01-02')),
+PARTITION `p1001-01-01` VALUES IN (TO_SECONDS('1001-01-01')));
+INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'),
+('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01');
+SELECT * FROM t1 WHERE a < '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+SELECT * FROM t1 WHERE a <= '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+SELECT * FROM t1 WHERE a >= '1001-01-01';
+a
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a > '1001-01-01';
+a
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a = '1001-01-01';
+a
+1001-01-01
+SELECT * FROM t1 WHERE a < '1001-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+SELECT * FROM t1 WHERE a <= '1001-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+SELECT * FROM t1 WHERE a >= '1001-00-00';
+a
+1001-00-00
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a > '1001-00-00';
+a
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a = '1001-00-00';
+a
+1001-00-00
+# Disabling warnings for the invalid date
+SELECT * FROM t1 WHERE a < '1999-02-31';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a <= '1999-02-31';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a >= '1999-02-31';
+a
+2001-01-01
+SELECT * FROM t1 WHERE a > '1999-02-31';
+a
+2001-01-01
+SELECT * FROM t1 WHERE a = '1999-02-31';
+a
+SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
+a
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01';
+a
+0001-01-01
+1001-00-00
+1001-01-01
+# test without index
+ALTER TABLE t1 DROP KEY a;
+SELECT * FROM t1 WHERE a < '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+SELECT * FROM t1 WHERE a <= '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+SELECT * FROM t1 WHERE a >= '1001-01-01';
+a
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a > '1001-01-01';
+a
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a = '1001-01-01';
+a
+1001-01-01
+SELECT * FROM t1 WHERE a < '1001-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+SELECT * FROM t1 WHERE a <= '1001-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+SELECT * FROM t1 WHERE a >= '1001-00-00';
+a
+1001-00-00
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a > '1001-00-00';
+a
+1001-01-01
+1002-00-00
+2001-01-01
+SELECT * FROM t1 WHERE a = '1001-00-00';
+a
+1001-00-00
+# Disabling warnings for the invalid date
+SELECT * FROM t1 WHERE a < '1999-02-31';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a <= '1999-02-31';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a >= '1999-02-31';
+a
+2001-01-01
+SELECT * FROM t1 WHERE a > '1999-02-31';
+a
+2001-01-01
+SELECT * FROM t1 WHERE a = '1999-02-31';
+a
+SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01';
+a
+0000-00-00
+0000-01-02
+0001-01-01
+1001-00-00
+1001-01-01
+SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00';
+a
+1001-00-00
+1001-01-01
+1002-00-00
+SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01';
+a
+0001-01-01
+1001-00-00
+1001-01-01
+DROP TABLE t1;
+create table t1 (a int, b int);
+insert into t1 values (10,10),(2,5),(0,0);
+select * from t1;
+a	b
+10	10
+2	5
+0	0
+alter table t1
+PARTITION BY LIST (a)
+(
+PARTITION p2 VALUES IN (1,2,3),
+PARTITION p1 VALUES IN (20,0),
+PARTITION p0 DEFAULT
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a)
+(PARTITION p2 VALUES IN (1,2,3) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (20,0) ENGINE = MyISAM,
+ PARTITION p0 DEFAULT ENGINE = MyISAM) */
+select * from t1;
+a	b
+2	5
+0	0
+10	10
+explain partitions select * from t1 where a=2 and b=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2	system	NULL	NULL	NULL	NULL	1	
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+alter table t1
+PARTITION BY LIST (a)
+(
+PARTITION p2 VALUES IN (1,2,3),
+PARTITION p1 VALUES IN (20,0),
+PARTITION p0 VALUES IN (10)
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a)
+(PARTITION p2 VALUES IN (1,2,3) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (20,0) ENGINE = MyISAM,
+ PARTITION p0 VALUES IN (10) ENGINE = MyISAM) */
+select * from t1;
+a	b
+2	5
+0	0
+10	10
+explain partitions select * from t1 where a=2 and b=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2	system	NULL	NULL	NULL	NULL	1	
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+alter table t1
+PARTITION BY LIST (a)
+(
+PARTITION p2 DEFAULT,
+PARTITION p1 VALUES IN (20,0),
+PARTITION p0 VALUES IN (10)
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a)
+(PARTITION p2 DEFAULT ENGINE = MyISAM,
+ PARTITION p1 VALUES IN (20,0) ENGINE = MyISAM,
+ PARTITION p0 VALUES IN (10) ENGINE = MyISAM) */
+select * from t1;
+a	b
+2	5
+0	0
+10	10
+explain partitions select * from t1 where a=2 and b=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2	system	NULL	NULL	NULL	NULL	1	
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+drop table t1;
+create table t1 (a int, b int);
+insert into t1 values (10,10),(2,5),(0,0);
+select * from t1;
+a	b
+10	10
+2	5
+0	0
+alter table t1
+PARTITION BY LIST COLUMNS(a,b)
+(
+PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+PARTITION p1 VALUES IN ((1,1),(0,0)),
+PARTITION p0 DEFAULT
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN ((1,1),(0,0)) ENGINE = MyISAM,
+ PARTITION p0 DEFAULT ENGINE = MyISAM) */
+select * from t1;
+a	b
+2	5
+0	0
+10	10
+explain partitions select * from t1 where a=2 and b=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2	system	NULL	NULL	NULL	NULL	1	
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+alter table t1
+PARTITION BY LIST COLUMNS(a,b)
+(
+PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+PARTITION p1 VALUES IN ((1,1),(0,0)),
+PARTITION p0 VALUES IN ((10,10))
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)) ENGINE = MyISAM,
+ PARTITION p1 VALUES IN ((1,1),(0,0)) ENGINE = MyISAM,
+ PARTITION p0 VALUES IN ((10,10)) ENGINE = MyISAM) */
+select * from t1;
+a	b
+2	5
+0	0
+10	10
+explain partitions select * from t1 where a=2 and b=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2	system	NULL	NULL	NULL	NULL	1	
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+alter table t1
+PARTITION BY LIST COLUMNS(a,b)
+(
+PARTITION p2 DEFAULT,
+PARTITION p1 VALUES IN ((1,1),(0,0)),
+PARTITION p0 VALUES IN ((10,10))
+)
+;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p2 DEFAULT ENGINE = MyISAM,
+ PARTITION p1 VALUES IN ((1,1),(0,0)) ENGINE = MyISAM,
+ PARTITION p0 VALUES IN ((10,10)) ENGINE = MyISAM) */
+select * from t1;
+a	b
+2	5
+0	0
+10	10
+explain partitions select * from t1 where a=2 and b=5;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p2	system	NULL	NULL	NULL	NULL	1	
+explain partitions select * from t1 where a=10 and b=10;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p0	system	NULL	NULL	NULL	NULL	1	
+drop table t1;
diff --git a/mysql-test/t/partition_default.test b/mysql-test/t/partition_default.test
new file mode 100644
index 0000000..9faf777
--- /dev/null
+++ b/mysql-test/t/partition_default.test
@@ -0,0 +1,338 @@
+
+--source include/have_partition.inc
+
+#
+# expression lists
+#
+create table t1 (a int, b int)
+  PARTITION BY LIST (a)
+  (
+    PARTITION p2 VALUES IN (4,5,6),
+    PARTITION p1 VALUES IN (1),
+    PARTITION p0 DEFAULT
+  )
+;
+show create table t1;
+insert into t1 values (10,10);
+select * from t1;
+drop table t1;
+
+--error ER_PARTITION_DEFAULT_ERROR
+create table t1 (a int, b int)
+  PARTITION BY LIST (a)
+  (
+    PARTITION p2 VALUES IN (4,5,6),
+    PARTITION p1 VALUES IN (1),
+    PARTITION p0 DEFAULT,
+    PARTITION p3 DEFAULT
+  )
+;
+--error ER_PARTITION_DEFAULT_ERROR
+create table t1 (a int, b int)
+  PARTITION BY LIST (a)
+  (
+    PARTITION p0 DEFAULT,
+    PARTITION p2 VALUES IN (4,5,6),
+    PARTITION p1 VALUES IN (1),
+    PARTITION p3 DEFAULT
+  )
+;
+
+create table t1 (a int, b int)
+  PARTITION BY LIST (a)
+  (
+    PARTITION p0 DEFAULT,
+    PARTITION p2 VALUES IN (4,5,6),
+    PARTITION p1 VALUES IN (1)
+  )
+;
+show create table t1;
+insert into t1 values (10,10);
+select * from t1;
+drop table t1;
+
+#
+# Default has its value as 0 check that they are not clash.
+#
+create table t1 (a int, b int)
+  PARTITION BY LIST (a)
+  (
+    PARTITION p0 DEFAULT,
+    PARTITION p2 VALUES IN (4,5,6),
+    PARTITION p1 VALUES IN (1, 0)
+  )
+;
+show create table t1;
+insert into t1 values (10,10);
+select * from t1;
+drop table t1;
+
+#
+# columns lists
+#
+create table t1 (a int, b int)
+  PARTITION BY LIST COLUMNS(a,b)
+  (
+    PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+    PARTITION p1 VALUES IN ((1,1),(0,0)),
+    PARTITION p0 DEFAULT
+  )
+;
+show create table t1;
+insert into t1 values (10,10);
+select * from t1;
+drop table t1;
+
+--error ER_PARTITION_DEFAULT_ERROR
+create table t1 (a int, b int)
+  PARTITION BY LIST COLUMNS(a,b)
+  (
+    PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+    PARTITION p1 VALUES IN ((1,1),(0,0)),
+    PARTITION p0 DEFAULT,
+    PARTITION p3 DEFAULT
+  )
+;
+
+--error ER_PARTITION_DEFAULT_ERROR
+create table t1 (a int, b int)
+  PARTITION BY LIST COLUMNS(a,b)
+  (
+    PARTITION p0 DEFAULT,
+    PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+    PARTITION p1 VALUES IN ((1,1),(0,0)),
+    PARTITION p3 DEFAULT
+  )
+;
+
+#
+# partititon prunning test
+#
+
+create table t1 (a int, b int)
+  PARTITION BY LIST (a)
+  (
+    PARTITION p2 VALUES IN (4,5,6),
+    PARTITION p1 VALUES IN (1,20),
+    PARTITION p0 default
+  )
+;
+show create table t1;
+insert into t1 values (10,10);
+select * from t1 where a=10;
+select * from t1 where a<=10;
+select * from t1 where a<=20;
+select * from t1 where a>=10;
+select * from t1 where a>=5;
+insert into t1 values (20,20),(5,5);
+select * from t1 where a=10;
+select * from t1 where a<=10;
+select * from t1 where a<=20;
+select * from t1 where a>=10;
+select * from t1 where a>=5;
+explain partitions select * from t1 where a=10;
+explain partitions select * from t1 where a=5;
+select * from t1 where a=10 or a=5;
+explain partitions select * from t1 where a=10 or a=5;
+
+drop table t1;
+
+create table t1 (a int, b int)
+  PARTITION BY LIST COLUMNS(a,b)
+  (
+    PARTITION p2 VALUES IN ((1,4),(2,5),(3,6),(5,5)),
+    PARTITION p1 VALUES IN ((1,1),(20,20)),
+    PARTITION p0 DEFAULT
+  )
+;
+show create table t1;
+insert into t1 values (10,10);
+select * from t1 where a=10 and b=10;
+explain partitions select * from t1 where a=10 and b=10;
+select * from t1 where a=10;
+explain partitions select * from t1 where a=10;
+select * from t1 where a<=10;
+select * from t1 where a>=10;
+insert into t1 values (20,20),(5,5);
+select * from t1 where a=10 and b=10;
+explain partitions select * from t1 where a=10 and b=10;
+select * from t1 where a=10 and b=10 or a=20 and b=20;
+explain partitions select * from t1 where a=10 and b=10 or a=20 and b=20;
+drop table t1;
+
+#
+# partition pruning with expressions
+#
+create table t1 (a int, b int);
+
+insert into t1 values (10,10),(2,5),(0,0);
+
+select * from t1;
+
+alter table t1
+  PARTITION BY LIST (a+b)
+  (
+    PARTITION p2 VALUES IN (1,2,3,7),
+    PARTITION p1 VALUES IN (21,0),
+    PARTITION p0 DEFAULT
+  )
+;
+show create table t1;
+select * from t1;
+explain partitions select * from t1 where a=2 and b=5;
+explain partitions select * from t1 where a=10 and b=10;
+drop table t1;
+
+create table t1 (a int, b int);
+
+insert into t1 values (10,10),(2,5),(0,0);
+
+select * from t1;
+
+alter table t1
+  PARTITION BY LIST (a+5)
+  (
+    PARTITION p2 VALUES IN (1,2,3,7),
+    PARTITION p1 VALUES IN (0),
+    PARTITION p0 DEFAULT
+  )
+;
+show create table t1;
+select * from t1;
+explain partitions select * from t1 where a>=2;
+explain partitions select * from t1 where a>=2 and a<=3;
+explain partitions select * from t1 where a=10;
+drop table t1;
+
+
+
+CREATE TABLE t1 (a DATE, KEY(a))
+PARTITION BY LIST (TO_DAYS(a))
+(PARTITION `pDEF` DEFAULT,
+ PARTITION `p2001-01-01` VALUES IN (TO_DAYS('2001-01-01')),
+ PARTITION `pNULL` VALUES IN (NULL),
+ PARTITION `p0000-01-02` VALUES IN (TO_DAYS('0000-01-02')),
+ PARTITION `p1001-01-01` VALUES IN (TO_DAYS('1001-01-01')));
+if ($verify_without_partitions)
+{
+ALTER TABLE t1 REMOVE PARTITIONING;
+}
+INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'),
+      ('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01');
+--source include/partition_date_range.inc
+--echo # test without index
+ALTER TABLE t1 DROP KEY a;
+--source include/partition_date_range.inc
+DROP TABLE t1;
+--echo # TO_SECONDS, test of LIST and index
+CREATE TABLE t1 (a DATE, KEY(a))
+PARTITION BY LIST (TO_SECONDS(a))
+(PARTITION `pDEF` DEFAULT,
+ PARTITION `p2001-01-01` VALUES IN (TO_SECONDS('2001-01-01')),
+ PARTITION `pNULL` VALUES IN (NULL),
+ PARTITION `p0000-01-02` VALUES IN (TO_SECONDS('0000-01-02')),
+ PARTITION `p1001-01-01` VALUES IN (TO_SECONDS('1001-01-01')));
+if ($verify_without_partitions)
+{
+ALTER TABLE t1 REMOVE PARTITIONING;
+}
+INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'),
+      ('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01');
+--source include/partition_date_range.inc
+--echo # test without index
+ALTER TABLE t1 DROP KEY a;
+--source include/partition_date_range.inc
+DROP TABLE t1;
+
+#
+# ALTER TABLE test
+#
+
+create table t1 (a int, b int);
+
+insert into t1 values (10,10),(2,5),(0,0);
+
+select * from t1;
+
+alter table t1
+  PARTITION BY LIST (a)
+  (
+    PARTITION p2 VALUES IN (1,2,3),
+    PARTITION p1 VALUES IN (20,0),
+    PARTITION p0 DEFAULT
+  )
+;
+show create table t1;
+select * from t1;
+explain partitions select * from t1 where a=2 and b=5;
+explain partitions select * from t1 where a=10 and b=10;
+alter table t1
+  PARTITION BY LIST (a)
+  (
+    PARTITION p2 VALUES IN (1,2,3),
+    PARTITION p1 VALUES IN (20,0),
+    PARTITION p0 VALUES IN (10)
+  )
+;
+show create table t1;
+select * from t1;
+explain partitions select * from t1 where a=2 and b=5;
+explain partitions select * from t1 where a=10 and b=10;
+alter table t1
+  PARTITION BY LIST (a)
+  (
+    PARTITION p2 DEFAULT,
+    PARTITION p1 VALUES IN (20,0),
+    PARTITION p0 VALUES IN (10)
+  )
+;
+show create table t1;
+select * from t1;
+explain partitions select * from t1 where a=2 and b=5;
+explain partitions select * from t1 where a=10 and b=10;
+drop table t1;
+
+
+create table t1 (a int, b int);
+
+insert into t1 values (10,10),(2,5),(0,0);
+
+select * from t1;
+
+alter table t1
+  PARTITION BY LIST COLUMNS(a,b)
+  (
+    PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+    PARTITION p1 VALUES IN ((1,1),(0,0)),
+    PARTITION p0 DEFAULT
+  )
+;
+show create table t1;
+select * from t1;
+explain partitions select * from t1 where a=2 and b=5;
+explain partitions select * from t1 where a=10 and b=10;
+alter table t1
+  PARTITION BY LIST COLUMNS(a,b)
+  (
+    PARTITION p2 VALUES IN ((1,4),(2,5),(3,6)),
+    PARTITION p1 VALUES IN ((1,1),(0,0)),
+    PARTITION p0 VALUES IN ((10,10))
+  )
+;
+show create table t1;
+select * from t1;
+explain partitions select * from t1 where a=2 and b=5;
+explain partitions select * from t1 where a=10 and b=10;
+alter table t1
+  PARTITION BY LIST COLUMNS(a,b)
+  (
+    PARTITION p2 DEFAULT,
+    PARTITION p1 VALUES IN ((1,1),(0,0)),
+    PARTITION p0 VALUES IN ((10,10))
+  )
+;
+show create table t1;
+select * from t1;
+explain partitions select * from t1 where a=2 and b=5;
+explain partitions select * from t1 where a=10 and b=10;
+drop table t1;
diff --git a/sql/partition_element.h b/sql/partition_element.h
index 308a4d6..b979b7a 100644
--- a/sql/partition_element.h
+++ b/sql/partition_element.h
@@ -65,7 +65,7 @@ typedef struct p_column_list_val
   Item* item_expression;
   partition_info *part_info;
   uint partition_id;
-  bool max_value;
+  bool max_value; // MAXVALUE for RANGE type or DEFAULT value for LIST type
   bool null_value;
   char fixed;
 } part_column_list_val;
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 4f297c6..db14c198 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1528,6 +1528,13 @@ bool partition_info::check_list_constants(THD *thd)
     do
     {
       part_def= list_func_it++;
+      if (part_def->max_value && part_type == LIST_PARTITION)
+      {
+        // DEFAULT is not a real value so let's exclude it from sorting.
+        DBUG_ASSERT(num_list_values);
+        num_list_values--;
+        continue;
+      }
       List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
       while ((list_value= list_val_it2++))
       {
@@ -1557,6 +1564,13 @@ bool partition_info::check_list_constants(THD *thd)
     do
     {
       part_def= list_func_it++;
+      if (part_def->max_value && part_type == LIST_PARTITION)
+      {
+        // DEFAULT is not a real value so let's exclude it from sorting.
+        DBUG_ASSERT(num_list_values);
+        num_list_values--;
+        continue;
+      }
       List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
       while ((list_value= list_val_it2++))
       {
@@ -2287,11 +2301,20 @@ int partition_info::add_max_value(THD *thd)
   DBUG_ENTER("partition_info::add_max_value");
 
   part_column_list_val *col_val;
-  if (!(col_val= add_column_value(thd)))
+  /*
+    Makes for LIST COLUMNS list of tuple DEFAULT valeus and one in other
+    cases
+  */
+  uint max_val= (num_columns && part_type == LIST_PARTITION) ?
+                 num_columns : 1;
+  for (uint i= 0; i < max_val; i++)
   {
-    DBUG_RETURN(TRUE);
+    if (!(col_val= add_column_value(thd)))
+    {
+      DBUG_RETURN(TRUE);
+    }
+    col_val->max_value= TRUE;
   }
-  col_val->max_value= TRUE;
   DBUG_RETURN(FALSE);
 }
 
@@ -2584,20 +2607,26 @@ int partition_info::fix_partition_values(THD *thd,
   if (col_val->max_value)
   {
     /* The parser ensures we're not LIST partitioned here */
-    DBUG_ASSERT(part_type == RANGE_PARTITION);
+    DBUG_ASSERT(part_type == RANGE_PARTITION ||
+                part_type == LIST_PARTITION);
     if (defined_max_value)
     {
-      my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0));
+      my_error((part_type == RANGE_PARTITION) ?
+               ER_PARTITION_MAXVALUE_ERROR :
+               ER_PARTITION_DEFAULT_ERROR, MYF(0));
       DBUG_RETURN(TRUE);
     }
-    if (part_id == (num_parts - 1))
+    if (part_id == (num_parts - 1) ||
+        part_type == LIST_PARTITION)
     {
       defined_max_value= TRUE;
+      default_partition_id= part_id;
       part_elem->max_value= TRUE;
       part_elem->range_value= LONGLONG_MAX;
     }
     else
     {
+      DBUG_ASSERT(part_type != LIST_PARTITION);
       my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0));
       DBUG_RETURN(TRUE);
     }
@@ -2840,6 +2869,24 @@ bool partition_info::fix_parser_data(THD *thd)
       part_elem_value *val= list_val_it++;
       if (column_list)
       {
+        if (part_type == LIST_PARTITION)
+        {
+          DBUG_ASSERT(val->added_items);
+          if (val->col_val_array[0].max_value)
+          {
+            //default value
+            DBUG_ASSERT(val->added_items == num_columns);
+            if (defined_max_value)
+            {
+              my_error(ER_PARTITION_DEFAULT_ERROR, MYF(0));
+              DBUG_RETURN(TRUE);
+            }
+            defined_max_value= TRUE;
+            default_partition_id= i; // i is a partition id
+            part_elem->max_value= TRUE;
+            continue;
+          }
+        }
         if (val->added_items != num_columns)
         {
           my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 5181e19..f70a68b 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -202,6 +202,7 @@ class partition_info : public Sql_alloc
   uint num_full_part_fields;
 
   uint has_null_part_id;
+  uint32 default_partition_id;
   /*
     This variable is used to calculate the partition id when using
     LINEAR KEY/HASH. This functionality is kept in the MySQL Server
@@ -230,6 +231,10 @@ class partition_info : public Sql_alloc
   bool use_default_num_subpartitions;
   bool default_partitions_setup;
   bool defined_max_value;
+  inline bool has_default_partititon()
+  {
+    return (part_type == LIST_PARTITION && defined_max_value);
+  }
   bool list_of_part_fields;                  // KEY or COLUMNS PARTITIONING
   bool list_of_subpart_fields;               // KEY SUBPARTITIONING
   bool linear_hash_ind;                      // LINEAR HASH/KEY
@@ -399,6 +404,7 @@ static inline void init_single_partition_iterator(uint32 part_id,
   part_iter->part_nums.start= part_iter->part_nums.cur= part_id;
   part_iter->part_nums.end= part_id+1;
   part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
+  part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE;
   part_iter->get_next= get_next_partition_id_range;
 }
 
@@ -410,6 +416,7 @@ void init_all_partitions_iterator(partition_info *part_info,
   part_iter->part_nums.start= part_iter->part_nums.cur= 0;
   part_iter->part_nums.end= part_info->num_parts;
   part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
+  part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE;
   part_iter->get_next= get_next_partition_id_range;
 }
 
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 361d68f..af85e1c 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -7213,3 +7213,6 @@ ER_CALCULATING_DEFAULT_VALUE
         eng "Got an error when calculating default value for %`s"
 ER_EXPRESSION_REFERS_TO_UNINIT_FIELD 01000
         eng "Expression for field %`-.64s is refering to uninitialized field %`s"
+ER_PARTITION_DEFAULT_ERROR
+        eng "Only one DEFAULT partition allowed"
+        ukr "Припустимо мати тільки один DEFAULT розділ" 
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index b45f855..9cef2b1 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -2311,6 +2311,14 @@ static int add_partition_values(File fptr, partition_info *part_info,
   {
     uint i;
     List_iterator<part_elem_value> list_val_it(p_elem->list_val_list);
+
+    if (p_elem->max_value)
+    {
+      DBUG_ASSERT(part_info->defined_max_value);
+      err+= add_string(fptr, " DEFAULT");
+      goto end;
+    }
+
     err+= add_string(fptr, " VALUES IN ");
     uint num_items= p_elem->list_val_list.elements;
 
@@ -3070,6 +3078,11 @@ int get_partition_id_list_col(partition_info *part_info,
     }
   }
 notfound:
+  if (part_info->defined_max_value)
+  {
+    *part_id= part_info->default_partition_id;
+    DBUG_RETURN(0);
+  }
   *part_id= 0;
   DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
 }
@@ -3123,6 +3136,11 @@ int get_partition_id_list(partition_info *part_info,
     }
   }
 notfound:
+  if (part_info->defined_max_value)
+  {
+    *part_id= part_info->default_partition_id;
+    DBUG_RETURN(0);
+  }
   *part_id= 0;
   DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
 }
@@ -7677,6 +7695,7 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
                                             uint flags,
                                             PARTITION_ITERATOR *part_iter)
 {
+  bool can_match_multiple_values;
   uint32 nparts;
   get_col_endpoint_func  UNINIT_VAR(get_col_endpoint);
   DBUG_ENTER("get_part_iter_for_interval_cols_via_map");
@@ -7696,6 +7715,12 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
   else
     assert(0);
 
+  can_match_multiple_values= (flags || !min_value || !max_value ||
+                              (min_len != max_len) ||
+                              memcmp(min_value, max_value, min_len));
+  if (can_match_multiple_values && part_info->has_default_partititon())
+    part_iter->ret_default_part= part_iter->ret_default_part_orig= TRUE;
+
   if (flags & NO_MIN_RANGE)
     part_iter->part_nums.start= part_iter->part_nums.cur= 0;
   else
@@ -7731,7 +7756,14 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
                                                nparts);
   }
   if (part_iter->part_nums.start == part_iter->part_nums.end)
+  {
+    if (part_info->has_default_partititon())
+    {
+      part_iter->ret_default_part= part_iter->ret_default_part_orig= TRUE;
+      DBUG_RETURN(1);
+    }
     DBUG_RETURN(0);
+  }
   DBUG_RETURN(1);
 }
 
@@ -7792,6 +7824,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
   (void)min_len;
   (void)max_len;
   part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
+  part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE;
 
   if (part_info->part_type == RANGE_PARTITION)
   {
@@ -7830,6 +7863,8 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
 
   can_match_multiple_values= (flags || !min_value || !max_value ||
                               memcmp(min_value, max_value, field_len));
+  if (can_match_multiple_values && part_info->has_default_partititon())
+    part_iter->ret_default_part= part_iter->ret_default_part_orig= TRUE;
   if (can_match_multiple_values &&
       (part_info->part_type == RANGE_PARTITION ||
        part_info->has_null_value))
@@ -7859,6 +7894,12 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
     {
       /* The right bound is X <= NULL, i.e. it is a "X IS NULL" interval */
       part_iter->part_nums.end= 0;
+      /*
+        It is something like select * from tbl where col IS NULL
+        and we have partition with NULL to catch it, so we do not need
+        DEFAULT partition
+      */
+      part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE;
       DBUG_RETURN(1);
     }
   }
@@ -7900,7 +7941,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
         }
       }
       if (part_iter->part_nums.start == max_endpoint_val)
-        DBUG_RETURN(0); /* No partitions */
+        goto not_found;
     }
   }
 
@@ -7937,9 +7978,17 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
     }
     if (part_iter->part_nums.start >= part_iter->part_nums.end &&
         !part_iter->ret_null_part)
-      DBUG_RETURN(0); /* No partitions */
+      goto not_found;
   }
   DBUG_RETURN(1); /* Ok, iterator initialized */
+
+not_found:
+  if (part_info->has_default_partititon())
+  {
+    part_iter->ret_default_part= part_iter->ret_default_part_orig= TRUE;
+    DBUG_RETURN(1);
+  }
+  DBUG_RETURN(0); /* No partitions */
 }
 
 
@@ -8003,6 +8052,8 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info,
   (void)max_len;
 
   part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
+  part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE;
+
   if (is_subpart)
   {
     field= part_info->subpart_field_array[0];
@@ -8134,6 +8185,8 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
       part_iter->ret_null_part= FALSE;
       return 0;                    /* NULL always in first range partition */
     }
+    DBUG_ASSERT(!part_iter->ret_default_part);
+
     part_iter->part_nums.cur= part_iter->part_nums.start;
     part_iter->ret_null_part= part_iter->ret_null_part_orig;
     return NOT_A_PARTITION_ID;
@@ -8171,8 +8224,14 @@ uint32 get_next_partition_id_list(PARTITION_ITERATOR *part_iter)
       part_iter->ret_null_part= FALSE;
       return part_iter->part_info->has_null_part_id;
     }
+    if (part_iter->ret_default_part)
+    {
+      part_iter->ret_default_part= FALSE;
+      return part_iter->part_info->default_partition_id;
+    }
     part_iter->part_nums.cur= part_iter->part_nums.start;
     part_iter->ret_null_part= part_iter->ret_null_part_orig;
+    part_iter->ret_default_part= part_iter->ret_default_part_orig;
     return NOT_A_PARTITION_ID;
   }
   else
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index dd352b6..b225c14 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -177,6 +177,10 @@ typedef struct st_partition_iter
     iterator also produce id of the partition that contains NULL value.
   */
   bool ret_null_part, ret_null_part_orig;
+  /*
+    We should return DEFAULT partition.
+  */
+  bool ret_default_part, ret_default_part_orig;
   struct st_part_num_range
   {
     uint32 start;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 9d7e735..072eb1b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5242,6 +5242,27 @@ opt_part_values:
               part_info->part_type= LIST_PARTITION;
           }
           part_values_in {}
+        | DEFAULT
+         {
+            LEX *lex= Lex;
+            partition_info *part_info= lex->part_info;
+            if (! lex->is_partition_management())
+            {
+              if (part_info->part_type != LIST_PARTITION)
+                my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
+                                  "LIST", "DEFAULT"));
+            }
+            else
+              part_info->part_type= LIST_PARTITION;
+            if (part_info->init_column_part(thd))
+            {
+              MYSQL_YYABORT;
+            }
+            if (part_info->add_max_value(thd))
+            {
+              MYSQL_YYABORT;
+            }
+         }
         ;
 
 part_func_max:



More information about the commits mailing list