Commit 5771a711 authored by mikael@dator5.(none)'s avatar mikael@dator5.(none)

BUG#18198: Less flexibility in defining partition functions

Changed test for functions if they are supported.
3 categories:
1) Fully supported
2) Supported for single character collations
3) Supported for binary collations
parent d35c7f2f
......@@ -742,7 +742,7 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='no comment' PARTITION BY KEY (a)
drop table t2;
create table t1 (s1 char(2) character set utf8)
partition by list (case when s1 > 'cz' then 1 else 2 end)
partition by list (cast(s1 as signed))
(partition p1 values in (1),
partition p2 values in (2));
drop table t1;
......
......@@ -867,7 +867,7 @@ drop table t2;
# 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 by list (cast(s1 as signed))
(partition p1 values in (1),
partition p2 values in (2));
drop table t1;
......
......@@ -789,7 +789,7 @@ public:
Check if a partition function is allowed
SYNOPSIS
check_partition_func_processor()
bool_arg Return argument
int_arg Return argument
RETURN VALUE
0
DESCRIPTION
......@@ -806,8 +806,28 @@ public:
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; }
#define PF_SAFE_BINARY_COLLATION 3
#define PF_SAFE_SINGLE_CHAR_COLLATION 2
#define PF_SAFE 1
#define PF_UNSAFE 0
bool safe_for_binary_collation(byte *int_arg)
{
if (*(int *)int_arg != PF_UNSAFE)
*(int*)int_arg= PF_SAFE_BINARY_COLLATION;
return 0;
}
bool safe_for_single_char_collation(byte *int_arg)
{
if (*(int*)int_arg == PF_SAFE)
*(int*)int_arg= PF_SAFE_SINGLE_CHAR_COLLATION;
return 0;
}
virtual bool check_partition_func_processor(byte *int_arg)
{
*(int *)int_arg= PF_UNSAFE;
return 0;
}
virtual Item *equal_fields_propagator(byte * arg) { return this; }
virtual Item *set_no_const_sub(byte *arg) { return this; }
......@@ -1106,7 +1126,8 @@ public:
Item::maybe_null= TRUE;
}
bool check_partition_func_processor(byte *bool_arg) { return 0; }
bool check_partition_func_processor(byte *int_arg)
{ return safe_for_single_char_collation(int_arg); }
bool fix_fields(THD *, Item **);
enum Type type() const;
......@@ -1153,7 +1174,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 0;}
};
#define NO_CACHED_FIELD_INDEX ((uint)(-1))
......@@ -1289,7 +1310,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 0; }
void cleanup();
bool result_as_longlong()
{
......@@ -1337,7 +1358,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 0;}
};
class Item_null_result :public Item_null
......@@ -1350,8 +1371,8 @@ 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)
{ *(int *)int_arg= PF_UNSAFE; return 0; }
};
/* Item represents one placeholder ('?') of prepared statement */
......@@ -1642,8 +1663,8 @@ 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)
{ *(int *)int_arg= PF_UNSAFE; return 0; }
};
......@@ -1721,7 +1742,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 0;}
};
......@@ -1736,8 +1757,8 @@ 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)
{ *(int *)int_arg= PF_UNSAFE; return 0; }
};
......@@ -1750,8 +1771,8 @@ 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)
{ *(int *)int_arg= PF_UNSAFE; return 0; }
};
class Item_empty_string :public Item_string
......@@ -1774,8 +1795,8 @@ 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)
{ *(int *)int_arg= PF_UNSAFE; return 0; }
};
......@@ -1799,7 +1820,8 @@ 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 safe_for_binary_collation(int_arg);}
};
......@@ -2026,8 +2048,8 @@ 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)
{ *(int *)int_arg= PF_UNSAFE; return 0; }
};
#ifdef MYSQL_SERVER
......
......@@ -240,7 +240,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
class Item_func_not :public Item_bool_func
......@@ -251,7 +252,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
class Item_maxmin_subselect;
......@@ -466,7 +468,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
......@@ -478,7 +481,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
......@@ -541,7 +545,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 0;}
};
......@@ -582,7 +586,7 @@ 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 0;}
};
......@@ -625,7 +629,8 @@ 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 *int_arg)
{ return safe_for_single_char_collation(int_arg); }
};
......@@ -976,7 +981,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
/* Functions used by where clause */
......@@ -1018,7 +1024,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 0;}
};
/* Functions used by HAVING for rewriting IN subquery */
......@@ -1040,8 +1046,8 @@ 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)
{ *(int *)int_arg= PF_UNSAFE; return 0; }
};
......@@ -1064,7 +1070,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 0;}
};
......@@ -1103,7 +1109,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
#ifdef USE_REGEX
......@@ -1126,7 +1133,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
#else
......@@ -1183,7 +1191,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
......
......@@ -247,7 +247,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 0;}
};
......@@ -260,7 +260,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 0;}
};
......@@ -311,7 +311,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 0;}
};
......@@ -345,7 +345,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 0;}
};
......@@ -414,7 +414,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 0;}
};
......@@ -487,7 +487,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 0;}
};
......@@ -497,7 +497,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 0;}
};
......@@ -508,7 +508,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 0;}
};
......@@ -518,7 +518,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 0;}
};
......@@ -528,7 +528,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 0;}
};
......@@ -538,7 +538,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 0;}
};
......@@ -548,7 +548,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 0;}
};
......@@ -558,7 +558,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 0;}
};
class Item_func_asin :public Item_dec_func
......@@ -567,7 +567,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 0;}
};
class Item_func_atan :public Item_dec_func
......@@ -577,7 +577,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 0;}
};
class Item_func_cos :public Item_dec_func
......@@ -586,7 +586,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 0;}
};
class Item_func_sin :public Item_dec_func
......@@ -595,7 +595,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 0;}
};
class Item_func_tan :public Item_dec_func
......@@ -604,7 +604,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 0;}
};
class Item_func_integer :public Item_int_func
......@@ -681,7 +681,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 0;}
};
......@@ -696,7 +696,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 0;}
};
......@@ -714,7 +714,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 0;}
};
class Item_func_min :public Item_func_min_max
......@@ -740,7 +740,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
class Item_func_bit_length :public Item_func_length
......@@ -760,7 +761,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
class Item_func_coercibility :public Item_int_func
......@@ -771,7 +773,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
......@@ -785,7 +786,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......@@ -810,7 +812,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
class Item_func_ord :public Item_int_func
......@@ -820,7 +823,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
class Item_func_find_in_set :public Item_int_func
......@@ -834,7 +838,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
/* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
......@@ -846,7 +851,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 0;}
};
class Item_func_bit_or :public Item_func_bit
......@@ -872,7 +877,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 0;}
};
class Item_func_shift_left :public Item_func_bit
......@@ -1309,7 +1314,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 0;}
};
......
......@@ -47,7 +47,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......@@ -58,7 +59,8 @@ 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;}
bool check_partition_func_processor(byte *int_arg)
{ return safe_for_single_char_collation(int_arg);}
};
class Item_func_aes_encrypt :public Item_str_func
......@@ -89,7 +91,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
class Item_func_concat_ws :public Item_str_func
......@@ -110,7 +113,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......@@ -148,7 +152,8 @@ 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 safe_for_binary_collation(int_arg);}
};
......@@ -212,7 +217,8 @@ 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;}
bool check_partition_func_processor(byte *int_arg)
{ return safe_for_single_char_collation(int_arg);}
};
......@@ -224,7 +230,8 @@ 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;}
bool check_partition_func_processor(byte *int_arg)
{ return safe_for_single_char_collation(int_arg);}
};
......@@ -239,7 +246,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "trim"; }
bool check_partition_func_processor(byte *bool_arg) { return 0;}
bool check_partition_func_processor(byte *int_arg)
{ return safe_for_single_char_collation(int_arg);}
};
......@@ -419,7 +427,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......@@ -527,7 +536,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......@@ -540,7 +550,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......@@ -555,7 +566,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......@@ -572,7 +584,8 @@ 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 safe_for_binary_collation(int_arg);}
};
class Item_func_unhex :public Item_str_func
......@@ -588,7 +601,8 @@ 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 safe_for_binary_collation(int_arg);}
};
......@@ -612,7 +626,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......@@ -652,7 +667,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 0;}
};
class Item_func_quote :public Item_str_func
......@@ -667,7 +682,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 0;}
};
class Item_func_conv_charset :public Item_str_func
......@@ -711,7 +726,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
......@@ -744,7 +758,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
......@@ -760,7 +773,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
......@@ -771,7 +783,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
class Item_func_uncompressed_length : public Item_int_func
......@@ -782,7 +795,8 @@ 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;}
bool check_partition_func_processor(byte *int_arg)
{ return safe_for_single_char_collation(int_arg);}
};
#ifdef HAVE_COMPRESS
......@@ -799,7 +813,8 @@ 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;}
bool check_partition_func_processor(byte *int_arg)
{ return safe_for_single_char_collation(int_arg);}
};
class Item_func_uncompress: public Item_str_func
......@@ -810,7 +825,8 @@ public:
void fix_length_and_dec(){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;}
bool check_partition_func_processor(byte *int_arg)
{ return safe_for_single_char_collation(int_arg);}
};
#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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -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 0;}
};
......@@ -692,7 +692,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
......@@ -729,7 +730,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 0;}
};
......@@ -749,7 +750,8 @@ 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 safe_for_single_char_collation(int_arg); }
};
......@@ -829,7 +831,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 0;}
};
......@@ -852,7 +854,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 0;}
};
class Item_func_timediff :public Item_str_func
......@@ -892,7 +894,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 0;}
};
class Item_func_microsecond :public Item_int_func
......@@ -906,7 +908,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 0;}
};
......@@ -924,7 +926,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 0;}
};
......@@ -971,7 +973,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 0;}
};
......
......@@ -42,7 +42,8 @@ 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 safe_for_single_char_collation(int_arg);}
};
......
......@@ -694,6 +694,7 @@ end:
file A reference to a handler of the table
max_rows Maximum number of rows stored in the table
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
......@@ -708,26 +709,42 @@ end:
*/
bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
handler *file, ulonglong max_rows)
handler *file, ulonglong max_rows,
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;
int part_expression_ok= PF_SAFE;
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)
pf_collation_allowed= PF_SAFE;
spf_collation_allowed= PF_SAFE;
if (check_partition_function)
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
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= (char)part_expression_ok;
part_expression_ok= PF_SAFE;
if (is_sub_partitioned() && !list_of_subpart_fields)
{
subpart_expr->walk(&Item::check_partition_func_processor, 0,
(byte*)(&part_expression_ok));
}
spf_collation_allowed= (char)part_expression_ok;
}
else
multi_char_collation_allowed= TRUE;
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)))
......
......@@ -188,6 +188,8 @@ public:
bool is_auto_partitioned;
bool from_openfrm;
bool has_null_value;
char pf_collation_allowed;
char spf_collation_allowed;
partition_info()
......@@ -217,7 +219,9 @@ public:
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),
pf_collation_allowed(0),
spf_collation_allowed(0)
{
all_fields_in_PF.clear_all();
all_fields_in_PPF.clear_all();
......@@ -250,7 +254,8 @@ public:
bool check_range_constants();
bool check_list_constants();
bool check_partition_info(THD *thd, handlerton **eng_type,
handler *file, ulonglong max_rows);
handler *file, ulonglong max_rows,
bool check_partition_function);
void print_no_partition_found(TABLE *table);
private:
static int list_part_cmp(const void* a, const void* b);
......
......@@ -525,6 +525,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 +550,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 +560,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++)))
......@@ -1369,6 +1371,38 @@ 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_collation()
part_info Partition info
ptr Array of Field pointers
RETURN VALUES
FALSE Success
TRUE Error
*/
static bool check_part_func_collation(int collation_allowed,
Field **ptr)
{
Field *field;
while ((field= *(ptr++)))
{
if (field->result_type() == STRING_RESULT)
{
CHARSET_INFO *cs= ((Field_str*)field)->charset();
if (use_strnxfrm(cs) ||
(collation_allowed == PF_SAFE_BINARY_COLLATION &&
(!(cs->state & MY_CS_BINSORT))))
return TRUE;
}
}
return FALSE;
}
/*
fix partition functions
......@@ -1514,6 +1548,17 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
}
}
if (((part_info->pf_collation_allowed != PF_SAFE) &&
check_part_func_collation(part_info->pf_collation_allowed,
part_info->part_field_array)) ||
(part_info->is_sub_partitioned() &&
part_info->spf_collation_allowed != PF_SAFE &&
check_part_func_collation(part_info->spf_collation_allowed,
part_info->subpart_field_array)))
{
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)))
......@@ -4545,7 +4590,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);
}
......
......@@ -3145,7 +3145,7 @@ 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->max_rows))
create_info->max_rows, TRUE))
goto err;
part_info->default_engine_type= engine_type;
......
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