Commit ddee02ec authored by unknown's avatar unknown

Merge abotchkov@bk-internal.mysql.com:/home/bk/mysql-5.1-kt

into  mysql.com:/home/hf/mysql-5.1.mrg

parents 9f465327 e1ff81bb
drop table if exists t1;
create table t1 (s1 char(2) character set utf8)
partition by list (case when s1 > 'cz' then 1 else 2 end)
(partition p1 values in (1),
partition p2 values in (2));
drop table t1;
create table t1 (a int)
partition by key(a)
partitions 0.2+e1;
......@@ -21,32 +16,6 @@ partition by key(a)
partitions 1e+300;
ERROR 42000: Only integers allowed as number here near '1e+300' at line 3
create table t1 (a int)
engine = innodb
partition by key (a);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 2 8192 16384 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (0), (1), (2), (3);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 4 4096 16384 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
drop table t1;
create table t1 (a int auto_increment primary key)
engine = innodb
partition by key (a);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 2 8192 16384 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 4 4096 16384 0 0 0 5 NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 8 2048 16384 0 0 0 9 NULL NULL NULL latin1_swedish_ci NULL partitioned
drop table t1;
create table t1 (a int)
partition by key (a)
(partition p0 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');
ERROR 42000: Incorrect table name 'part-data'
......@@ -1042,17 +1011,6 @@ set session sql_mode='';
drop table t1;
create table t1 (a int)
partition by key (a)
(partition p1 engine = innodb);
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
drop table t1;
create table t1 (a int)
partition by key (a)
(partition p0 engine = MERGE);
ERROR HY000: Engine cannot be used in partitioned tables
create table t1 (a varchar(1))
......
drop table if exists t1;
create table t1 (a int)
engine = x
partition by key (a);
Warnings:
Error 1286 Unknown table engine 'x'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (a) */
drop table t1;
create table t1 (a int)
engine = innodb
partition by list (a)
(partition p0 values in (0));
alter table t1 engine = x;
Warnings:
Error 1286 Unknown table engine 'x'
show create table t1;
Table Create Table
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;
partition by list (a)
partitions 3
(partition x1 values in (1,2,9,4) tablespace ts1,
......
drop table if exists t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin)
partition by hash(length(a))
partitions 10;
insert into t1 values (''),(' '),('a'),('a '),('a ');
explain partitions select * from t1 where a='a ';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where
explain partitions select * from t1 where a='a';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where
explain partitions select * from t1 where a='a ' OR a='a';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where
drop table t1;
create table t1 (a int unsigned)
partition by hash(a div 2)
partitions 4;
......
......@@ -3,3 +3,74 @@ show table status like 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 2 8192 16384 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
drop table t1;
create table t1 (a int)
engine = innodb
partition by key (a);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 2 8192 16384 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (0), (1), (2), (3);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 4 4096 16384 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
drop table t1;
create table t1 (a int auto_increment primary key)
engine = innodb
partition by key (a);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 2 8192 16384 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 4 4096 16384 0 0 0 5 NULL NULL NULL latin1_swedish_ci NULL partitioned
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 InnoDB 10 Compact 8 2048 16384 0 0 0 9 NULL NULL NULL latin1_swedish_ci NULL partitioned
drop table t1;
create table t1 (a int)
partition by key (a)
(partition p1 engine = innodb);
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
drop table t1;
create table t1 (a date)
engine = innodb
partition by range (year(a))
(partition p0 values less than (2006),
partition p1 values less than (2007));
explain partitions select * from t1
where a between '2006-01-01' and '2007-06-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 2 Using where
drop table t1;
create table t1 (a int)
engine = x
partition by key (a);
Warnings:
Error 1286 Unknown table engine 'x'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (a) */
drop table t1;
create table t1 (a int)
engine = innodb
partition by list (a)
(partition p0 values in (0));
alter table t1 engine = x;
Warnings:
Error 1286 Unknown table engine 'x'
show create table t1;
Table Create Table
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;
......@@ -284,13 +284,6 @@ explain partitions select * from t9 where a <= '2004-12-19';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t9 p0,p1 ALL NULL NULL NULL NULL 2 Using where
drop table t5,t6,t7,t8,t9;
create table t1 (a enum('a','b','c','d') default 'a')
partition by hash (ascii(a)) partitions 2;
insert into t1 values ('a'),('b'),('c');
explain partitions select * from t1 where a='b';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 3 Using where
drop table t1;
create table t1 (
a1 int not null
)
......@@ -683,8 +676,9 @@ f_int1 f_int2
8 8
9 9
drop table t1;
create table t1 (a char(10)) partition by list(length(a)) (
partition p1 values in (1),
create table t1 (a char(10) binary)
partition by list(length(a))
(partition p1 values in (1),
partition p2 values in (2),
partition p3 values in (3),
partition p4 values in (4),
......
drop table if exists t1;
create table t1 (a date)
engine = innodb
partition by range (year(a))
(partition p0 values less than (2006),
partition p1 values less than (2007));
explain partitions select * from t1
where a between '2006-01-01' and '2007-06-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 2 Using where
create table t1 (a varchar(10) charset latin1 collate latin1_bin, b int)
partition by range (length(a) * b)
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 2),('a',3);
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin, b int)
partition by range (b* length(a) * b)
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 2),('a',3);
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin,
b varchar(10) charset latin1 collate latin1_bin)
partition by range (length(b) * length(a))
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 'b '),('a','b');
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin,
b varchar(10) charset latin1 collate latin1_bin)
partition by range (length(a) * length(b))
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 'b '),('a','b');
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin,
b varchar(10) charset latin1 collate latin1_bin, c int)
partition by range (length(a) * c)
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 'b ', 2),('a','b', 3);
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin,
b varchar(10) charset latin1 collate latin1_bin, c int)
partition by range (c * length(a))
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 'b ', 2),('a','b', 3);
drop table t1;
create table t1 (a int unsigned)
partition by range (a)
......@@ -719,3 +743,45 @@ WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR
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;
create table t1 (a varchar(20))
partition by range (crc32(md5(a)))
(partition p0 values less than (100),
partition p1 values less than maxvalue);
insert into t1 values ("12345678901234567890");
insert into t1 values ("A2345678901234567890");
insert into t1 values ("B2345678901234567890");
insert into t1 values ("1234567890123456789");
insert into t1 values ("1234567890123456");
select * from t1;
a
12345678901234567890
A2345678901234567890
B2345678901234567890
1234567890123456789
1234567890123456
explain partitions select * from t1 where a = "12345678901234567890";
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 5 Using where
explain partitions select * from t1 where a = "12345678901234567890" OR
a = "A2345678901234567890" OR
a = "B2345678901234567890" OR
a = "C2345678901234567890";
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 5 Using where
explain partitions select * from t1 where a = "01234567890123456";
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 5 Using where
select * from t1 where a = "01234567890123456";
a
select * from t1 where a = "12345678901234567890" OR
a = "A2345678901234567890" OR
a = "B2345678901234567890" OR
a = "C2345678901234567890";
a
12345678901234567890
A2345678901234567890
B2345678901234567890
select * from t1 where a = "12345678901234567890";
a
12345678901234567890
drop table t1;
......@@ -13,15 +13,6 @@
drop table if exists t1;
--enable_warnings
#
# Bug#14367: Partitions: crash if utf8 column
#
create table t1 (s1 char(2) character set utf8)
partition by list (case when s1 > 'cz' then 1 else 2 end)
(partition p1 values in (1),
partition p2 values in (2));
drop table t1;
#
# Bug 15890: Strange number of partitions accepted
#
......@@ -42,27 +33,6 @@ create table t1 (a int)
partition by key(a)
partitions 1e+300;
#
# Bug 21173: SHOW TABLE STATUS crashes server in InnoDB
#
create table t1 (a int)
engine = innodb
partition by key (a);
show table status;
insert into t1 values (0), (1), (2), (3);
show table status;
drop table t1;
create table t1 (a int auto_increment primary key)
engine = innodb
partition by key (a);
show table status;
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
drop table t1;
#
# Bug 21350: Data Directory problems
#
......@@ -1193,22 +1163,6 @@ show create table t1;
set session sql_mode='';
drop table t1;
#
# BUG 19122 Crash after ALTER TABLE t1 REBUILD PARTITION p1
#
create table t1 (a int)
partition by key (a)
(partition p1 engine = innodb);
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
drop table t1;
#
# BUG 19304 Partitions: MERGE handler not allowed in partitioned tables
#
......
......@@ -8,24 +8,6 @@
drop table if exists t1;
--enable_warnings
#
# Bug 20397: Partitions: Crash when using non-existing engine
#
create table t1 (a int)
engine = x
partition by key (a);
show create table t1;
drop table t1;
create table t1 (a int)
engine = innodb
partition by list (a)
(partition p0 values in (0));
alter table t1 engine = x;
show create table t1;
drop table t1;
#
# Partition by key stand-alone error
#
......
......@@ -9,6 +9,18 @@
drop table if exists t1;
--enable_warnings
#
# BUG 18198: Partition functions handling
#
create table t1 (a varchar(10) charset latin1 collate latin1_bin)
partition by hash(length(a))
partitions 10;
insert into t1 values (''),(' '),('a'),('a '),('a ');
explain partitions select * from t1 where a='a ';
explain partitions select * from t1 where a='a';
explain partitions select * from t1 where a='a ' OR a='a';
drop table t1;
#
# More partition pruning tests, especially on interval walking
#
......
......@@ -8,3 +8,71 @@ create table t1 (a int) engine=innodb partition by hash(a) ;
show table status like 't1';
drop table t1;
#
# Bug 21173: SHOW TABLE STATUS crashes server in InnoDB
#
create table t1 (a int)
engine = innodb
partition by key (a);
show table status;
insert into t1 values (0), (1), (2), (3);
show table status;
drop table t1;
create table t1 (a int auto_increment primary key)
engine = innodb
partition by key (a);
show table status;
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
insert into t1 values (NULL), (NULL), (NULL), (NULL);
show table status;
drop table t1;
#
# BUG 19122 Crash after ALTER TABLE t1 REBUILD PARTITION p1
#
create table t1 (a int)
partition by key (a)
(partition p1 engine = innodb);
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
alter table t1 rebuild partition p1;
drop table t1;
#
# Bug 21339: Crash in Explain Partitions
#
create table t1 (a date)
engine = innodb
partition by range (year(a))
(partition p0 values less than (2006),
partition p1 values less than (2007));
explain partitions select * from t1
where a between '2006-01-01' and '2007-06-01';
drop table t1;
#
# Bug 20397: Partitions: Crash when using non-existing engine
#
create table t1 (a int)
engine = x
partition by key (a);
show create table t1;
drop table t1;
create table t1 (a int)
engine = innodb
partition by list (a)
(partition p0 values in (0));
alter table t1 engine = x;
show create table t1;
drop table t1;
......@@ -238,11 +238,14 @@ explain partitions select * from t9 where a <= '2004-12-19';
drop table t5,t6,t7,t8,t9;
# Test the case where we can't create partitioning 'index'
create table t1 (a enum('a','b','c','d') default 'a')
partition by hash (ascii(a)) partitions 2;
insert into t1 values ('a'),('b'),('c');
explain partitions select * from t1 where a='b';
drop table t1;
#
# Not supported after bug#18198 is fixed
#
#create table t1 (a enum('a','b','c','d') default 'a')
# partition by hash (ascii(a)) partitions 2;
#insert into t1 values ('a'),('b'),('c');
#explain partitions select * from t1 where a='b';
#drop table t1;
#
# Test cases for bugs found in code review:
......@@ -535,8 +538,9 @@ select * from t1 where f_int1 between 5 and 15 order by f_int1;
drop table t1;
# part2: bug in pruning code
create table t1 (a char(10)) partition by list(length(a)) (
partition p1 values in (1),
create table t1 (a char(10) binary)
partition by list(length(a))
(partition p1 values in (1),
partition p2 values in (2),
partition p3 values in (3),
partition p4 values in (4),
......
......@@ -10,15 +10,46 @@ drop table if exists t1;
--enable_warnings
#
# Bug 21339: Crash in Explain Partitions
#
create table t1 (a date)
engine = innodb
partition by range (year(a))
(partition p0 values less than (2006),
partition p1 values less than (2007));
explain partitions select * from t1
where a between '2006-01-01' and '2007-06-01';
# BUG 18198: Various tests for partition functions
#
create table t1 (a varchar(10) charset latin1 collate latin1_bin, b int)
partition by range (length(a) * b)
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 2),('a',3);
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin, b int)
partition by range (b* length(a) * b)
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 2),('a',3);
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin,
b varchar(10) charset latin1 collate latin1_bin)
partition by range (length(b) * length(a))
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 'b '),('a','b');
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin,
b varchar(10) charset latin1 collate latin1_bin)
partition by range (length(a) * length(b))
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 'b '),('a','b');
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin,
b varchar(10) charset latin1 collate latin1_bin, c int)
partition by range (length(a) * c)
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 'b ', 2),('a','b', 3);
drop table t1;
create table t1 (a varchar(10) charset latin1 collate latin1_bin,
b varchar(10) charset latin1 collate latin1_bin, c int)
partition by range (c * length(a))
(partition p0 values less than (2), partition p1 values less than (400));
insert into t1 values ('a ', 'b ', 2),('a','b', 3);
drop table t1;
#
......@@ -699,3 +730,32 @@ WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR
(a >= '2005-07-01' AND a <= '2005-09-30');
DROP TABLE t1;
#
# Bug 18198: Try with a couple of cases using VARCHAR fields in
# partition function.
create table t1 (a varchar(20))
partition by range (crc32(md5(a)))
(partition p0 values less than (100),
partition p1 values less than maxvalue);
insert into t1 values ("12345678901234567890");
insert into t1 values ("A2345678901234567890");
insert into t1 values ("B2345678901234567890");
insert into t1 values ("1234567890123456789");
insert into t1 values ("1234567890123456");
select * from t1;
explain partitions select * from t1 where a = "12345678901234567890";
explain partitions select * from t1 where a = "12345678901234567890" OR
a = "A2345678901234567890" OR
a = "B2345678901234567890" OR
a = "C2345678901234567890";
explain partitions select * from t1 where a = "01234567890123456";
select * from t1 where a = "01234567890123456";
select * from t1 where a = "12345678901234567890" OR
a = "A2345678901234567890" OR
a = "B2345678901234567890" OR
a = "C2345678901234567890";
select * from t1 where a = "12345678901234567890";
drop table t1;
......@@ -1907,7 +1907,10 @@ int ha_ndbcluster::peek_indexed_rows(const byte *record)
error= m_part_info->get_partition_id(m_part_info, &part_id, &func_value);
dbug_tmp_restore_column_map(table->read_set, old_map);
if (error)
{
m_part_info->err_value= func_value;
DBUG_RETURN(error);
}
op->setPartitionId(part_id);
}
}
......@@ -2564,7 +2567,10 @@ int ha_ndbcluster::write_row(byte *record)
error= m_part_info->get_partition_id(m_part_info, &part_id, &func_value);
dbug_tmp_restore_column_map(table->read_set, old_map);
if (error)
{
m_part_info->err_value= func_value;
DBUG_RETURN(error);
}
op->setPartitionId(part_id);
}
......@@ -2756,6 +2762,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
m_part_info, &old_part_id, &new_part_id,
&func_value)))
{
m_part_info->err_value= func_value;
DBUG_RETURN(error);
}
......
......@@ -1366,6 +1366,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
i= 0;
part_count= 0;
orig_count= 0;
first= TRUE;
part_it.rewind();
do
{
......@@ -1393,9 +1394,16 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
DBUG_RETURN(ER_OUTOFMEMORY);
}
} while (++j < no_subparts);
if (part_elem->part_state == PART_CHANGED)
orig_count+= no_subparts;
else if (temp_partitions && first)
{
orig_count+= (no_subparts * temp_partitions);
first= FALSE;
}
}
} while (++i < no_parts);
first= FALSE;
/*
Step 5:
Create the new partitions and also open, lock and call external_lock
......@@ -2664,7 +2672,10 @@ int ha_partition::write_row(byte * buf)
#endif
dbug_tmp_restore_column_map(table->read_set, old_map);
if (unlikely(error))
{
m_part_info->err_value= func_value;
DBUG_RETURN(error);
}
m_last_part= part_id;
DBUG_PRINT("info", ("Insert in partition %d", part_id));
DBUG_RETURN(m_file[part_id]->write_row(buf));
......@@ -2713,6 +2724,7 @@ int ha_partition::update_row(const byte *old_data, byte *new_data)
m_part_info, &old_part_id, &new_part_id,
&func_value)))
{
m_part_info->err_value= func_value;
DBUG_RETURN(error);
}
......@@ -3657,7 +3669,10 @@ int ha_partition::read_range_first(const key_range *start_key,
if (!start_key) // Read first record
{
m_index_scan_type= partition_index_first;
if (m_ordered)
m_index_scan_type= partition_index_first;
else
m_index_scan_type= partition_index_first_unordered;
error= common_first_last(m_rec0);
}
else
......@@ -3871,6 +3886,18 @@ int ha_partition::handle_unordered_scan_next_partition(byte * buf)
DBUG_PRINT("info", ("index_first on partition %d", i));
error= file->index_first(buf);
break;
case partition_index_first_unordered:
/*
We perform a scan without sorting and this means that we
should not use the index_first since not all handlers
support it and it is also unnecessary to restrict sort
order.
*/
DBUG_PRINT("info", ("read_range_first on partition %d", i));
table->record[0]= buf;
error= file->read_range_first(0, end_range, eq_range, 0);
table->record[0]= m_rec0;
break;
default:
DBUG_ASSERT(FALSE);
DBUG_RETURN(1);
......
......@@ -45,9 +45,10 @@ private:
{
partition_index_read= 0,
partition_index_first= 1,
partition_index_last= 2,
partition_index_read_last= 3,
partition_no_index_scan= 4
partition_index_first_unordered= 2,
partition_index_last= 3,
partition_index_read_last= 4,
partition_no_index_scan= 5
};
/* Data for the partition handler */
int m_mode; // Open mode
......
......@@ -831,12 +831,20 @@ public:
Check if a partition function is allowed
SYNOPSIS
check_partition_func_processor()
bool_arg Return argument
int_arg Ignored
RETURN VALUE
0
TRUE Partition function not accepted
FALSE Partition function accepted
DESCRIPTION
check_partition_func_processor is used to check if a partition function
uses an allowed function. The default is that an item is not allowed
uses an allowed function. An allowed function will always ensure that
X=Y guarantees that also part_function(X)=part_function(Y) where X is
a set of partition fields and so is Y. The problems comes mainly from
character sets where two equal strings can be quite unequal. E.g. the
german character for double s is equal to 2 s.
The default is that an item is not allowed
in a partition function. However all mathematical functions, string
manipulation functions, date functions are allowed. Allowed functions
can never depend on server version, they cannot depend on anything
......@@ -847,9 +855,31 @@ public:
allowed in a partition function then it is very important to consider
whether this should be inherited to the new class. If not the function
below should be defined in the new Item class.
*/
virtual bool check_partition_func_processor(byte *bool_arg)
{ *(bool *)bool_arg= FALSE; return 0; }
The general behaviour is that most integer functions are allowed.
If the partition function contains any multi-byte collations then
the function check_part_func_fields will report an error on the
partition function independent of what functions are used. So the
only character sets allowed are single character collation and
even for those only a limited set of functions are allowed. The
problem with multi-byte collations is that almost every string
function has the ability to change things such that two strings
that are equal will not be equal after manipulated by a string
function. E.g. two strings one contains a double s, there is a
special german character that is equal to two s. Now assume a
string function removes one character at this place, then in
one the double s will be removed and in the other there will
still be one s remaining and the strings are no longer equal
and thus the partition function will not sort equal strings into
the same partitions.
So the check if a partition function is valid is two steps. First
check that the field types are valid, next check that the partition
function is valid. The current set of partition functions valid
assumes that there are no multi-byte collations amongst the partition
fields.
*/
virtual bool check_partition_func_processor(byte *bool_arg) { return TRUE;}
virtual bool subst_argument_checker(byte **arg)
{
if (*arg)
......@@ -1147,7 +1177,6 @@ public:
Item::maybe_null= TRUE;
}
bool check_partition_func_processor(byte *bool_arg) { return 0; }
bool fix_fields(THD *, Item **);
enum Type type() const;
......@@ -1193,7 +1222,7 @@ public:
Item_num() {} /* Remove gcc warning */
virtual Item_num *neg()= 0;
Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) { return FALSE;}
};
#define NO_CACHED_FIELD_INDEX ((uint)(-1))
......@@ -1351,7 +1380,7 @@ public:
bool collect_item_field_processor(byte * arg);
bool find_item_in_field_list_processor(byte *arg);
bool register_field_in_read_map(byte *arg);
bool check_partition_func_processor(byte *bool_arg) { return 0; }
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
void cleanup();
bool result_as_longlong()
{
......@@ -1400,7 +1429,7 @@ public:
bool is_null() { return 1; }
void print(String *str) { str->append(STRING_WITH_LEN("NULL")); }
Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_null_result :public Item_null
......@@ -1413,8 +1442,7 @@ public:
{
save_in_field(result_field, no_conversions);
}
bool check_partition_func_processor(byte *bool_arg)
{ *(bool *)bool_arg= FALSE; return 0; }
bool check_partition_func_processor(byte *int_arg) {return TRUE;}
};
/* Item represents one placeholder ('?') of prepared statement */
......@@ -1705,8 +1733,7 @@ public:
{}
void print(String *str) { str->append(func_name); }
Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(byte *bool_arg)
{ *(bool *)bool_arg= FALSE; return 0; }
bool check_partition_func_processor(byte *int_arg) {return TRUE;}
};
......@@ -1784,7 +1811,7 @@ public:
void print(String *str);
// to prevent drop fixed flag (no need parent cleanup call)
void cleanup() {}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -1799,8 +1826,7 @@ public:
{}
Item *safe_charset_converter(CHARSET_INFO *tocs);
void print(String *str) { str->append(func_name); }
bool check_partition_func_processor(byte *bool_arg)
{ *(bool *)bool_arg= FALSE; return 0; }
bool check_partition_func_processor(byte *int_arg) {return TRUE;}
};
......@@ -1813,8 +1839,7 @@ public:
&my_charset_bin)
{ max_length=19;}
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
bool check_partition_func_processor(byte *bool_arg)
{ *(bool *)bool_arg= FALSE; return 0; }
bool check_partition_func_processor(byte *int_arg) {return TRUE;}
};
class Item_empty_string :public Item_string
......@@ -1837,8 +1862,7 @@ public:
unsigned_flag=1;
}
enum_field_types field_type() const { return int_field_type; }
bool check_partition_func_processor(byte *bool_arg)
{ *(bool *)bool_arg= FALSE; return 0; }
bool check_partition_func_processor(byte *int_arg) {return TRUE;}
};
......@@ -1862,7 +1886,7 @@ public:
void cleanup() {}
bool eq(const Item *item, bool binary_cmp) const;
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -2089,8 +2113,7 @@ public:
}
Item *new_item();
virtual Item *real_item() { return ref; }
bool check_partition_func_processor(byte *bool_arg)
{ *(bool *)bool_arg= FALSE; return 0; }
bool check_partition_func_processor(byte *int_arg) {return TRUE;}
};
#ifdef MYSQL_SERVER
......
......@@ -240,7 +240,7 @@ public:
}
Item *neg_transformer(THD *thd);
virtual Item *negated_item();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
bool subst_argument_checker(byte **arg) { return TRUE; }
};
......@@ -252,7 +252,7 @@ public:
enum Functype functype() const { return NOT_FUNC; }
const char *func_name() const { return "not"; }
Item *neg_transformer(THD *thd);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_maxmin_subselect;
......@@ -469,7 +469,7 @@ public:
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
uint decimal_precision() const { return 1; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -481,7 +481,7 @@ public:
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
const char *func_name() const { return "strcmp"; }
void print(String *str) { Item_func::print(str); }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -544,7 +544,7 @@ public:
const char *func_name() const { return "ifnull"; }
Field *tmp_table_field(TABLE *table);
uint decimal_precision() const;
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -585,10 +585,9 @@ public:
void print(String *str) { Item_func::print(str); }
table_map not_null_tables() const { return 0; }
bool is_null();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
/* Functions to handle the optimized IN */
......@@ -977,7 +976,7 @@ public:
void print(String *str);
Item *find_item(String *str);
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *bool_arg) { return FALSE;}
void cleanup()
{
uint i;
......@@ -1047,7 +1046,7 @@ public:
bool nulls_in_row();
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
/* Functions used by where clause */
......@@ -1089,7 +1088,7 @@ public:
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
Item *neg_transformer(THD *thd);
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
/* Functions used by HAVING for rewriting IN subquery */
......@@ -1111,8 +1110,7 @@ public:
*/
table_map used_tables() const
{ return used_tables_cache | RAND_TABLE_BIT; }
bool check_partition_func_processor(byte *bool_arg)
{ *(bool *)bool_arg= FALSE; return 0; }
bool check_partition_func_processor(byte *int_arg) {return TRUE;}
};
......@@ -1135,7 +1133,7 @@ public:
void print(String *str);
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
void top_level_item() { abort_on_null=1; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -1174,7 +1172,7 @@ public:
const char *func_name() const { return "like"; }
bool fix_fields(THD *thd, Item **ref);
void cleanup();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
#ifdef USE_REGEX
......@@ -1197,7 +1195,7 @@ public:
const char *func_name() const { return "regexp"; }
void print(String *str) { print_op(str); }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
#else
......@@ -1254,7 +1252,7 @@ public:
Item *transform(Item_transformer transformer, byte *arg);
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
void neg_arguments(THD *thd);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
bool subst_argument_checker(byte **arg) { return TRUE; }
Item *compile(Item_analyzer analyzer, byte **arg_p,
Item_transformer transformer, byte *arg_t);
......
......@@ -254,7 +254,7 @@ public:
void fix_num_length_and_dec();
void find_num_type();
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -267,7 +267,7 @@ class Item_num_op :public Item_func_numhybrid
void print(String *str) { print_op(str); }
void find_num_type();
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -318,7 +318,7 @@ public:
{ max_length=args[0]->max_length; unsigned_flag=0; }
void print(String *str);
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -352,7 +352,7 @@ public:
void fix_length_and_dec() {};
const char *func_name() const { return "decimal_typecast"; }
void print(String *);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -421,7 +421,7 @@ public:
const char *func_name() const { return "DIV"; }
void fix_length_and_dec();
void print(String *str) { print_op(str); }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -494,7 +494,7 @@ public:
Item_func_exp(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "exp"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -504,7 +504,7 @@ public:
Item_func_ln(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "ln"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -515,7 +515,7 @@ public:
Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {}
double val_real();
const char *func_name() const { return "log"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -525,7 +525,7 @@ public:
Item_func_log2(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "log2"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -535,7 +535,7 @@ public:
Item_func_log10(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "log10"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -545,7 +545,7 @@ public:
Item_func_sqrt(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "sqrt"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -555,7 +555,7 @@ public:
Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {}
double val_real();
const char *func_name() const { return "pow"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -565,7 +565,7 @@ public:
Item_func_acos(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "acos"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_asin :public Item_dec_func
......@@ -574,7 +574,7 @@ public:
Item_func_asin(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "asin"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_atan :public Item_dec_func
......@@ -584,7 +584,7 @@ public:
Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {}
double val_real();
const char *func_name() const { return "atan"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_cos :public Item_dec_func
......@@ -593,7 +593,7 @@ public:
Item_func_cos(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "cos"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_sin :public Item_dec_func
......@@ -602,7 +602,7 @@ public:
Item_func_sin(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "sin"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_tan :public Item_dec_func
......@@ -611,7 +611,7 @@ public:
Item_func_tan(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "tan"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_integer :public Item_int_func
......@@ -688,7 +688,7 @@ public:
Item_func_sign(Item *a) :Item_int_func(a) {}
const char *func_name() const { return "sign"; }
longlong val_int();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -703,7 +703,7 @@ public:
const char *func_name() const { return name; }
void fix_length_and_dec()
{ decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -721,7 +721,7 @@ public:
my_decimal *val_decimal(my_decimal *);
void fix_length_and_dec();
enum Item_result result_type () const { return cmp_type; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_min :public Item_func_min_max
......@@ -747,7 +747,7 @@ public:
longlong val_int();
const char *func_name() const { return "length"; }
void fix_length_and_dec() { max_length=10; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_bit_length :public Item_func_length
......@@ -767,7 +767,7 @@ public:
longlong val_int();
const char *func_name() const { return "char_length"; }
void fix_length_and_dec() { max_length=10; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_coercibility :public Item_int_func
......@@ -778,7 +778,6 @@ public:
const char *func_name() const { return "coercibility"; }
void fix_length_and_dec() { max_length=10; maybe_null= 0; }
table_map not_null_tables() const { return 0; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
class Item_func_locate :public Item_int_func
......@@ -792,7 +791,7 @@ public:
longlong val_int();
void fix_length_and_dec();
void print(String *str);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -817,7 +816,7 @@ public:
longlong val_int();
const char *func_name() const { return "ascii"; }
void fix_length_and_dec() { max_length=3; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_ord :public Item_int_func
......@@ -827,7 +826,7 @@ public:
Item_func_ord(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "ord"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_find_in_set :public Item_int_func
......@@ -841,7 +840,7 @@ public:
longlong val_int();
const char *func_name() const { return "find_in_set"; }
void fix_length_and_dec();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
/* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
......@@ -853,7 +852,7 @@ public:
Item_func_bit(Item *a) :Item_int_func(a) {}
void fix_length_and_dec() { unsigned_flag= 1; }
void print(String *str) { print_op(str); }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_bit_or :public Item_func_bit
......@@ -879,7 +878,7 @@ public:
longlong val_int();
const char *func_name() const { return "bit_count"; }
void fix_length_and_dec() { max_length=2; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_shift_left :public Item_func_bit
......@@ -1319,7 +1318,7 @@ public:
longlong val_int();
const char *func_name() const { return "inet_aton"; }
void fix_length_and_dec() { decimals = 0; max_length = 21; maybe_null=1;}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......
......@@ -50,7 +50,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "md5"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -64,7 +64,6 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "sha"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
class Item_func_aes_encrypt :public Item_str_func
......@@ -95,7 +94,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "concat"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_concat_ws :public Item_str_func
......@@ -117,7 +116,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "reverse"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -155,7 +154,7 @@ protected:
public:
Item_str_conv(Item *item) :Item_str_func(item) {}
String *val_str(String *);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -219,7 +218,6 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "substr"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
......@@ -231,7 +229,6 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "substring_index"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
......@@ -248,7 +245,6 @@ public:
const char *func_name() const { return "trim"; }
void print(String *str);
virtual const char *mode_name() const { return "both"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
......@@ -461,7 +457,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "soundex"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -562,7 +558,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "rpad"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -575,7 +571,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "lpad"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -590,7 +586,7 @@ public:
collation.set(default_charset());
max_length= 64;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -607,7 +603,7 @@ public:
decimals=0;
max_length=args[0]->max_length*2*collation.collation->mbmaxlen;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_unhex :public Item_str_func
......@@ -623,7 +619,7 @@ public:
decimals=0;
max_length=(1+args[0]->max_length)/2;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -647,7 +643,7 @@ public:
}
void print(String *str);
const char *func_name() const { return "cast_as_binary"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -687,7 +683,7 @@ public:
String* val_str(String* str);
const char *func_name() const { return "inet_ntoa"; }
void fix_length_and_dec() { decimals = 0; max_length=3*8+7; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_quote :public Item_str_func
......@@ -702,7 +698,7 @@ public:
collation.set(args[0]->collation);
max_length= args[0]->max_length * 2 + 2;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_conv_charset :public Item_str_func
......@@ -746,7 +742,6 @@ public:
void fix_length_and_dec();
const char *func_name() const { return "convert"; }
void print(String *str);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
class Item_func_set_collation :public Item_str_func
......@@ -779,7 +774,6 @@ public:
maybe_null= 0;
};
table_map not_null_tables() const { return 0; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
class Item_func_collation :public Item_str_func
......@@ -795,7 +789,6 @@ public:
maybe_null= 0;
};
table_map not_null_tables() const { return 0; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
class Item_func_crc32 :public Item_int_func
......@@ -806,7 +799,7 @@ public:
const char *func_name() const { return "crc32"; }
void fix_length_and_dec() { max_length=10; }
longlong val_int();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_uncompressed_length : public Item_int_func
......@@ -817,7 +810,6 @@ public:
const char *func_name() const{return "uncompressed_length";}
void fix_length_and_dec() { max_length=10; }
longlong val_int();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
#ifdef HAVE_COMPRESS
......@@ -834,7 +826,6 @@ public:
void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
const char *func_name() const{return "compress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
class Item_func_uncompress: public Item_str_func
......@@ -845,7 +836,6 @@ public:
void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
const char *func_name() const{return "uncompress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
bool check_partition_func_processor(byte *bool_arg) { return 0;}
};
#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
......
......@@ -39,7 +39,7 @@ public:
{
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -54,7 +54,7 @@ public:
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -71,7 +71,7 @@ public:
maybe_null=1;
}
enum_monotonicity_info get_monotonicity_info() const;
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -87,7 +87,7 @@ public:
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -112,7 +112,7 @@ public:
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -145,7 +145,7 @@ public:
max_length=3*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -161,7 +161,7 @@ public:
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -177,7 +177,7 @@ public:
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -193,7 +193,7 @@ public:
max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -209,7 +209,7 @@ public:
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -225,7 +225,7 @@ public:
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_yearweek :public Item_int_func
......@@ -240,7 +240,7 @@ public:
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -257,7 +257,7 @@ public:
max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -287,7 +287,7 @@ public:
max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_dayname :public Item_func_weekday
......@@ -320,7 +320,7 @@ public:
decimals=0;
max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -335,7 +335,7 @@ public:
decimals=0;
max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -545,7 +545,7 @@ public:
Item_func_from_days(Item *a) :Item_date(a) {}
const char *func_name() const { return "from_days"; }
bool get_date(TIME *res, uint fuzzy_date);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -563,7 +563,7 @@ public:
void fix_length_and_dec();
uint format_length(const String *format);
bool eq(const Item *item, bool binary_cmp) const;
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -582,7 +582,7 @@ class Item_func_from_unixtime :public Item_date_func
const char *func_name() const { return "from_unixtime"; }
void fix_length_and_dec();
bool get_date(TIME *res, uint fuzzy_date);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -651,7 +651,7 @@ public:
return tmp_table_field_from_field_type(table, 0);
}
bool result_as_longlong() { return TRUE; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -674,7 +674,7 @@ public:
bool get_date(TIME *res, uint fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -692,7 +692,7 @@ class Item_extract :public Item_int_func
void fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -729,7 +729,7 @@ public:
max_length=args[0]->max_length;
maybe_null= 1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -749,7 +749,7 @@ public:
String *val_str(String *a);
void fix_length_and_dec();
void print(String *str);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -829,7 +829,7 @@ public:
}
bool result_as_longlong() { return TRUE; }
longlong val_int();
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -852,7 +852,7 @@ public:
}
void print(String *str);
const char *func_name() const { return "add_time"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_timediff :public Item_str_func
......@@ -892,7 +892,7 @@ public:
{
return tmp_table_field_from_field_type(table, 0);
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
class Item_func_microsecond :public Item_int_func
......@@ -906,7 +906,7 @@ public:
decimals=0;
maybe_null=1;
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -924,7 +924,7 @@ public:
maybe_null=1;
}
void print(String *str);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......@@ -971,7 +971,7 @@ public:
{
return tmp_table_field_from_field_type(table, 1);
}
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......
......@@ -42,7 +42,7 @@ public:
Item_func_xml_extractvalue(Item *a,Item *b) :Item_xml_str_func(a,b) {}
const char *func_name() const { return "extractvalue"; }
String *val_str(String *);
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
......
......@@ -693,6 +693,7 @@ end:
file A reference to a handler of the table
info Create info
engine_type Return value for used engine in partitions
check_partition_function Should we check the partition function
RETURN VALUE
TRUE Error, something went wrong
......@@ -707,26 +708,33 @@ end:
*/
bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
handler *file, HA_CREATE_INFO *info)
handler *file, HA_CREATE_INFO *info,
bool check_partition_function)
{
handlerton **engine_array= NULL;
uint part_count= 0;
uint i, tot_partitions;
bool result= TRUE;
char *same_name;
bool part_expression_ok= TRUE;
DBUG_ENTER("partition_info::check_partition_info");
if (part_type != HASH_PARTITION || !list_of_part_fields)
part_expr->walk(&Item::check_partition_func_processor, 0,
(byte*)(&part_expression_ok));
if (is_sub_partitioned() && !list_of_subpart_fields)
subpart_expr->walk(&Item::check_partition_func_processor, 0,
(byte*)(&part_expression_ok));
if (!part_expression_ok)
if (check_partition_function)
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
int err= 0;
if (part_type != HASH_PARTITION || !list_of_part_fields)
{
err= part_expr->walk(&Item::check_partition_func_processor, 0,
NULL);
if (!err && is_sub_partitioned() && !list_of_subpart_fields)
err= subpart_expr->walk(&Item::check_partition_func_processor, 0,
NULL);
}
if (err)
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
}
}
if (unlikely(!is_sub_partitioned() &&
!(use_default_subpartitions && use_default_no_subpartitions)))
......@@ -828,11 +836,12 @@ end:
/*
Print error for no partition found
SYNOPSIS
print_no_partition_found()
table Table object
RETURN VALUES
NONE
*/
void partition_info::print_no_partition_found(TABLE *table)
......@@ -844,10 +853,176 @@ void partition_info::print_no_partition_found(TABLE *table)
if (part_expr->null_value)
buf_ptr= (char*)"NULL";
else
longlong2str(part_expr->val_int(), buf,
longlong2str(err_value, buf,
part_expr->unsigned_flag ? 10 : -10);
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr);
dbug_tmp_restore_column_map(table->read_set, old_map);
}
/*
Set up buffers and arrays for fields requiring preparation
SYNOPSIS
set_up_charset_field_preps()
RETURN VALUES
TRUE Memory Allocation error
FALSE Success
DESCRIPTION
Set up arrays and buffers for fields that require special care for
calculation of partition id. This is used for string fields with
variable length or string fields with fixed length that isn't using
the binary collation.
*/
bool partition_info::set_up_charset_field_preps()
{
Field *field, **ptr;
char *field_buf;
char **char_ptrs;
unsigned i;
bool found;
size_t size;
uint tot_fields= 0;
uint tot_part_fields= 0;
uint tot_subpart_fields= 0;
DBUG_ENTER("set_up_charset_field_preps");
if (!(part_type == HASH_PARTITION &&
list_of_part_fields) &&
check_part_func_fields(part_field_array, FALSE))
{
ptr= part_field_array;
/* Set up arrays and buffers for those fields */
i= 0;
while ((field= *(ptr++)))
{
if (field_is_partition_charset(field))
{
tot_part_fields++;
tot_fields++;
}
}
size= tot_part_fields * sizeof(char*);
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
part_field_buffers= char_ptrs;
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
restore_part_field_ptrs= char_ptrs;
size= (tot_part_fields + 1) * sizeof(Field*);
if (!(char_ptrs= (char**)sql_alloc(size)))
goto error;
part_charset_field_array= (Field**)char_ptrs;
ptr= part_field_array;
i= 0;
while ((field= *(ptr++)))
{
if (field_is_partition_charset(field))
{
CHARSET_INFO *cs= ((Field_str*)field)->charset();
size= field->pack_length();
if (!(field_buf= sql_calloc(size)))
goto error;
part_charset_field_array[i]= field;
part_field_buffers[i++]= field_buf;
}
}
part_charset_field_array[i]= NULL;
}
if (is_sub_partitioned() && list_of_subpart_fields &&
check_part_func_fields(subpart_field_array, FALSE))
{
/* Set up arrays and buffers for those fields */
ptr= subpart_field_array;
while ((field= *(ptr++)))
{
if (field_is_partition_charset(field))
tot_subpart_fields++;
}
size= tot_subpart_fields * sizeof(char*);
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
subpart_field_buffers= char_ptrs;
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
restore_subpart_field_ptrs= char_ptrs;
size= (tot_subpart_fields + 1) * sizeof(Field*);
if (!(char_ptrs= (char**)sql_alloc(size)))
goto error;
subpart_charset_field_array= (Field**)char_ptrs;
i= 0;
while ((field= *(ptr++)))
{
unsigned j= 0;
Field *part_field;
CHARSET_INFO *cs;
if (!field_is_partition_charset(field))
continue;
cs= ((Field_str*)field)->charset();
size= field->pack_length();
found= FALSE;
for (j= 0; j < tot_part_fields; j++)
{
if (field == part_charset_field_array[i])
found= TRUE;
}
if (!found)
{
tot_fields++;
if (!(field_buf= sql_calloc(size)))
goto error;
}
subpart_field_buffers[i++]= field_buf;
}
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
restore_subpart_field_ptrs= char_ptrs;
}
if (tot_fields)
{
Field *part_field, *subpart_field;
uint j,k,l;
size= tot_fields*sizeof(char**);
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
full_part_field_buffers= char_ptrs;
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
restore_full_part_field_ptrs= char_ptrs;
size= (tot_fields + 1) * sizeof(char**);
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
full_part_charset_field_array= (Field**)char_ptrs;
for (i= 0; i < tot_part_fields; i++)
{
full_part_charset_field_array[i]= part_charset_field_array[i];
full_part_field_buffers[i]= part_field_buffers[i];
}
k= tot_part_fields;
l= 0;
for (i= 0; i < tot_subpart_fields; i++)
{
field= subpart_charset_field_array[i];
found= FALSE;
for (j= 0; j < tot_part_fields; j++)
{
if (field == part_charset_field_array[i])
found= TRUE;
}
if (!found)
{
full_part_charset_field_array[l]= subpart_charset_field_array[k];
full_part_field_buffers[l]= subpart_field_buffers[k];
k++; l++;
}
}
full_part_charset_field_array[tot_fields]= NULL;
}
DBUG_RETURN(FALSE);
error:
mem_alloc_error(size);
DBUG_RETURN(TRUE);
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */
......@@ -60,17 +60,40 @@ public:
same in all subpartitions
*/
get_subpart_id_func get_subpartition_id;
/*
When we have various string fields we might need some preparation
before and clean-up after calling the get_part_id_func's. We need
one such method for get_partition_id and one for
get_part_partition_id and one for get_subpartition_id.
*/
get_part_id_func get_partition_id_charset;
get_part_id_func get_part_partition_id_charset;
get_subpart_id_func get_subpartition_id_charset;
/* NULL-terminated array of fields used in partitioned expression */
Field **part_field_array;
/* NULL-terminated array of fields used in subpartitioned expression */
Field **subpart_field_array;
Field **part_charset_field_array;
Field **subpart_charset_field_array;
/*
Array of all fields used in partition and subpartition expression,
without duplicates, NULL-terminated.
*/
Field **full_part_field_array;
Field **full_part_charset_field_array;
/*
When we have a field that requires transformation before calling the
partition functions we must allocate field buffers for the field of
the fields in the partition function.
*/
char **part_field_buffers;
char **subpart_field_buffers;
char **full_part_field_buffers;
char **restore_part_field_ptrs;
char **restore_subpart_field_ptrs;
char **restore_full_part_field_ptrs;
Item *part_expr;
Item *subpart_expr;
......@@ -127,7 +150,8 @@ public:
/********************************************
* INTERVAL ANALYSIS ENDS
********************************************/
longlong err_value;
char* part_info_string;
char *part_func_string;
......@@ -194,10 +218,17 @@ public:
: get_partition_id(NULL), get_part_partition_id(NULL),
get_subpartition_id(NULL),
part_field_array(NULL), subpart_field_array(NULL),
part_charset_field_array(NULL),
subpart_charset_field_array(NULL),
full_part_field_array(NULL),
full_part_charset_field_array(NULL),
part_field_buffers(NULL), subpart_field_buffers(NULL),
full_part_field_buffers(NULL),
restore_part_field_ptrs(NULL), restore_subpart_field_ptrs(NULL),
restore_full_part_field_ptrs(NULL),
part_expr(NULL), subpart_expr(NULL), item_free_list(NULL),
first_log_entry(NULL), exec_log_entry(NULL), frm_log_entry(NULL),
list_array(NULL),
list_array(NULL), err_value(0),
part_info_string(NULL),
part_func_string(NULL), subpart_func_string(NULL),
part_state(NULL),
......@@ -250,8 +281,10 @@ public:
bool check_range_constants();
bool check_list_constants();
bool check_partition_info(THD *thd, handlerton **eng_type,
handler *file, HA_CREATE_INFO *info);
handler *file, HA_CREATE_INFO *info,
bool check_partition_function);
void print_no_partition_found(TABLE *table);
bool set_up_charset_field_preps();
private:
static int list_part_cmp(const void* a, const void* b);
static int list_part_cmp_unsigned(const void* a, const void* b);
......
This diff is collapsed.
......@@ -93,6 +93,9 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
bool is_sub_part, bool is_field_to_be_setup);
bool check_part_func_fields(Field **ptr, bool ok_with_charsets);
bool field_is_partition_charset(Field *field);
/*
A "Get next" function for partition iterator.
......
......@@ -1132,6 +1132,26 @@ bool execute_ddl_log_entry(THD *thd, uint first_entry)
}
/*
Close the ddl log
SYNOPSIS
close_ddl_log()
RETURN VALUES
NONE
*/
static void close_ddl_log()
{
DBUG_ENTER("close_ddl_log");
if (global_ddl_log.file_id >= 0)
{
VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
global_ddl_log.file_id= (File) -1;
}
DBUG_VOID_RETURN;
}
/*
Execute the ddl log at recovery of MySQL Server
SYNOPSIS
......@@ -1183,6 +1203,7 @@ void execute_ddl_log_recovery()
}
}
}
close_ddl_log();
create_ddl_log_file_name(file_name);
VOID(my_delete(file_name, MYF(0)));
global_ddl_log.recovery_phase= FALSE;
......@@ -1220,11 +1241,7 @@ void release_ddl_log()
my_free((char*)free_list, MYF(0));
free_list= tmp;
}
if (global_ddl_log.file_id >= 0)
{
VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
global_ddl_log.file_id= (File) -1;
}
close_ddl_log();
global_ddl_log.inited= 0;
pthread_mutex_unlock(&LOCK_gdl);
VOID(pthread_mutex_destroy(&LOCK_gdl));
......@@ -3304,7 +3321,8 @@ bool mysql_create_table_internal(THD *thd,
}
DBUG_PRINT("info", ("db_type = %d",
ha_legacy_type(part_info->default_engine_type)));
if (part_info->check_partition_info(thd, &engine_type, file, create_info))
if (part_info->check_partition_info(thd, &engine_type, file,
create_info, TRUE))
goto err;
part_info->default_engine_type= engine_type;
......
......@@ -3600,6 +3600,7 @@ part_bit_expr:
{
Item *part_expr= $1;
bool not_corr_func;
int part_expression_ok= 1;
LEX *lex= Lex;
THD *thd= YYTHD;
longlong item_value;
......@@ -3617,13 +3618,18 @@ part_bit_expr:
mem_alloc_error(sizeof(part_elem_value));
YYABORT;
}
if (part_expr->walk(&Item::check_partition_func_processor, 0,
NULL))
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
YYABORT;
}
if (part_expr->fix_fields(YYTHD, (Item**)0) ||
((context->table_list= save_list), FALSE) ||
(!part_expr->const_item()) ||
(!lex->safe_to_cache_query))
{
yyerror(ER(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR));
my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
YYABORT;
}
thd->where= save_where;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment