diff options
-rw-r--r-- | mysql-test/r/information_schema_part.result | 29 | ||||
-rw-r--r-- | mysql-test/r/partition.result | 12 | ||||
-rw-r--r-- | mysql-test/r/partition_error.result | 23 | ||||
-rw-r--r-- | mysql-test/t/information_schema_part.test | 22 | ||||
-rw-r--r-- | mysql-test/t/partition.test | 17 | ||||
-rw-r--r-- | mysql-test/t/partition_error.test | 28 | ||||
-rw-r--r-- | sql/item.h | 41 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 15 | ||||
-rw-r--r-- | sql/item_func.h | 32 | ||||
-rw-r--r-- | sql/item_strfunc.h | 24 | ||||
-rw-r--r-- | sql/item_timefunc.h | 30 | ||||
-rw-r--r-- | sql/item_xmlfunc.h | 1 | ||||
-rw-r--r-- | sql/partition_info.cc | 12 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 3 | ||||
-rw-r--r-- | sql/sql_partition.cc | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 21 | ||||
-rw-r--r-- | storage/archive/ha_archive.cc | 17 |
17 files changed, 311 insertions, 18 deletions
diff --git a/mysql-test/r/information_schema_part.result b/mysql-test/r/information_schema_part.result index cf49abf888a..e1bc6ef8700 100644 --- a/mysql-test/r/information_schema_part.result +++ b/mysql-test/r/information_schema_part.result @@ -111,3 +111,32 @@ NULL test t1 p0 NULL 1 NULL LINEAR HASH NULL month(f1) NULL NULL 0 0 0 # 1024 0 NULL test t1 p1 NULL 2 NULL LINEAR HASH NULL month(f1) NULL NULL 0 0 0 # 1024 0 # # NULL NULL default 0 default NULL test t1 p2 NULL 3 NULL LINEAR HASH NULL month(f1) NULL NULL 0 0 0 # 1024 0 # # NULL NULL default 0 default drop table t1; +create table t1 (a int) +PARTITION BY RANGE (a) +SUBPARTITION BY LINEAR HASH (a) +(PARTITION p0 VALUES LESS THAN (10)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY RANGE (a) SUBPARTITION BY LINEAR HASH (a) (PARTITION p0 VALUES LESS THAN (10) ) +select SUBPARTITION_METHOD FROM information_schema.partitions WHERE +table_schema="test" AND table_name="t1"; +SUBPARTITION_METHOD +LINEAR HASH +drop table t1; +create table t1 (a int) +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN +(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53) ENGINE = MyISAM) +SELECT PARTITION_DESCRIPTION FROM information_schema.partitions WHERE +table_schema = "test" AND table_name = "t1"; +PARTITION_DESCRIPTION +10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53 +drop table t1; diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 3be9f3edee2..2fb7b6942de 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -936,4 +936,16 @@ OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize note The storage engine for the table doesn't support optimize drop table t1; +create database db99; +use db99; +create table t1 (a int not null) +engine=archive +partition by list (a) +(partition p0 values in (1), partition p1 values in (2)); +insert into t1 values (1), (2); +create index inx on t1 (a); +alter table t1 add partition (partition p2 values in (3)); +alter table t1 drop partition p2; +use test; +drop database db99; End of 5.1 tests diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 1a0b1dd9b3a..a7ca3d9b2fa 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -554,3 +554,26 @@ PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN(5)); insert into t1 values (10); ERROR HY000: Table has no partition for value 10 drop table t1; +create table t1 (v varchar(12)) +partition by range (ascii(v)) +(partition p0 values less than (10)); +drop table t1; +create table t1 (a int) +partition by hash (rand(a)); +ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +create table t1 (a int) +partition by hash(CURTIME() + a); +ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +create table t1 (a int) +partition by hash (NOW()+a); +ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +create table t1 (a int) +partition by hash (extract(hour from convert_tz(a, '+00:00', '+00:00'))); +ERROR HY000: This partition function is not allowed +create table t1 (a int) +partition by range (a + (select count(*) from t1)) +(partition p1 values less than (1)); +ERROR HY000: This partition function is not allowed +create table t1 (a char(10)) +partition by hash (extractvalue(a,'a')); +ERROR HY000: The PARTITION function returns the wrong type diff --git a/mysql-test/t/information_schema_part.test b/mysql-test/t/information_schema_part.test index 163b04248b8..4cbf21ca1d3 100644 --- a/mysql-test/t/information_schema_part.test +++ b/mysql-test/t/information_schema_part.test @@ -99,3 +99,25 @@ select * from information_schema.partitions where table_schema="test" and table_name="t1"; drop table t1; +# +# Bug 20161 Partitions: SUBPARTITION METHOD doesn't show LINEAR keyword +# +create table t1 (a int) +PARTITION BY RANGE (a) +SUBPARTITION BY LINEAR HASH (a) +(PARTITION p0 VALUES LESS THAN (10)); + +SHOW CREATE TABLE t1; +select SUBPARTITION_METHOD FROM information_schema.partitions WHERE +table_schema="test" AND table_name="t1"; +drop table t1; + +create table t1 (a int) +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN +(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53)); +SHOW CREATE TABLE t1; +SELECT PARTITION_DESCRIPTION FROM information_schema.partitions WHERE +table_schema = "test" AND table_name = "t1"; +drop table t1; diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index a24124d3fb5..f7676ca471a 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1077,4 +1077,21 @@ OPTIMIZE TABLE t1; drop table t1; +# +# Bug 17310 Partitions: Bugs with archived partitioned tables +# +create database db99; +use db99; +create table t1 (a int not null) +engine=archive +partition by list (a) +(partition p0 values in (1), partition p1 values in (2)); +insert into t1 values (1), (2); +--error 0, 1005 +create index inx on t1 (a); +alter table t1 add partition (partition p2 values in (3)); +alter table t1 drop partition p2; +use test; +drop database db99; + --echo End of 5.1 tests diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 03a2ab41807..659f0b8cef4 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -747,3 +747,31 @@ CREATE TABLE t1(a int) --error ER_NO_PARTITION_FOR_GIVEN_VALUE insert into t1 values (10); drop table t1; + +# +# Bug 18198 Partitions: Verify that erroneus partition functions doesn't work +# +create table t1 (v varchar(12)) +partition by range (ascii(v)) +(partition p0 values less than (10)); +drop table t1; + +-- error 1064 +create table t1 (a int) +partition by hash (rand(a)); +-- error 1064 +create table t1 (a int) +partition by hash(CURTIME() + a); +-- error 1064 +create table t1 (a int) +partition by hash (NOW()+a); +-- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int) +partition by hash (extract(hour from convert_tz(a, '+00:00', '+00:00'))); +-- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int) +partition by range (a + (select count(*) from t1)) +(partition p1 values less than (1)); +-- error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR +create table t1 (a char(10)) +partition by hash (extractvalue(a,'a')); diff --git a/sql/item.h b/sql/item.h index 2f99034130a..685da3014ef 100644 --- a/sql/item.h +++ b/sql/item.h @@ -783,6 +783,29 @@ public: virtual bool find_item_in_field_list_processor(byte *arg) { return 0; } virtual bool change_context_processor(byte *context) { return 0; } virtual bool reset_query_id_processor(byte *query_id) { return 0; } + /* + Check if a partition function is allowed + SYNOPSIS + check_partition_func_processor() + bool_arg Return argument + RETURN VALUE + 0 + DESCRIPTION + check_partition_func_processor is used to check if a partition function + uses an allowed function. The default is that an item is not allowed + in a partition function. However all mathematical functions, string + manipulation functions, date functions are allowed. Allowed functions + can never depend on server version, they cannot depend on anything + related to the environment. They can also only depend on a set of + fields in the table itself. They cannot depend on other tables and + cannot contain any queries and cannot contain udf's or similar. + If a new Item class is defined and it inherits from a class that is + allowed in a partition function then it is very important to consider + whether this should be inherited to the new class. If not the function + below should be defined in the new Item class. + */ + virtual bool check_partition_func_processor(byte *bool_arg) + { *(bool *)bool_arg= FALSE; return 0; } virtual Item *equal_fields_propagator(byte * arg) { return this; } virtual Item *set_no_const_sub(byte *arg) { return this; } @@ -1073,6 +1096,7 @@ public: Item::maybe_null= TRUE; } + bool check_partition_func_processor(byte *bool_arg) { return 0; } bool fix_fields(THD *, Item **); enum Type type() const; @@ -1119,6 +1143,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;} }; #define NO_CACHED_FIELD_INDEX ((uint)(-1)) @@ -1260,6 +1285,7 @@ public: result_field->query_id= field->query_id; return 0; } + bool check_partition_func_processor(byte *bool_arg) { return 0; } void cleanup(); Item_equal *find_item_equal(COND_EQUAL *cond_equal); Item *equal_fields_propagator(byte *arg); @@ -1303,6 +1329,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;} }; class Item_null_result :public Item_null @@ -1315,6 +1342,8 @@ public: { save_in_field(result_field, no_conversions); } + bool check_partition_func_processor(byte *bool_arg) + { *(bool *)bool_arg= FALSE; return 0; } }; /* Item represents one placeholder ('?') of prepared statement */ @@ -1605,6 +1634,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; } }; @@ -1682,6 +1713,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;} }; @@ -1696,6 +1728,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; } }; @@ -1708,6 +1742,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; } }; class Item_empty_string :public Item_string @@ -1730,6 +1766,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; } }; @@ -1753,6 +1791,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;} }; @@ -1975,6 +2014,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; } }; #ifdef MYSQL_SERVER diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 1cfdcef02d0..f7da1e5e297 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -239,6 +239,7 @@ public: } Item *neg_transformer(THD *thd); virtual Item *negated_item(); + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_not :public Item_bool_func @@ -249,6 +250,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;} }; class Item_maxmin_subselect; @@ -463,6 +465,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;} }; @@ -474,6 +477,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;} }; @@ -536,6 +540,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;} }; @@ -576,6 +581,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;} }; @@ -618,6 +624,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;} }; @@ -968,6 +975,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;} }; /* Functions used by where clause */ @@ -1009,6 +1017,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;} }; /* Functions used by HAVING for rewriting IN subquery */ @@ -1030,6 +1039,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; } }; @@ -1052,6 +1063,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;} }; @@ -1090,6 +1102,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;} }; #ifdef USE_REGEX @@ -1112,6 +1125,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;} }; #else @@ -1168,6 +1182,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;} }; diff --git a/sql/item_func.h b/sql/item_func.h index 1d8a1bd5e22..9d31b57838c 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -247,6 +247,7 @@ public: void fix_num_length_and_dec(); void find_num_type(); String *str_op(String *str) { DBUG_ASSERT(0); return 0; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -259,6 +260,7 @@ class Item_num_op :public Item_func_numhybrid void print(String *str) { print_op(str); } void find_num_type(); String *str_op(String *str) { DBUG_ASSERT(0); return 0; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -309,7 +311,7 @@ public: { max_length=args[0]->max_length; unsigned_flag=0; } void print(String *str); uint decimal_precision() const { return args[0]->decimal_precision(); } - + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -343,6 +345,7 @@ public: void fix_length_and_dec() {}; const char *func_name() const { return "decimal_typecast"; } void print(String *); + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -411,6 +414,7 @@ public: const char *func_name() const { return "DIV"; } void fix_length_and_dec(); void print(String *str) { print_op(str); } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -483,6 +487,7 @@ public: Item_func_exp(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "exp"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -492,6 +497,7 @@ public: Item_func_ln(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "ln"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -502,6 +508,7 @@ public: Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {} double val_real(); const char *func_name() const { return "log"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -511,6 +518,7 @@ public: Item_func_log2(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "log2"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -520,6 +528,7 @@ public: Item_func_log10(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "log10"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -529,6 +538,7 @@ public: Item_func_sqrt(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "sqrt"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -538,6 +548,7 @@ public: Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {} double val_real(); const char *func_name() const { return "pow"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -547,6 +558,7 @@ public: Item_func_acos(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "acos"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_asin :public Item_dec_func @@ -555,6 +567,7 @@ public: Item_func_asin(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "asin"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_atan :public Item_dec_func @@ -564,6 +577,7 @@ public: Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {} double val_real(); const char *func_name() const { return "atan"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_cos :public Item_dec_func @@ -572,6 +586,7 @@ public: Item_func_cos(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "cos"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_sin :public Item_dec_func @@ -580,6 +595,7 @@ public: Item_func_sin(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "sin"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_tan :public Item_dec_func @@ -588,6 +604,7 @@ public: Item_func_tan(Item *a) :Item_dec_func(a) {} double val_real(); const char *func_name() const { return "tan"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_integer :public Item_int_func @@ -664,6 +681,7 @@ public: Item_func_sign(Item *a) :Item_int_func(a) {} const char *func_name() const { return "sign"; } longlong val_int(); + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -678,6 +696,7 @@ public: const char *func_name() const { return name; } void fix_length_and_dec() { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -695,6 +714,7 @@ public: my_decimal *val_decimal(my_decimal *); void fix_length_and_dec(); enum Item_result result_type () const { return cmp_type; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_min :public Item_func_min_max @@ -720,6 +740,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;} }; class Item_func_bit_length :public Item_func_length @@ -739,6 +760,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;} }; class Item_func_coercibility :public Item_int_func @@ -749,6 +771,7 @@ 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 @@ -762,6 +785,7 @@ public: longlong val_int(); void fix_length_and_dec(); void print(String *str); + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -786,6 +810,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;} }; class Item_func_ord :public Item_int_func @@ -795,6 +820,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;} }; class Item_func_find_in_set :public Item_int_func @@ -808,6 +834,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;} }; /* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */ @@ -819,6 +846,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;} }; class Item_func_bit_or :public Item_func_bit @@ -844,6 +872,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;} }; class Item_func_shift_left :public Item_func_bit @@ -1280,6 +1309,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;} }; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 90d421a2c68..212c06c45ff 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -47,6 +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;} }; @@ -57,6 +58,7 @@ 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 @@ -87,6 +89,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;} }; class Item_func_concat_ws :public Item_str_func @@ -107,6 +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;} }; @@ -144,6 +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;} }; @@ -207,6 +212,7 @@ 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;} }; @@ -218,6 +224,7 @@ 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;} }; @@ -232,6 +239,7 @@ 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;} }; @@ -411,6 +419,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;} }; @@ -518,6 +527,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;} }; @@ -530,6 +540,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;} }; @@ -544,6 +555,7 @@ public: collation.set(default_charset()); max_length= 64; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -560,6 +572,7 @@ public: decimals=0; max_length=args[0]->max_length*2*collation.collation->mbmaxlen; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_unhex :public Item_str_func @@ -575,6 +588,7 @@ public: decimals=0; max_length=(1+args[0]->max_length)/2; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -598,6 +612,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;} }; @@ -637,6 +652,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;} }; class Item_func_quote :public Item_str_func @@ -651,6 +667,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;} }; class Item_func_conv_charset :public Item_str_func @@ -693,6 +710,7 @@ 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 @@ -725,6 +743,7 @@ 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 @@ -740,6 +759,7 @@ 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 @@ -750,6 +770,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;} }; class Item_func_uncompressed_length : public Item_int_func @@ -760,6 +781,7 @@ 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 @@ -776,6 +798,7 @@ 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 @@ -786,6 +809,7 @@ 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 ae0ca1a0445..69c8ec5959a 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -39,6 +39,7 @@ public: { max_length=6*MY_CHARSET_BIN_MB_MAXLEN; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -53,6 +54,7 @@ public: decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -69,6 +71,7 @@ public: maybe_null=1; } enum_monotonicity_info get_monotonicity_info() const; + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -84,6 +87,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -108,6 +112,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -140,6 +145,7 @@ public: max_length=3*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -155,6 +161,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -170,6 +177,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -185,6 +193,7 @@ public: max_length=1*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -200,6 +209,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -215,6 +225,7 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_yearweek :public Item_int_func @@ -229,6 +240,7 @@ public: max_length=6*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -245,6 +257,7 @@ public: max_length=4*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -274,6 +287,7 @@ public: max_length=1*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_dayname :public Item_func_weekday @@ -306,6 +320,7 @@ public: decimals=0; max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -320,6 +335,7 @@ public: decimals=0; max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -526,6 +542,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;} }; @@ -543,6 +560,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;} }; @@ -561,6 +579,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;} }; @@ -627,6 +646,7 @@ public: { return tmp_table_field_from_field_type(table, 0); } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -649,6 +669,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;} }; @@ -666,6 +687,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;} }; @@ -702,6 +724,7 @@ public: max_length=args[0]->max_length; maybe_null= 1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -721,6 +744,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;} }; @@ -792,6 +816,7 @@ public: { return tmp_table_field_from_field_type(table, 0); } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -814,6 +839,7 @@ public: } void print(String *str); const char *func_name() const { return "add_time"; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_timediff :public Item_str_func @@ -853,6 +879,7 @@ public: { return tmp_table_field_from_field_type(table, 0); } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; class Item_func_microsecond :public Item_int_func @@ -866,6 +893,7 @@ public: decimals=0; maybe_null=1; } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -883,6 +911,7 @@ public: maybe_null=1; } void print(String *str); + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; @@ -929,6 +958,7 @@ public: { return tmp_table_field_from_field_type(table, 1); } + bool check_partition_func_processor(byte *bool_arg) { return 0;} }; diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index bc47e9c5bb1..e11b4eac1e2 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -42,6 +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;} }; diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 0924a8adf6e..289296fcac3 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -685,8 +685,20 @@ bool partition_info::check_partition_info(handlerton **eng_type, 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, + (byte*)(&part_expression_ok)); + if (is_sub_partitioned() && !list_of_subpart_fields) + subpart_expr->walk(&Item::check_partition_func_processor, + (byte*)(&part_expression_ok)); + if (!part_expression_ok) + { + 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/share/errmsg.txt b/sql/share/errmsg.txt index 5aab951b2ca..58dc107900a 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5832,6 +5832,9 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT eng "The NDB cluster engine does not support changing the binlog format on the fly yet" ER_PARTITION_NO_TEMPORARY eng "Cannot create temporary table with partitions" +ER_PARTITION_FUNCTION_IS_NOT_ALLOWED + eng "This partition function is not allowed" + swe "Denna partitioneringsfunktion är inte tillåten" ER_DDL_LOG_ERROR eng "Error in DDL log" ER_NULL_IN_VALUES_LESS_THAN diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 733287f8359..53536e72961 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1843,6 +1843,8 @@ char *generate_partition_syntax(partition_info *part_info, { err+= add_subpartition_by(fptr); /* Must be hash partitioning for subpartitioning */ + if (part_info->linear_hash_ind) + err+= add_string(fptr, partition_keywords[PKW_LINEAR].str); if (part_info->list_of_subpart_fields) err+= add_key_partition(fptr, part_info->subpart_field_list); else diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 8c492e9457b..dfa90733739 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3916,24 +3916,28 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables, { table->field[9]->store(part_info->part_func_string, part_info->part_func_len, cs); - table->field[9]->set_notnull(); } else if (part_info->list_of_part_fields) { collect_partition_expr(part_info->part_field_list, &tmp_str); table->field[9]->store(tmp_str.ptr(), tmp_str.length(), cs); - table->field[9]->set_notnull(); } + table->field[9]->set_notnull(); if (part_info->is_sub_partitioned()) { /* Subpartition method */ + tmp_res.length(0); + if (part_info->linear_hash_ind) + tmp_res.append(partition_keywords[PKW_LINEAR].str, + partition_keywords[PKW_LINEAR].length); if (part_info->list_of_subpart_fields) - table->field[8]->store(partition_keywords[PKW_KEY].str, - partition_keywords[PKW_KEY].length, cs); + tmp_res.append(partition_keywords[PKW_KEY].str, + partition_keywords[PKW_KEY].length); else - table->field[8]->store(partition_keywords[PKW_HASH].str, - partition_keywords[PKW_HASH].length, cs); + tmp_res.append(partition_keywords[PKW_HASH].str, + partition_keywords[PKW_HASH].length); + table->field[8]->store(tmp_res.ptr(), tmp_res.length(), cs); table->field[8]->set_notnull(); /* Subpartition expression */ @@ -3941,14 +3945,13 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables, { table->field[10]->store(part_info->subpart_func_string, part_info->subpart_func_len, cs); - table->field[10]->set_notnull(); } else if (part_info->list_of_subpart_fields) { collect_partition_expr(part_info->subpart_field_list, &tmp_str); table->field[10]->store(tmp_str.ptr(), tmp_str.length(), cs); - table->field[10]->set_notnull(); } + table->field[10]->set_notnull(); } while ((part_elem= part_it++)) @@ -5352,7 +5355,7 @@ ST_FIELD_INFO partitions_fields_info[]= {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0}, {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0}, {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0}, - {"SUBPARTITION_METHOD", 5, MYSQL_TYPE_STRING, 0, 1, 0}, + {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0}, {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0}, diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 739acffeb0d..39b887a8001 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -666,14 +666,6 @@ int ha_archive::create(const char *name, TABLE *table_arg, create_info->auto_increment_value -1 : (ulonglong) 0); - if ((create_file= my_create(fn_format(name_buff,name,"",ARM, - MY_REPLACE_EXT|MY_UNPACK_FILENAME),0, - O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) - { - error= my_errno; - goto error; - } - for (uint key= 0; key < table_arg->s->keys; key++) { KEY *pos= table_arg->key_info+key; @@ -687,11 +679,20 @@ int ha_archive::create(const char *name, TABLE *table_arg, if (!(field->flags & AUTO_INCREMENT_FLAG)) { error= -1; + DBUG_PRINT("info", ("Index error in creating archive table")); goto error; } } } + if ((create_file= my_create(fn_format(name_buff,name,"",ARM, + MY_REPLACE_EXT|MY_UNPACK_FILENAME),0, + O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) + { + error= my_errno; + goto error; + } + write_meta_file(create_file, 0, auto_increment_value, 0, (char *)create_info->data_file_name, FALSE); |