diff options
-rw-r--r-- | mysql-test/r/partition.result | 2 | ||||
-rw-r--r-- | mysql-test/r/partition_error.result | 17 | ||||
-rw-r--r-- | mysql-test/t/partition.test | 2 | ||||
-rw-r--r-- | mysql-test/t/partition_error.test | 22 | ||||
-rw-r--r-- | sql/item.h | 45 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 30 | ||||
-rw-r--r-- | sql/item_func.h | 61 | ||||
-rw-r--r-- | sql/item_strfunc.h | 38 | ||||
-rw-r--r-- | sql/item_timefunc.h | 60 | ||||
-rw-r--r-- | sql/item_xmlfunc.h | 2 | ||||
-rw-r--r-- | sql/partition_info.cc | 38 | ||||
-rw-r--r-- | sql/partition_info.h | 3 | ||||
-rw-r--r-- | sql/sql_partition.cc | 50 | ||||
-rw-r--r-- | sql/sql_table.cc | 3 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 11 |
15 files changed, 243 insertions, 141 deletions
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index e95489864f7..2b5b47aeedd 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -751,7 +751,7 @@ t2 CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='no comment' /*!50100 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; diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index a51aaf22f69..6ded066c3ec 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -1,5 +1,22 @@ 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: diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index d4e930f91ec..4583c06e74f 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -884,7 +884,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; diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index d0e3f355292..a9efbc587be 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -9,6 +9,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 # create table t1 (a int) diff --git a/sql/item.h b/sql/item.h index be25d51bea1..f7bae8d3d47 100644 --- a/sql/item.h +++ b/sql/item.h @@ -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,12 @@ 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; } + + virtual bool check_partition_func_processor(byte *int_arg) + { + *(int *)int_arg= 0; + return FALSE; + } virtual Item *equal_fields_propagator(byte * arg) { return this; } virtual Item *set_no_const_sub(byte *arg) { return this; } @@ -1099,7 +1103,6 @@ public: Item::maybe_null= TRUE; } - bool check_partition_func_processor(byte *bool_arg) { return 0; } bool fix_fields(THD *, Item **); enum Type type() const; @@ -1145,7 +1148,7 @@ public: Item_num() {} /* Remove gcc warning */ virtual Item_num *neg()= 0; Item *safe_charset_converter(CHARSET_INFO *tocs); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; #define NO_CACHED_FIELD_INDEX ((uint)(-1)) @@ -1303,7 +1306,7 @@ public: bool collect_item_field_processor(byte * arg); bool find_item_in_field_list_processor(byte *arg); bool register_field_in_read_map(byte *arg); - bool check_partition_func_processor(byte *bool_arg) { return 0; } + bool check_partition_func_processor(byte *int_arg) { return FALSE; } void cleanup(); bool result_as_longlong() { @@ -1351,7 +1354,7 @@ public: bool is_null() { return 1; } void print(String *str) { str->append(STRING_WITH_LEN("NULL")); } Item *safe_charset_converter(CHARSET_INFO *tocs); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; class Item_null_result :public Item_null @@ -1364,8 +1367,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= 0; return FALSE; } }; /* Item represents one placeholder ('?') of prepared statement */ @@ -1656,8 +1659,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= 0; return FALSE; } }; @@ -1735,7 +1738,7 @@ public: void print(String *str); // to prevent drop fixed flag (no need parent cleanup call) void cleanup() {} - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -1750,8 +1753,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= 0; return FALSE; } }; @@ -1764,8 +1767,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= 0; return FALSE; } }; class Item_empty_string :public Item_string @@ -1788,8 +1791,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= 0; return FALSE; } }; @@ -1813,7 +1816,7 @@ public: void cleanup() {} bool eq(const Item *item, bool binary_cmp) const; virtual Item *safe_charset_converter(CHARSET_INFO *tocs); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -2040,8 +2043,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= 0; return FALSE; } }; #ifdef MYSQL_SERVER diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 82cb5febe7d..d84e73ff6a5 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -240,7 +240,7 @@ public: } Item *neg_transformer(THD *thd); virtual Item *negated_item(); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_not :public Item_bool_func @@ -251,7 +251,7 @@ public: enum Functype functype() const { return NOT_FUNC; } const char *func_name() const { return "not"; } Item *neg_transformer(THD *thd); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_maxmin_subselect; @@ -466,7 +466,7 @@ public: bool is_bool_func() { return 1; } CHARSET_INFO *compare_collation() { return cmp_collation.collation; } uint decimal_precision() const { return 1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -478,7 +478,7 @@ public: optimize_type select_optimize() const { return OPTIMIZE_NONE; } const char *func_name() const { return "strcmp"; } void print(String *str) { Item_func::print(str); } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -541,7 +541,7 @@ public: const char *func_name() const { return "ifnull"; } Field *tmp_table_field(TABLE *table); uint decimal_precision() const; - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -582,7 +582,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 FALSE; } }; @@ -625,7 +625,7 @@ public: void print(String *str); Item *find_item(String *str); CHARSET_INFO *compare_collation() { return cmp_collation.collation; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -976,7 +976,7 @@ public: bool nulls_in_row(); bool is_bool_func() { return 1; } CHARSET_INFO *compare_collation() { return cmp_collation.collation; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; /* Functions used by where clause */ @@ -1018,7 +1018,7 @@ public: optimize_type select_optimize() const { return OPTIMIZE_NULL; } Item *neg_transformer(THD *thd); CHARSET_INFO *compare_collation() { return args[0]->collation.collation; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; /* Functions used by HAVING for rewriting IN subquery */ @@ -1040,8 +1040,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= 0; return FALSE; } }; @@ -1064,7 +1064,7 @@ public: void print(String *str); CHARSET_INFO *compare_collation() { return args[0]->collation.collation; } void top_level_item() { abort_on_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -1103,7 +1103,7 @@ public: const char *func_name() const { return "like"; } bool fix_fields(THD *thd, Item **ref); void cleanup(); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; #ifdef USE_REGEX @@ -1126,7 +1126,7 @@ public: const char *func_name() const { return "regexp"; } void print(String *str) { print_op(str); } CHARSET_INFO *compare_collation() { return cmp_collation.collation; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; #else @@ -1183,7 +1183,7 @@ public: Item *transform(Item_transformer transformer, byte *arg); void traverse_cond(Cond_traverser, void *arg, traverse_order order); void neg_arguments(THD *thd); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; diff --git a/sql/item_func.h b/sql/item_func.h index ae7bff8a737..51447c335a6 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -250,7 +250,7 @@ public: void fix_num_length_and_dec(); void find_num_type(); String *str_op(String *str) { DBUG_ASSERT(0); return 0; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -263,7 +263,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; } }; @@ -314,7 +314,7 @@ public: { max_length=args[0]->max_length; unsigned_flag=0; } void print(String *str); uint decimal_precision() const { return args[0]->decimal_precision(); } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -348,7 +348,7 @@ public: void fix_length_and_dec() {}; const char *func_name() const { return "decimal_typecast"; } void print(String *); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -417,7 +417,7 @@ public: const char *func_name() const { return "DIV"; } void fix_length_and_dec(); void print(String *str) { print_op(str); } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -490,7 +490,7 @@ public: Item_func_exp(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "exp"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -500,7 +500,7 @@ public: Item_func_ln(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "ln"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -511,7 +511,7 @@ public: Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {} double val_real(); const char *func_name() const { return "log"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -521,7 +521,7 @@ public: Item_func_log2(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "log2"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -531,7 +531,7 @@ public: Item_func_log10(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "log10"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -541,7 +541,7 @@ public: Item_func_sqrt(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "sqrt"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -551,7 +551,7 @@ public: Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {} double val_real(); const char *func_name() const { return "pow"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -561,7 +561,7 @@ public: Item_func_acos(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "acos"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_asin :public Item_dec_func @@ -570,7 +570,7 @@ public: Item_func_asin(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "asin"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_atan :public Item_dec_func @@ -580,7 +580,7 @@ public: Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {} double val_real(); const char *func_name() const { return "atan"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_cos :public Item_dec_func @@ -589,7 +589,7 @@ public: Item_func_cos(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "cos"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_sin :public Item_dec_func @@ -598,7 +598,7 @@ public: Item_func_sin(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "sin"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_tan :public Item_dec_func @@ -607,7 +607,7 @@ public: Item_func_tan(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "tan"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_integer :public Item_int_func @@ -684,7 +684,7 @@ public: Item_func_sign(Item *a) :Item_int_func(a) {} const char *func_name() const { return "sign"; } longlong val_int(); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -699,7 +699,7 @@ public: const char *func_name() const { return name; } void fix_length_and_dec() { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -717,7 +717,7 @@ public: my_decimal *val_decimal(my_decimal *); void fix_length_and_dec(); enum Item_result result_type () const { return cmp_type; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_min :public Item_func_min_max @@ -743,7 +743,7 @@ public: longlong val_int(); const char *func_name() const { return "length"; } void fix_length_and_dec() { max_length=10; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_bit_length :public Item_func_length @@ -763,7 +763,7 @@ public: longlong val_int(); const char *func_name() const { return "char_length"; } void fix_length_and_dec() { max_length=10; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_coercibility :public Item_int_func @@ -774,7 +774,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 @@ -788,7 +787,7 @@ public: longlong val_int(); void fix_length_and_dec(); void print(String *str); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -813,7 +812,7 @@ public: longlong val_int(); const char *func_name() const { return "ascii"; } void fix_length_and_dec() { max_length=3; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_ord :public Item_int_func @@ -823,7 +822,7 @@ public: Item_func_ord(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "ord"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_find_in_set :public Item_int_func @@ -837,7 +836,7 @@ public: longlong val_int(); const char *func_name() const { return "find_in_set"; } void fix_length_and_dec(); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; /* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */ @@ -849,7 +848,7 @@ public: Item_func_bit(Item *a) :Item_int_func(a) {} void fix_length_and_dec() { unsigned_flag= 1; } void print(String *str) { print_op(str); } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_bit_or :public Item_func_bit @@ -875,7 +874,7 @@ public: longlong val_int(); const char *func_name() const { return "bit_count"; } void fix_length_and_dec() { max_length=2; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_shift_left :public Item_func_bit @@ -1312,7 +1311,7 @@ public: longlong val_int(); const char *func_name() const { return "inet_aton"; } void fix_length_and_dec() { decimals = 0; max_length = 21; maybe_null=1;} - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index c021aacf114..6f954744fc0 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -47,7 +47,7 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "md5"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -58,7 +58,6 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "sha"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_aes_encrypt :public Item_str_func @@ -89,7 +88,7 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "concat"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_concat_ws :public Item_str_func @@ -110,7 +109,7 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "reverse"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -148,7 +147,7 @@ protected: public: Item_str_conv(Item *item) :Item_str_func(item) {} String *val_str(String *); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -212,7 +211,6 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "substr"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -224,7 +222,6 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "substring_index"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -239,7 +236,6 @@ 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;} }; @@ -438,7 +434,7 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "soundex"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -546,7 +542,7 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "rpad"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -559,7 +555,7 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "lpad"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -574,7 +570,7 @@ public: collation.set(default_charset()); max_length= 64; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -591,7 +587,7 @@ public: decimals=0; max_length=args[0]->max_length*2*collation.collation->mbmaxlen; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_unhex :public Item_str_func @@ -607,7 +603,7 @@ public: decimals=0; max_length=(1+args[0]->max_length)/2; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -631,7 +627,7 @@ public: } void print(String *str); const char *func_name() const { return "cast_as_binary"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; @@ -671,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 FALSE; } }; class Item_func_quote :public Item_str_func @@ -686,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 FALSE; } }; class Item_func_conv_charset :public Item_str_func @@ -730,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 @@ -763,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 @@ -779,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 @@ -790,7 +783,7 @@ public: const char *func_name() const { return "crc32"; } void fix_length_and_dec() { max_length=10; } longlong val_int(); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; class Item_func_uncompressed_length : public Item_int_func @@ -801,7 +794,6 @@ public: const char *func_name() const{return "uncompressed_length";} void fix_length_and_dec() { max_length=10; } longlong val_int(); - bool check_partition_func_processor(byte *bool_arg) { return 0;} }; #ifdef HAVE_COMPRESS @@ -818,7 +810,6 @@ public: void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;} const char *func_name() const{return "compress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION - bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_uncompress: public Item_str_func @@ -829,7 +820,6 @@ 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;} }; #define UUID_LENGTH (8+1+4+1+4+1+4+1+12) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index e3f10c9716f..6623f7ad418 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -39,7 +39,7 @@ public: { max_length=6*MY_CHARSET_BIN_MB_MAXLEN; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -54,7 +54,7 @@ public: decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -71,7 +71,7 @@ public: maybe_null=1; } enum_monotonicity_info get_monotonicity_info() const; - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -87,7 +87,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -112,7 +112,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -145,7 +145,7 @@ public: max_length=3*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -161,7 +161,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -177,7 +177,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -193,7 +193,7 @@ public: max_length=1*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -209,7 +209,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -225,7 +225,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; class Item_func_yearweek :public Item_int_func @@ -240,7 +240,7 @@ public: max_length=6*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -257,7 +257,7 @@ public: max_length=4*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -287,7 +287,7 @@ public: max_length=1*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; class Item_func_dayname :public Item_func_weekday @@ -320,7 +320,7 @@ public: decimals=0; max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -335,7 +335,7 @@ public: decimals=0; max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -545,7 +545,7 @@ public: Item_func_from_days(Item *a) :Item_date(a) {} const char *func_name() const { return "from_days"; } bool get_date(TIME *res, uint fuzzy_date); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -563,7 +563,7 @@ public: void fix_length_and_dec(); uint format_length(const String *format); bool eq(const Item *item, bool binary_cmp) const; - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -582,7 +582,7 @@ class Item_func_from_unixtime :public Item_date_func const char *func_name() const { return "from_unixtime"; } void fix_length_and_dec(); bool get_date(TIME *res, uint fuzzy_date); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -651,7 +651,7 @@ public: return tmp_table_field_from_field_type(table, 0); } bool result_as_longlong() { return TRUE; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -674,7 +674,7 @@ public: bool get_date(TIME *res, uint fuzzy_date); bool eq(const Item *item, bool binary_cmp) const; void print(String *str); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -692,7 +692,7 @@ class Item_extract :public Item_int_func void fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; void print(String *str); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -729,7 +729,7 @@ public: max_length=args[0]->max_length; maybe_null= 1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -749,7 +749,7 @@ public: String *val_str(String *a); void fix_length_and_dec(); void print(String *str); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -829,7 +829,7 @@ public: } bool result_as_longlong() { return TRUE; } longlong val_int(); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -852,7 +852,7 @@ public: } void print(String *str); const char *func_name() const { return "add_time"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; class Item_func_timediff :public Item_str_func @@ -892,7 +892,7 @@ public: { return tmp_table_field_from_field_type(table, 0); } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; class Item_func_microsecond :public Item_int_func @@ -906,7 +906,7 @@ public: decimals=0; maybe_null=1; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -924,7 +924,7 @@ public: maybe_null=1; } void print(String *str); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; @@ -971,7 +971,7 @@ public: { return tmp_table_field_from_field_type(table, 1); } - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE;} }; diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index e11b4eac1e2..513a85aa665 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -42,7 +42,7 @@ public: Item_func_xml_extractvalue(Item *a,Item *b) :Item_xml_str_func(a,b) {} const char *func_name() const { return "extractvalue"; } String *val_str(String *); - bool check_partition_func_processor(byte *bool_arg) { return 0;} + bool check_partition_func_processor(byte *int_arg) { return FALSE; } }; diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 286637bd9aa..1afbb968547 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -695,6 +695,7 @@ end: file A reference to a handler of the table info Create info engine_type Return value for used engine in partitions + check_partition_function Should we check the partition function RETURN VALUE TRUE Error, something went wrong @@ -709,26 +710,41 @@ end: */ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type, - handler *file, HA_CREATE_INFO *info) + handler *file, HA_CREATE_INFO *info, + bool check_partition_function) { handlerton **engine_array= NULL; uint part_count= 0; uint i, tot_partitions; bool result= TRUE; char *same_name; - bool part_expression_ok= TRUE; DBUG_ENTER("partition_info::check_partition_info"); - if (part_type != HASH_PARTITION || !list_of_part_fields) - part_expr->walk(&Item::check_partition_func_processor, 0, - (byte*)(&part_expression_ok)); - if (is_sub_partitioned() && !list_of_subpart_fields) - subpart_expr->walk(&Item::check_partition_func_processor, 0, - (byte*)(&part_expression_ok)); - if (!part_expression_ok) + if (check_partition_function) { - my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0)); - goto end; + int 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))) diff --git a/sql/partition_info.h b/sql/partition_info.h index d938d21653a..8cc989c0991 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -250,7 +250,8 @@ public: bool check_range_constants(); bool check_list_constants(); bool check_partition_info(THD *thd, handlerton **eng_type, - handler *file, HA_CREATE_INFO *info); + handler *file, HA_CREATE_INFO *info, + bool check_partition_function); void print_no_partition_found(TABLE *table); private: static int list_part_cmp(const void* a, const void* b); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 3f1572ee676..55eab215746 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -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,43 @@ 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() + part_info Partition info + ptr Array of Field pointers + RETURN VALUES + FALSE Success + TRUE Error +*/ + +static bool check_part_func_fields(Field **ptr) +{ + Field *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) + return FALSE; + return TRUE; + } + } + return FALSE; +} + + /* fix partition functions @@ -1514,6 +1553,13 @@ bool fix_partition_func(THD *thd, TABLE *table, goto end; } } + if ((check_part_func_fields(part_info->part_field_array)) || + (part_info->is_sub_partitioned() && + check_part_func_fields(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))) @@ -4544,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); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 945fac83ff2..4187e89cd68 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3183,7 +3183,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; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ff422c4418c..bb44cbd43ab 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3637,6 +3637,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; @@ -3654,13 +3655,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; |