Commit de9001d3 authored by mikael/pappa@dator5.(none)'s avatar mikael/pappa@dator5.(none)

Merge dator5.(none):/home/pappa/clean-mysql-5.1

into  dator5.(none):/home/pappa/bug18198
parents 3a65bd16 0d4d06fd
drop table if exists t1;
create table t1 (a int)
partition by range (a)
(partition p0 values less than ((select count(*) from t1)));
ERROR HY000: This partition function is not allowed
create table t1 (a int)
partition by range (a)
(partition p0 values less than (a);
ERROR 42S22: Unknown column 'a' in 'partition function'
create table t1 (a int)
partition by range (a)
(partition p0 values less than (1));
alter table t1 add partition (partition p1 values less than (a));
ERROR 42S22: Unknown column 'a' in 'partition function'
alter table t1 add partition
(partition p1 values less than ((select count(*) from t1)));
ERROR HY000: This partition function is not allowed
drop table t1;
create table t1 (a int)
engine = x
partition by key (a);
Warnings:
......
......@@ -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),
......
......@@ -719,3 +719,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
#
......
......@@ -8,6 +8,28 @@
drop table if exists t1;
--enable_warnings
#
# Bug 18198: Partitions: Too flexible functions
#
-- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
create table t1 (a int)
partition by range (a)
(partition p0 values less than ((select count(*) from t1)));
-- error 1054
create table t1 (a int)
partition by range (a)
(partition p0 values less than (a);
create table t1 (a int)
partition by range (a)
(partition p0 values less than (1));
-- error 1054
alter table t1 add partition (partition p1 values less than (a));
-- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
alter table t1 add partition
(partition p1 values less than ((select count(*) from t1)));
drop table t1;
#
# Bug 20397: Partitions: Crash when using non-existing engine
#
......
......@@ -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),
......
......@@ -699,3 +699,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;
......@@ -830,7 +830,7 @@ class Item {
Check if a partition function is allowed
SYNOPSIS
check_partition_func_processor()
bool_arg Return argument
int_arg Return argument
RETURN VALUE
0
DESCRIPTION
......@@ -847,8 +847,7 @@ class Item {
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; }
virtual bool check_partition_func_processor(byte *bool_arg) { return FALSE; }
virtual bool subst_argument_checker(byte **arg)
{
if (*arg)
......@@ -1146,7 +1145,6 @@ class Item_name_const : public Item
Item::maybe_null= TRUE;
}
bool check_partition_func_processor(byte *bool_arg) { return 0; }
bool fix_fields(THD *, Item **);
enum Type type() const;
......@@ -1192,7 +1190,7 @@ class Item_num: public Item
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))
......@@ -1350,7 +1348,7 @@ class Item_field :public Item_ident
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()
{
......@@ -1399,7 +1397,7 @@ class Item_null :public Item
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
......@@ -1412,8 +1410,8 @@ class Item_null_result :public Item_null
{
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)
{ *(int *)int_arg= 0; return FALSE; }
};
/* Item represents one placeholder ('?') of prepared statement */
......@@ -1704,8 +1702,8 @@ class Item_static_float_func :public Item_float
{}
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)
{ *(int *)int_arg= 0; return FALSE; }
};
......@@ -1783,7 +1781,7 @@ class Item_string :public Item
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;}
};
......@@ -1798,8 +1796,8 @@ class Item_static_string_func :public Item_string
{}
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)
{ *(int *)int_arg= 0; return FALSE; }
};
......@@ -1812,8 +1810,8 @@ class Item_datetime :public Item_string
&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)
{ *(int *)int_arg= 0; return FALSE; }
};
class Item_empty_string :public Item_string
......@@ -1836,8 +1834,8 @@ class Item_return_int :public Item_int
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)
{ *(int *)int_arg= 0; return FALSE; }
};
......@@ -1861,7 +1859,7 @@ class Item_hex_string: public Item
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; }
};
......@@ -2088,8 +2086,8 @@ class Item_int_with_ref :public Item_int
}
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)
{ *(int *)int_arg= 0; return FALSE; }
};
#ifdef MYSQL_SERVER
......
......@@ -240,7 +240,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2
}
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 @@ class Item_func_not :public Item_bool_func
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 @@ class Item_func_between :public Item_func_opt_neg
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 @@ class Item_func_strcmp :public Item_bool_func2
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 @@ class Item_func_ifnull :public Item_func_coalesce
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,7 +585,7 @@ class Item_func_nullif :public Item_bool_func2
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; }
};
......@@ -628,7 +628,7 @@ class Item_func_case :public Item_func
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 *int_arg) { return FALSE; }
};
......@@ -979,7 +979,7 @@ class Item_func_in :public Item_func_opt_neg
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 */
......@@ -1021,7 +1021,7 @@ class Item_func_isnull :public Item_bool_func
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 */
......@@ -1043,8 +1043,8 @@ class Item_is_not_null_test :public Item_func_isnull
*/
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)
{ *(int *)int_arg= 0; return FALSE; }
};
......@@ -1067,7 +1067,7 @@ class Item_func_isnotnull :public Item_bool_func
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; }
};
......@@ -1106,7 +1106,7 @@ class Item_func_like :public Item_bool_func2
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
......@@ -1129,7 +1129,7 @@ class Item_func_regex :public Item_bool_func
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
......@@ -1186,7 +1186,7 @@ class Item_cond :public Item_bool_func
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 @@ class Item_func_num1: public Item_func_numhybrid
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 @@ class Item_func_signed :public Item_int_func
{ 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 @@ class Item_decimal_typecast :public Item_func
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 @@ class Item_func_int_div :public Item_int_func
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 @@ class Item_func_exp :public Item_dec_func
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 @@ class Item_func_ln :public Item_dec_func
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 @@ class Item_func_log :public Item_dec_func
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 @@ class Item_func_log2 :public Item_dec_func
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 @@ class Item_func_log10 :public Item_dec_func
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 @@ class Item_func_sqrt :public Item_dec_func
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 @@ class Item_func_pow :public Item_dec_func
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 @@ class Item_func_acos :public Item_dec_func
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 @@ class Item_func_asin :public Item_dec_func
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 @@ class Item_func_atan :public Item_dec_func
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 @@ class Item_func_cos :public Item_dec_func
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 @@ class Item_func_sin :public Item_dec_func
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 @@ class Item_func_tan :public Item_dec_func
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 @@ class Item_func_sign :public Item_int_func
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 @@ class Item_func_units :public Item_real_func
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 @@ class Item_func_min_max :public Item_func
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 @@ class Item_func_length :public Item_int_func
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 @@ class Item_func_char_length :public Item_int_func
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 @@ class Item_func_coercibility :public Item_int_func
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 @@ class Item_func_locate :public Item_int_func
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 @@ class Item_func_ascii :public Item_int_func
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 @@ class Item_func_ord :public Item_int_func
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 @@ class Item_func_find_in_set :public Item_int_func
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 @@ class Item_func_bit: public Item_int_func
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 @@ class Item_func_bit_count :public Item_int_func
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 @@ class Item_func_inet_aton : public Item_int_func
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 @@ class Item_func_md5 :public Item_str_func
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 @@ class Item_func_sha :public Item_str_func
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 @@ class Item_func_concat :public Item_str_func
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 @@ class Item_func_reverse :public Item_str_func
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 @@ class Item_str_conv :public Item_str_func
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 @@ class Item_func_substr :public Item_str_func
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 @@ class Item_func_substr_index :public Item_str_func
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 @@ class Item_func_trim :public Item_str_func
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 @@ class Item_func_soundex :public Item_str_func
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 @@ class Item_func_rpad :public Item_str_func
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 @@ class Item_func_lpad :public Item_str_func
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 @@ class Item_func_conv :public Item_str_func
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 @@ class Item_func_hex :public Item_str_func
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 @@ class Item_func_unhex :public Item_str_func
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 @@ class Item_func_binary :public Item_str_func
}
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 @@ class Item_func_inet_ntoa : public Item_str_func
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 @@ class Item_func_quote :public Item_str_func
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 @@ class Item_func_conv_charset :public Item_str_func
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 @@ class Item_func_charset :public Item_str_func
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 @@ class Item_func_collation :public Item_str_func
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 @@ class Item_func_crc32 :public Item_int_func
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 @@ class Item_func_uncompressed_length : public Item_int_func
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 @@ class Item_func_compress: public Item_str_func
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 @@ class Item_func_uncompress: public Item_str_func
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 @@ class Item_func_period_add :public Item_int_func
{
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 @@ class Item_func_period_diff :public Item_int_func
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 @@ class Item_func_to_days :public Item_int_func
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 @@ class Item_func_dayofmonth :public Item_int_func
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 @@ class Item_func_month :public Item_func
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 @@ class Item_func_dayofyear :public Item_int_func
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 @@ class Item_func_hour :public Item_int_func
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 @@ class Item_func_minute :public Item_int_func
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 @@ class Item_func_quarter :public Item_int_func
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 @@ class Item_func_second :public Item_int_func
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 @@ class Item_func_week :public Item_int_func
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 @@ class Item_func_yearweek :public Item_int_func
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 @@ class Item_func_year :public Item_int_func
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 @@ class Item_func_weekday :public Item_func
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 @@ class Item_func_unix_timestamp :public Item_int_func
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 @@ class Item_func_time_to_sec :public Item_int_func
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 @@ class Item_func_from_days :public Item_date
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 @@ class Item_func_date_format :public Item_str_func
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 @@ class Item_func_sec_to_time :public Item_str_func
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 @@ class Item_date_add_interval :public Item_date_func
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 @@ class Item_typecast_maybe_null :public Item_typecast
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 @@ class Item_char_typecast :public Item_typecast
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 @@ class Item_func_makedate :public Item_str_func
}
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 @@ class Item_func_add_time :public Item_str_func
}
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 @@ class Item_func_maketime :public Item_str_func
{
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 @@ class Item_func_microsecond :public Item_int_func
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 @@ class Item_func_timestamp_diff :public Item_int_func
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 @@ class Item_func_str_to_date :public Item_str_func
{
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 @@ class Item_func_xml_extractvalue: public Item_xml_str_func
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; }
};
......
......@@ -695,6 +695,7 @@ bool partition_info::check_list_constants()
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
......@@ -709,26 +710,41 @@ bool partition_info::check_list_constants()
*/
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 part_expression_ok= 1;
int pf_collation_allowed= 1;
int spf_collation_allowed= 1;
if (part_type != HASH_PARTITION || !list_of_part_fields)
{
part_expr->walk(&Item::check_partition_func_processor, 0,
(byte*)(&part_expression_ok));
pf_collation_allowed= part_expression_ok;
part_expression_ok= 1;
if (is_sub_partitioned() && !list_of_subpart_fields)
{
subpart_expr->walk(&Item::check_partition_func_processor, 0,
(byte*)(&part_expression_ok));
}
spf_collation_allowed= part_expression_ok;
}
if (!pf_collation_allowed ||
!spf_collation_allowed)
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
}
}
if (unlikely(!is_sub_partitioned() &&
!(use_default_subpartitions && use_default_no_subpartitions)))
......
......@@ -60,7 +60,17 @@ class partition_info : public Sql_alloc
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 */
......@@ -72,6 +82,16 @@ class partition_info : public Sql_alloc
*/
Field **full_part_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 **restore_part_field_ptrs;
char **restore_subpart_field_ptrs;
Item *part_expr;
Item *subpart_expr;
......@@ -188,6 +208,8 @@ class partition_info : public Sql_alloc
bool is_auto_partitioned;
bool from_openfrm;
bool has_null_value;
bool includes_charset_field_part;
bool includes_charset_field_subpart;
partition_info()
......@@ -195,6 +217,8 @@ class partition_info : public Sql_alloc
get_subpartition_id(NULL),
part_field_array(NULL), subpart_field_array(NULL),
full_part_field_array(NULL),
part_field_buffers(NULL), subpart_field_buffers(NULL),
restore_part_field_ptrs(NULL), restore_subpart_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),
......@@ -217,7 +241,8 @@ class partition_info : public Sql_alloc
list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
linear_hash_ind(FALSE), fixed(FALSE),
is_auto_partitioned(FALSE), from_openfrm(FALSE),
has_null_value(FALSE)
has_null_value(FALSE), includes_charset_field_part(FALSE),
includes_charset_field_subpart(FALSE)
{
all_fields_in_PF.clear_all();
all_fields_in_PPF.clear_all();
......@@ -250,7 +275,8 @@ class partition_info : public Sql_alloc
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);
private:
static int list_part_cmp(const void* a, const void* b);
......
......@@ -62,48 +62,64 @@ static const char *end_paren_str= ")";
static const char *begin_paren_str= "(";
static const char *comma_str= ",";
static int get_part_id_charset_func_all(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
static int get_part_id_charset_func_part(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
static int get_part_id_charset_func_subpart(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
static int get_part_part_id_charset_func(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
static uint32 get_subpart_id_charset_func(partition_info *part_info);
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_hash_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_key_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_key_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_linear_hash_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_linear_key_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_linear_key_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_linear_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_linear_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_linear_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_linear_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_linear_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_linear_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
uint32 get_partition_id_hash_sub(partition_info *part_info);
uint32 get_partition_id_key_sub(partition_info *part_info);
uint32 get_partition_id_linear_hash_sub(partition_info *part_info);
......@@ -525,6 +541,7 @@ static bool set_up_field_array(TABLE *table,
}
/*
Create a field array including all fields of both the partitioning and the
subpartitioning functions.
......@@ -549,6 +566,7 @@ static bool create_full_part_field_array(TABLE *table,
partition_info *part_info)
{
bool result= FALSE;
Field **ptr;
DBUG_ENTER("create_full_part_field_array");
if (!part_info->is_sub_partitioned())
......@@ -558,7 +576,7 @@ static bool create_full_part_field_array(TABLE *table,
}
else
{
Field **ptr, *field, **field_array;
Field *field, **field_array;
uint no_part_fields=0, size_field_array;
ptr= table->field;
while ((field= *(ptr++)))
......@@ -1328,6 +1346,34 @@ static void set_up_partition_func_pointers(partition_info *part_info)
}
}
}
if (part_info->includes_charset_field_part ||
part_info->includes_charset_field_subpart)
{
DBUG_ASSERT(part_info->get_partition_id);
part_info->get_partition_id_charset= part_info->get_partition_id;
if (part_info->includes_charset_field_part &&
part_info->includes_charset_field_subpart)
part_info->get_partition_id= get_part_id_charset_func_all;
else if (part_info->includes_charset_field_part)
part_info->get_partition_id= get_part_id_charset_func_part;
else
part_info->get_partition_id= get_part_id_charset_func_subpart;
}
if (part_info->includes_charset_field_part &&
part_info->is_sub_partitioned())
{
DBUG_ASSERT(part_info->get_part_partition_id);
part_info->get_part_partition_id_charset=
part_info->get_part_partition_id;
part_info->get_part_partition_id= get_part_part_id_charset_func;
}
if (part_info->includes_charset_field_subpart)
{
DBUG_ASSERT(part_info->get_subpartition_id);
part_info->get_subpartition_id_charset=
part_info->get_subpartition_id;
part_info->get_subpartition_id= get_subpart_id_charset_func;
}
DBUG_VOID_RETURN;
}
......@@ -1388,6 +1434,156 @@ static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask,
return part_id;
}
/*
Check that partition function do not contain any forbidden
character sets and collations.
SYNOPSIS
check_part_func_fields()
ptr Array of Field pointers
ok_with_charsets Will we report allowed charset
fields as ok
RETURN VALUES
FALSE Success
TRUE Error
DESCRIPTION
We will check in this routine that the fields of the partition functions
do not contain unallowed parts. It can also be used to check if there
are fields that require special care by calling my_strnxfrm before
calling the functions to calculate partition id.
*/
static bool check_part_func_fields(Field **ptr, bool ok_with_charsets)
{
Field *field;
DBUG_ENTER("check_part_func_field");
while ((field= *(ptr++)))
{
/*
For CHAR/VARCHAR fields we need to take special precautions.
Binary collation with CHAR is automatically supported. Other
types need some kind of standardisation function handling
*/
if (field->type() == MYSQL_TYPE_STRING ||
field->type() == MYSQL_TYPE_VARCHAR)
{
CHARSET_INFO *cs= ((Field_str*)field)->charset();
if (field->type() == MYSQL_TYPE_STRING &&
cs->state & MY_CS_BINSORT)
continue;
if (!ok_with_charsets ||
cs->mbmaxlen > 1 ||
cs->strxfrm_multiply > 1)
{
DBUG_RETURN(TRUE);
}
}
}
DBUG_RETURN(FALSE);
}
/*
Set up buffers and arrays for fields requiring preparation
SYNOPSIS
set_up_charset_field_preps()
part_info Partition info object
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.
*/
static bool set_up_charset_field_preps(partition_info *part_info)
{
Field *field, **ptr;
char *field_buf;
char **char_ptrs;
unsigned i;
size_t size;
DBUG_ENTER("set_up_charset_field_preps");
if (check_part_func_fields(part_info->part_field_array, FALSE))
{
ptr= part_info->part_field_array;
part_info->includes_charset_field_part= TRUE;
/*
Set up arrays and buffers for those fields
*/
i= 0;
while ((field= *(ptr++)))
i++;
size= i * sizeof(char*);
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
part_info->part_field_buffers= char_ptrs;
if (!(char_ptrs= (char**)sql_calloc(size)))
goto error;
part_info->restore_part_field_ptrs= char_ptrs;
ptr= part_info->part_field_array;
i= 0;
while ((field= *(ptr++)))
{
CHARSET_INFO *cs= ((Field_str*)field)->charset();
size= field->pack_length();
if (!(field_buf= sql_calloc(size)))
goto error;
part_info->part_field_buffers[i++]= field_buf;
}
}
if (part_info->is_sub_partitioned() &&
check_part_func_fields(part_info->subpart_field_array, FALSE))
{
/*
Set up arrays and buffers for those fields
*/
part_info->includes_charset_field_subpart= TRUE;
ptr= part_info->subpart_field_array;
i= 0;
while ((field= *(ptr++)))
{
unsigned j= 0;
Field *part_field;
Field **part_ptr= part_info->part_field_array;
bool field_already_have_buffer= FALSE;
CHARSET_INFO *cs= ((Field_str*)field)->charset();
size= field->pack_length();
while ((part_field= *(part_ptr++)))
{
field_buf= part_info->part_field_buffers[j++];
if (field == part_field)
{
field_already_have_buffer= TRUE;
break;
}
}
if (!field_already_have_buffer)
{
if (!(field_buf= sql_calloc(size)))
goto error;
}
part_info->subpart_field_buffers[i++]= field_buf;
}
size= i * sizeof(char*);
if (!(char_ptrs= (char**)sql_calloc(i * sizeof(char*))))
goto error;
part_info->restore_subpart_field_ptrs= char_ptrs;
}
DBUG_RETURN(FALSE);
error:
mem_alloc_error(size);
DBUG_RETURN(TRUE);
}
/*
fix partition functions
......@@ -1531,6 +1727,16 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
}
}
if (((part_info->part_type != HASH_PARTITION ||
part_info->list_of_part_fields == FALSE) &&
check_part_func_fields(part_info->part_field_array, TRUE)) ||
(part_info->list_of_part_fields == FALSE &&
part_info->is_sub_partitioned() &&
check_part_func_fields(part_info->subpart_field_array, TRUE)))
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
}
if (unlikely(create_full_part_field_array(table, part_info)))
goto end;
if (unlikely(check_primary_key(table)))
......@@ -1541,6 +1747,11 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
if (unlikely(set_up_partition_bitmap(thd, part_info)))
goto end;
if (unlikely(set_up_charset_field_preps(part_info)))
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
}
check_range_capable_PF(table);
set_up_partition_key_maps(table, part_info);
set_up_partition_func_pointers(part_info);
......@@ -2256,6 +2467,86 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
no_parts));
}
/*
Copy to field buffers and set up field pointers
SYNOPSIS
copy_to_part_field_buffers()
ptr Array of fields to copy
RETURN VALUES
NONE
DESCRIPTION
This routine is used to take the data from field pointer, convert
it to a standard format and store this format in a field buffer
allocated for this purpose. Next the field pointers are moved to
point to the field buffers. There is a separate to restore the
field pointers after this call.
*/
static void copy_to_part_field_buffers(Field **ptr,
char **field_bufs,
char **restore_ptr)
{
Field *field;
while ((field= *(ptr++)))
{
*restore_ptr= field->ptr;
restore_ptr++;
if ((field->type() == MYSQL_TYPE_VARCHAR ||
(field->type() == MYSQL_TYPE_STRING &&
(!(((Field_str*)field)->charset()->state & MY_CS_BINSORT))) &&
((!field->maybe_null()) || (!field->is_null()))))
{
CHARSET_INFO *cs= ((Field_str*)field)->charset();
uint len= field->pack_length();
char *field_buf= *field_bufs;
/*
We only use the field buffer for VARCHAR and CHAR strings
which isn't of a binary collation. We also only use the
field buffer for fields which are not currently NULL.
The field buffer will store a normalised string. We use
the strnxfrm method to normalise the string.
*/
if (field->type() == MYSQL_TYPE_VARCHAR)
{
uint len_bytes= ((Field_varstring*)field)->length_bytes;
my_strnxfrm(cs, (uchar*)(field_buf + len_bytes), (len - len_bytes),
(uchar*)(field->ptr + len_bytes), field->field_length);
if (len_bytes == 1)
*field_buf= (uchar)field->field_length;
else
int2store(field_buf, field->field_length);
}
else
{
my_strnxfrm(cs, (uchar*)field_buf, len,
(uchar*)field->ptr, field->field_length);
}
field->ptr= field_buf;
}
field_bufs++;
}
return;
}
/*
Restore field pointers
SYNOPSIS
restore_part_field_pointers()
ptr Array of fields to restore
RETURN VALUES
NONE
*/
static void restore_part_field_pointers(Field **ptr, char **restore_ptr)
{
Field *field;
while ((field= *(ptr++)))
{
field->ptr= *restore_ptr;
restore_ptr++;
}
return;
}
/*
This function is used to calculate the partition id where all partition
fields have been prepared to point to a record where the partition field
......@@ -2266,6 +2557,7 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
part_info A reference to the partition_info struct where all the
desired information is given
out:part_id The partition id is returned through this pointer
out: func_value Value of partition function (longlong)
RETURN VALUE
part_id Partition id of partition that would contain
......@@ -2309,6 +2601,7 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
part_info A reference to the partition_info struct where all the
desired information is given
out:part_id The partition id is returned through this pointer
out: func_value The value calculated by partition function
RETURN VALUE
part_id Partition id of partition that would contain
......@@ -2330,6 +2623,78 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
get_partition_id_linear_key_nosub
*/
static int get_part_id_charset_func_subpart(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
{
int res;
copy_to_part_field_buffers(part_info->subpart_field_array,
part_info->subpart_field_buffers,
part_info->restore_subpart_field_ptrs);
res= part_info->get_partition_id_charset(part_info, part_id, func_value);
restore_part_field_pointers(part_info->subpart_field_array,
part_info->restore_subpart_field_ptrs);
return res;
}
static int get_part_id_charset_func_part(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
{
int res;
copy_to_part_field_buffers(part_info->part_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
res= part_info->get_partition_id_charset(part_info, part_id, func_value);
restore_part_field_pointers(part_info->part_field_array,
part_info->restore_part_field_ptrs);
return res;
}
static int get_part_id_charset_func_all(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
{
int res;
copy_to_part_field_buffers(part_info->part_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
copy_to_part_field_buffers(part_info->subpart_field_array,
part_info->subpart_field_buffers,
part_info->restore_subpart_field_ptrs);
res= part_info->get_partition_id_charset(part_info, part_id, func_value);
restore_part_field_pointers(part_info->part_field_array,
part_info->restore_part_field_ptrs);
restore_part_field_pointers(part_info->subpart_field_array,
part_info->restore_subpart_field_ptrs);
return res;
}
static int get_part_part_id_charset_func(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
{
int res;
copy_to_part_field_buffers(part_info->part_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
res= part_info->get_part_partition_id_charset(part_info,
part_id, func_value);
restore_part_field_pointers(part_info->part_field_array,
part_info->restore_part_field_ptrs);
return res;
}
static uint32 get_subpart_id_charset_func(partition_info *part_info)
{
int res;
copy_to_part_field_buffers(part_info->subpart_field_array,
part_info->subpart_field_buffers,
part_info->restore_subpart_field_ptrs);
res= part_info->get_subpartition_id_charset(part_info);
restore_part_field_pointers(part_info->subpart_field_array,
part_info->restore_subpart_field_ptrs);
return res;
}
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
......@@ -2418,6 +2783,21 @@ int get_partition_id_list(partition_info *part_info,
The edge of corresponding sub-array of part_info->list_array
*/
uint32 get_list_array_idx_for_endpoint_charset(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
{
uint32 res;
copy_to_part_field_buffers(part_info->part_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
res= get_list_array_idx_for_endpoint(part_info, left_endpoint,
include_endpoint);
restore_part_field_pointers(part_info->part_field_array,
part_info->restore_part_field_ptrs);
return res;
}
uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
......@@ -2547,6 +2927,22 @@ int get_partition_id_range(partition_info *part_info,
The edge of corresponding part_info->range_int_array sub-array.
*/
static uint32
get_partition_id_range_for_endpoint_charset(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
{
uint32 res;
copy_to_part_field_buffers(part_info->part_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
res= get_partition_id_range_for_endpoint(part_info, left_endpoint,
include_endpoint);
restore_part_field_pointers(part_info->part_field_array,
part_info->restore_part_field_ptrs);
return res;
}
uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
......@@ -4559,7 +4955,7 @@ the generated partition syntax in a correct manner.
tab_part_info->use_default_no_subpartitions= FALSE;
}
if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
table->file, ULL(0)))
table->file, ULL(0), FALSE))
{
DBUG_RETURN(TRUE);
}
......@@ -6386,13 +6782,20 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
if (part_info->part_type == RANGE_PARTITION)
{
get_endpoint= get_partition_id_range_for_endpoint;
if (part_info->includes_charset_field_part)
get_endpoint= get_partition_id_range_for_endpoint_charset;
else
get_endpoint= get_partition_id_range_for_endpoint;
max_endpoint_val= part_info->no_parts;
part_iter->get_next= get_next_partition_id_range;
}
else if (part_info->part_type == LIST_PARTITION)
{
get_endpoint= get_list_array_idx_for_endpoint;
if (part_info->includes_charset_field_part)
get_endpoint= get_list_array_idx_for_endpoint_charset;
else
get_endpoint= get_list_array_idx_for_endpoint;
max_endpoint_val= part_info->no_list_values;
part_iter->get_next= get_next_partition_id_list;
part_iter->part_info= part_info;
......
......@@ -3303,7 +3303,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,19 @@ part_bit_expr:
mem_alloc_error(sizeof(part_elem_value));
YYABORT;
}
part_expr->walk(&Item::check_partition_func_processor, 0,
(byte*)(&part_expression_ok));
if (!part_expression_ok)
{
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