diff options
author | Mattias Jonsson <mattias.jonsson@oracle.com> | 2011-01-04 14:13:20 +0100 |
---|---|---|
committer | Mattias Jonsson <mattias.jonsson@oracle.com> | 2011-01-04 14:13:20 +0100 |
commit | 16994abf9a113187576691417f7430f48e514087 (patch) | |
tree | 61f3487ebf4903ac71afb0d5811427493546f8b0 /sql | |
parent | ee12d72444beedc9b2bb7bbdb46b18f10099909b (diff) | |
parent | 991815352259545d80dc1049d65854b08bd799c4 (diff) | |
download | mariadb-git-16994abf9a113187576691417f7430f48e514087.tar.gz |
merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 8 | ||||
-rw-r--r-- | sql/item_func.h | 42 | ||||
-rw-r--r-- | sql/item_timefunc.h | 94 | ||||
-rw-r--r-- | sql/sql_partition.cc | 11 |
4 files changed, 144 insertions, 11 deletions
diff --git a/sql/item.h b/sql/item.h index eb809ca410f..38b33bdf2fe 100644 --- a/sql/item.h +++ b/sql/item.h @@ -966,11 +966,11 @@ public: virtual bool set_no_const_sub(uchar *arg) { return FALSE; } virtual Item *replace_equal_field(uchar * arg) { return this; } /* - Check if an expression value depends on the current timezone. Used by - partitioning code to reject timezone-dependent expressions in a - (sub)partitioning function. + Check if an expression value has allowed arguments, like DATE/DATETIME + for date functions. Also used by partitioning code to reject + timezone-dependent expressions in a (sub)partitioning function. */ - virtual bool is_timezone_dependent_processor(uchar *bool_arg) + virtual bool check_valid_arguments_processor(uchar *bool_arg) { return FALSE; } diff --git a/sql/item_func.h b/sql/item_func.h index a280477a4b2..e9d91b56318 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -189,6 +189,7 @@ public: null_value=1; return 0.0; } + bool has_timestamp_args() { DBUG_ASSERT(fixed == TRUE); @@ -200,6 +201,45 @@ public: } return FALSE; } + + bool has_date_args() + { + DBUG_ASSERT(fixed == TRUE); + for (uint i= 0; i < arg_count; i++) + { + if (args[i]->type() == Item::FIELD_ITEM && + (args[i]->field_type() == MYSQL_TYPE_DATE || + args[i]->field_type() == MYSQL_TYPE_DATETIME)) + return TRUE; + } + return FALSE; + } + + bool has_time_args() + { + DBUG_ASSERT(fixed == TRUE); + for (uint i= 0; i < arg_count; i++) + { + if (args[i]->type() == Item::FIELD_ITEM && + (args[i]->field_type() == MYSQL_TYPE_TIME || + args[i]->field_type() == MYSQL_TYPE_DATETIME)) + return TRUE; + } + return FALSE; + } + + bool has_datetime_args() + { + DBUG_ASSERT(fixed == TRUE); + for (uint i= 0; i < arg_count; i++) + { + if (args[i]->type() == Item::FIELD_ITEM && + args[i]->field_type() == MYSQL_TYPE_DATETIME) + return TRUE; + } + return FALSE; + } + /* We assume the result of any function that has a TIMESTAMP argument to be timezone-dependent, since a TIMESTAMP value in both numeric and string @@ -208,7 +248,7 @@ public: representation of a TIMESTAMP argument verbatim, and thus does not depend on the timezone. */ - virtual bool is_timezone_dependent_processor(uchar *bool_arg) + virtual bool check_valid_arguments_processor(uchar *bool_arg) { return has_timestamp_args(); } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 47bb9509582..f4299460abf 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -70,6 +70,10 @@ public: enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; @@ -86,6 +90,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; @@ -111,6 +119,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; @@ -140,6 +152,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; @@ -156,6 +172,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_time_args(); + } }; @@ -172,6 +192,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_time_args(); + } }; @@ -188,6 +212,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; @@ -204,6 +232,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_time_args(); + } }; @@ -234,6 +266,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; @@ -252,6 +288,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; @@ -282,6 +322,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; class Item_func_dayname :public Item_func_weekday @@ -311,7 +355,7 @@ public: (and thus may not be used as a partitioning function) when its argument is NOT of the TIMESTAMP type. */ - bool is_timezone_dependent_processor(uchar *int_arg) + bool check_valid_arguments_processor(uchar *int_arg) { return !has_timestamp_args(); } @@ -336,6 +380,10 @@ public: max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_time_args(); + } }; @@ -589,6 +637,10 @@ public: const char *func_name() const { return "from_days"; } bool get_date(MYSQL_TIME *res, uint fuzzy_date); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return has_date_args() || has_time_args(); + } }; @@ -715,6 +767,42 @@ class Item_extract :public Item_int_func bool eq(const Item *item, bool binary_cmp) const; virtual void print(String *str, enum_query_type query_type); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + switch (int_type) { + case INTERVAL_YEAR: + case INTERVAL_YEAR_MONTH: + case INTERVAL_QUARTER: + case INTERVAL_MONTH: + /* case INTERVAL_WEEK: Not allowed as partitioning function, bug#57071 */ + case INTERVAL_DAY: + return !has_date_args(); + case INTERVAL_DAY_HOUR: + case INTERVAL_DAY_MINUTE: + case INTERVAL_DAY_SECOND: + case INTERVAL_DAY_MICROSECOND: + return !has_datetime_args(); + case INTERVAL_HOUR: + case INTERVAL_HOUR_MINUTE: + case INTERVAL_HOUR_SECOND: + case INTERVAL_MINUTE: + case INTERVAL_MINUTE_SECOND: + case INTERVAL_SECOND: + case INTERVAL_MICROSECOND: + case INTERVAL_HOUR_MICROSECOND: + case INTERVAL_MINUTE_MICROSECOND: + case INTERVAL_SECOND_MICROSECOND: + return !has_time_args(); + default: + /* + INTERVAL_LAST is only an end marker, + INTERVAL_WEEK depends on default_week_format which is a session + variable and cannot be used for partitioning. See bug#57071. + */ + break; + } + return true; + } }; @@ -965,6 +1053,10 @@ public: maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_time_args(); + } }; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 48d50c3a303..f8e5130880b 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1014,12 +1014,13 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, } /* - We don't allow creating partitions with timezone-dependent expressions as - a (sub)partitioning function, but we want to allow such expressions when - opening existing tables for easier maintenance. This exception should be - deprecated at some point in future so that we always throw an error. + We don't allow creating partitions with expressions with non matching + arguments as a (sub)partitioning function, + but we want to allow such expressions when opening existing tables for + easier maintenance. This exception should be deprecated at some point + in future so that we always throw an error. */ - if (func_expr->walk(&Item::is_timezone_dependent_processor, + if (func_expr->walk(&Item::check_valid_arguments_processor, 0, NULL)) { if (is_create_table_ind) |