diff options
Diffstat (limited to 'sql/item_timefunc.h')
-rw-r--r-- | sql/item_timefunc.h | 236 |
1 files changed, 160 insertions, 76 deletions
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index b9888dab304..e930a24d2b0 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -1,5 +1,4 @@ -/* Copyright (c) 2000-2007 MySQL AB, 2008, 2009 Sun Microsystems, Inc. - Use is subject to license terms. +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,7 +11,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ /* Function items used by mysql */ @@ -26,6 +26,9 @@ enum date_time_format_types TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND }; +bool get_interval_value(Item *args,interval_type int_type, + String *str_value, INTERVAL *interval); + class Item_func_period_add :public Item_int_func { public: @@ -65,6 +68,13 @@ public: max_length=6*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + 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(); + } }; @@ -80,6 +90,11 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -104,6 +119,11 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -116,6 +136,7 @@ public: String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); + bool check_partition_func_processor(uchar *int_arg) {return TRUE;} }; @@ -131,6 +152,11 @@ public: max_length=3*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -146,6 +172,11 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -161,6 +192,11 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -176,6 +212,11 @@ public: max_length=1*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -191,6 +232,11 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -220,6 +266,11 @@ public: max_length=6*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -229,12 +280,19 @@ public: Item_func_year(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "year"; } + enum_monotonicity_info get_monotonicity_info() const; + longlong val_int_endpoint(bool left_endp, bool *incl_endp); void fix_length_and_dec() { decimals=0; max_length=4*MY_CHARSET_BIN_MB_MAXLEN; 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(); + } }; @@ -264,6 +322,11 @@ public: max_length=1*MY_CHARSET_BIN_MB_MAXLEN; 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 @@ -275,6 +338,7 @@ class Item_func_dayname :public Item_func_weekday String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); + bool check_partition_func_processor(uchar *int_arg) {return TRUE;} }; @@ -286,6 +350,16 @@ public: Item_func_unix_timestamp(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "unix_timestamp"; } + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + /* + UNIX_TIMESTAMP() depends on the current timezone + (and thus may not be used as a partitioning function) + when its argument is NOT of the TIMESTAMP type. + */ + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_timestamp_args(); + } void fix_length_and_dec() { decimals=0; @@ -302,9 +376,15 @@ public: const char *func_name() const { return "time_to_sec"; } void fix_length_and_dec() { + maybe_null= TRUE; decimals=0; 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(); + } }; @@ -329,10 +409,10 @@ public: decimals=0; max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } - Field *tmp_table_field(TABLE *t_arg) + Field *tmp_table_field(TABLE *table) { - return (new Field_newdate(maybe_null, name, t_arg, &my_charset_bin)); - } + return tmp_table_field_from_field_type(table, 0); + } bool result_as_longlong() { return TRUE; } my_decimal *val_decimal(my_decimal *decimal_value) { @@ -354,9 +434,9 @@ public: Item_date_func(Item *a,Item *b) :Item_str_func(a,b) {} Item_date_func(Item *a,Item *b, Item *c) :Item_str_func(a,b,c) {} enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } - Field *tmp_table_field(TABLE *t_arg) + Field *tmp_table_field(TABLE *table) { - return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin)); + return tmp_table_field_from_field_type(table, 0); } bool result_as_longlong() { return TRUE; } double val_real() { return (double) val_int(); } @@ -385,9 +465,9 @@ public: decimals= DATETIME_DEC; max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } - Field *tmp_table_field(TABLE *t_arg) + Field *tmp_table_field(TABLE *table) { - return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); + return tmp_table_field_from_field_type(table, 0); } double val_real() { return val_real_from_decimal(); } my_decimal *val_decimal(my_decimal *decimal_value) @@ -418,10 +498,6 @@ public: longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } String *val_str(String *str); void fix_length_and_dec(); - Field *tmp_table_field(TABLE *t_arg) - { - return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); - } /* Abstract method that defines which time zone is used for conversion. Converts time current time in my_time_t representation to broken-down @@ -561,6 +637,11 @@ public: Item_func_from_days(Item *a) :Item_date(a) {} 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(); + } }; @@ -610,8 +691,6 @@ class Time_zone; */ class Item_func_convert_tz :public Item_date_func { - /* Cached pointer to list of pre-opened time zone tables. */ - TABLE_LIST *tz_tables; /* If time zone parameters are constants we are caching objects that represent them (we use separate from_tz_cached/to_tz_cached members @@ -626,7 +705,6 @@ class Item_func_convert_tz :public Item_date_func longlong val_int(); String *val_str(String *str); const char *func_name() const { return "convert_tz"; } - bool fix_fields(THD *, Item **); void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); void cleanup(); @@ -654,23 +732,6 @@ public: bool result_as_longlong() { return TRUE; } }; -/* - 'interval_type' must be sorted so that simple intervals comes first, - ie year, quarter, month, week, day, hour, etc. The order based on - interval size is also important and the intervals should be kept in a - large to smaller order. (get_interval_value() depends on this) -*/ - -enum interval_type -{ - INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, - INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, - INTERVAL_MICROSECOND, INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, - INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, - INTERVAL_HOUR_SECOND, INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, - INTERVAL_HOUR_MICROSECOND, INTERVAL_MINUTE_MICROSECOND, - INTERVAL_SECOND_MICROSECOND -}; class Item_date_add_interval :public Item_date_func { @@ -689,13 +750,12 @@ public: longlong val_int(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); bool eq(const Item *item, bool binary_cmp) const; - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; class Item_extract :public Item_int_func { - String value; bool date_value; public: const interval_type int_type; // keep it public @@ -706,7 +766,44 @@ class Item_extract :public Item_int_func const char *func_name() const { return "extract"; } void fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; - void print(String *str); + 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; + } }; @@ -729,7 +826,7 @@ public: max_length=args[0]->max_length; } virtual const char* cast_type() const= 0; - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; @@ -761,7 +858,7 @@ public: const char* cast_type() const { return "char"; }; String *val_str(String *a); void fix_length_and_dec(); - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; @@ -775,9 +872,9 @@ public: bool get_time(MYSQL_TIME *ltime); const char *cast_type() const { return "date"; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; } - Field *tmp_table_field(TABLE *t_arg) + Field *tmp_table_field(TABLE *table) { - return (new Field_newdate(maybe_null, name, t_arg, &my_charset_bin)); + return tmp_table_field_from_field_type(table, 0); } void fix_length_and_dec() { @@ -809,9 +906,9 @@ public: bool get_time(MYSQL_TIME *ltime); const char *cast_type() const { return "time"; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } - Field *tmp_table_field(TABLE *t_arg) + Field *tmp_table_field(TABLE *table) { - return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); + return tmp_table_field_from_field_type(table, 0); } bool result_as_longlong() { return TRUE; } longlong val_int(); @@ -836,6 +933,10 @@ public: String *val_str(String *str); const char *cast_type() const { return "datetime"; } enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } + Field *tmp_table_field(TABLE *table) + { + return tmp_table_field_from_field_type(table, 0); + } void fix_length_and_dec() { collation.set(&my_charset_bin); @@ -843,11 +944,6 @@ public: max_length= MAX_DATETIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN; decimals= DATETIME_DEC; } - - Field *tmp_table_field(TABLE *t_arg) - { - return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin)); - } bool result_as_longlong() { return TRUE; } longlong val_int(); double val_real() { return val_real_from_decimal(); } @@ -874,21 +970,10 @@ public: { decimals=0; max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; - } - Field *tmp_table_field(TABLE *t_arg) - { - return (new Field_newdate(maybe_null, name, t_arg, &my_charset_bin)); + /* It returns NULL when the second argument is less or equal to 0 */ + maybe_null= 1; } longlong val_int(); - my_decimal *val_decimal(my_decimal *decimal_value) - { - DBUG_ASSERT(fixed == 1); - return val_decimal_from_date(decimal_value); - } - int save_in_field(Field *field, bool no_conversions) - { - return save_date_in_field(field); - } }; @@ -905,20 +990,11 @@ public: enum_field_types field_type() const { return cached_field_type; } void fix_length_and_dec(); -/* - TODO: - Change this when we support - microseconds in TIME/DATETIME -*/ - Field *tmp_table_field(TABLE *t_arg) + Field *tmp_table_field(TABLE *table) { - if (cached_field_type == MYSQL_TYPE_TIME) - return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); - else if (cached_field_type == MYSQL_TYPE_DATETIME) - return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin)); - return (new Field_string(max_length, maybe_null, name, t_arg, &my_charset_bin)); + return tmp_table_field_from_field_type(table, 0); } - void print(String *str); + virtual void print(String *str, enum_query_type query_type); const char *func_name() const { return "add_time"; } double val_real() { return val_real_from_decimal(); } my_decimal *val_decimal(my_decimal *decimal_value) @@ -977,6 +1053,11 @@ public: decimals=0; 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(); + } }; @@ -993,7 +1074,7 @@ public: decimals=0; maybe_null=1; } - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; @@ -1017,7 +1098,7 @@ public: decimals=0; max_length=17*MY_CHARSET_BIN_MB_MAXLEN; } - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; @@ -1036,7 +1117,10 @@ public: const char *func_name() const { return "str_to_date"; } enum_field_types field_type() const { return cached_field_type; } void fix_length_and_dec(); - Field *tmp_table_field(TABLE *t_arg); + Field *tmp_table_field(TABLE *table) + { + return tmp_table_field_from_field_type(table, 1); + } }; |