diff options
author | unknown <mikael/pappa@dator5.(none)> | 2006-08-02 07:01:38 -0400 |
---|---|---|
committer | unknown <mikael/pappa@dator5.(none)> | 2006-08-02 07:01:38 -0400 |
commit | 66f51d15742da645513e6f50db28d5a47e97fc5f (patch) | |
tree | f18a764bff80f479eb18d1517215d1160a408a07 /sql | |
parent | 95dcd768ca9da1f50f0ddfc42c9072c0001bc3d5 (diff) | |
parent | bcd98d512db7957896e44059e1f291c04aca3550 (diff) | |
download | mariadb-git-66f51d15742da645513e6f50db28d5a47e97fc5f.tar.gz |
Merge dator5.(none):/home/pappa/clean-mysql-5.1
into dator5.(none):/home/pappa/bug18198
mysql-test/r/partition_pruning.result:
Auto merged
mysql-test/t/partition_pruning.test:
Auto merged
sql/item.h:
Auto merged
sql/item_cmpfunc.h:
Auto merged
sql/item_func.h:
Auto merged
sql/sql_partition.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
sql/item_strfunc.h:
SCCS merged
Diffstat (limited to 'sql')
-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 | 32 | ||||
-rw-r--r-- | sql/sql_partition.cc | 456 | ||||
-rw-r--r-- | sql/sql_table.cc | 3 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 11 |
11 files changed, 612 insertions, 164 deletions
diff --git a/sql/item.h b/sql/item.h index 0e62d2aa9f0..420dbf164f9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -797,7 +797,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 @@ -814,8 +814,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; } @@ -1107,7 +1111,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; @@ -1153,7 +1156,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)) @@ -1311,7 +1314,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() { @@ -1359,7 +1362,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 @@ -1372,8 +1375,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 */ @@ -1664,8 +1667,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; } }; @@ -1743,7 +1746,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;} }; @@ -1758,8 +1761,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; } }; @@ -1772,8 +1775,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 @@ -1796,8 +1799,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; } }; @@ -1821,7 +1824,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; } }; @@ -2048,8 +2051,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 04462e05e9f..6785939b2bc 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; @@ -468,7 +468,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; } }; @@ -480,7 +480,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; } }; @@ -543,7 +543,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; } }; @@ -584,7 +584,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; } }; @@ -627,7 +627,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; } }; @@ -978,7 +978,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 */ @@ -1020,7 +1020,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 */ @@ -1042,8 +1042,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; } }; @@ -1066,7 +1066,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; } }; @@ -1105,7 +1105,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 @@ -1128,7 +1128,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 @@ -1185,7 +1185,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 3a1952c8d0f..274c058d3cc 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -252,7 +252,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; } }; @@ -265,7 +265,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; } }; @@ -316,7 +316,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; } }; @@ -350,7 +350,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; } }; @@ -419,7 +419,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; } }; @@ -492,7 +492,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; } }; @@ -502,7 +502,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; } }; @@ -513,7 +513,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; } }; @@ -523,7 +523,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; } }; @@ -533,7 +533,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; } }; @@ -543,7 +543,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; } }; @@ -553,7 +553,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; } }; @@ -563,7 +563,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 @@ -572,7 +572,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 @@ -582,7 +582,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 @@ -591,7 +591,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 @@ -600,7 +600,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 @@ -609,7 +609,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 @@ -686,7 +686,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; } }; @@ -701,7 +701,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; } }; @@ -719,7 +719,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 @@ -745,7 +745,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 @@ -765,7 +765,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 @@ -776,7 +776,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 @@ -790,7 +789,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; } }; @@ -815,7 +814,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 @@ -825,7 +824,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 @@ -839,7 +838,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: '~', '|', '^', '&', '>>', '<<' */ @@ -851,7 +850,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 @@ -877,7 +876,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 @@ -1316,7 +1315,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 e085c0b4d7b..615ad4b9aa3 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 @@ -111,7 +110,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; } }; @@ -149,7 +148,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; } }; @@ -213,7 +212,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;} }; @@ -225,7 +223,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;} }; @@ -242,7 +239,6 @@ public: const char *func_name() const { return "trim"; } void print(String *str); virtual const char *mode_name() const { return "both"; } - bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -443,7 +439,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; } }; @@ -551,7 +547,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; } }; @@ -564,7 +560,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; } }; @@ -579,7 +575,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; } }; @@ -596,7 +592,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 @@ -612,7 +608,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; } }; @@ -636,7 +632,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; } }; @@ -676,7 +672,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 @@ -691,7 +687,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 @@ -735,7 +731,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 @@ -768,7 +763,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 @@ -784,7 +778,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 @@ -795,7 +788,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 @@ -806,7 +799,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 @@ -823,7 +815,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 @@ -834,7 +825,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..91beaf569e0 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -60,7 +60,17 @@ public: same in all subpartitions */ get_subpart_id_func get_subpartition_id; - + + /* + When we have various string fields we might need some preparation + before and clean-up after calling the get_part_id_func's. We need + one such method for get_partition_id and one for + get_part_partition_id and one for get_subpartition_id. + */ + get_part_id_func get_partition_id_charset; + get_part_id_func get_part_partition_id_charset; + get_subpart_id_func get_subpartition_id_charset; + /* NULL-terminated array of fields used in partitioned expression */ Field **part_field_array; /* NULL-terminated array of fields used in subpartitioned expression */ @@ -72,6 +82,16 @@ public: */ 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 @@ public: 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 @@ public: 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 @@ 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), 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 @@ 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 73091c0994e..2cf13216f6d 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -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++))) @@ -1309,6 +1327,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; } @@ -1369,6 +1415,159 @@ 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) + { + DBUG_RETURN(FALSE); + } + if (!ok_with_charsets || + cs->mbmaxlen > 1 || + cs->strxfrm_multiply > 1) + { + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); + } + } + 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 @@ -1514,6 +1713,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))) @@ -1524,6 +1733,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); @@ -2241,6 +2455,86 @@ static uint32 get_part_id_linear_key(partition_info *part_info, } /* + 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 values are bound. @@ -2250,6 +2544,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 @@ -2293,6 +2588,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 @@ -2314,6 +2610,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, @@ -2402,6 +2770,21 @@ notfound: 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) @@ -2531,6 +2914,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) @@ -4544,7 +4943,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); } @@ -6371,13 +6770,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; 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 b8d68a91afc..74b87821892 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; |