diff options
Diffstat (limited to 'sql/item_timefunc.h')
-rw-r--r-- | sql/item_timefunc.h | 185 |
1 files changed, 111 insertions, 74 deletions
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 8d19e59ddfb..3af08a8168e 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -1,3 +1,5 @@ +#ifndef ITEM_TIMEFUNC_INCLUDED +#define ITEM_TIMEFUNC_INCLUDED /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. Copyright (c) 2009-2011, Monty Program Ab @@ -12,8 +14,7 @@ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Function items used by mysql */ @@ -22,13 +23,27 @@ #pragma interface /* gcc class implementation */ #endif +class MY_LOCALE; + 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); +static inline enum enum_mysql_timestamp_type +mysql_type_to_time_type(enum enum_field_types mysql_type) +{ + switch(mysql_type) { + case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME; + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME; + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE; + default: return MYSQL_TIMESTAMP_ERROR; + } +} + +bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval); class Item_func_period_add :public Item_int_func { @@ -80,6 +95,39 @@ public: }; +class Item_func_to_seconds :public Item_int_func +{ +public: + Item_func_to_seconds(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "to_seconds"; } + void fix_length_and_dec() + { + decimals=0; + 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 *bool_arg) { return FALSE;} + + bool intro_version(uchar *int_arg) + { + int *input_version= (int*)int_arg; + /* This function was introduced in 5.5 */ + int output_version= max(*input_version, 50500); + *input_version= output_version; + return 0; + } + + /* Only meaningful with date part and optional time part */ + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } +}; + + class Item_func_dayofmonth :public Item_int_func { public: @@ -104,7 +152,7 @@ public: class Item_func_month :public Item_func { public: - Item_func_month(Item *a) :Item_func(a) {} + Item_func_month(Item *a) :Item_func(a) { collation.set_numeric(); } longlong val_int(); double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); } @@ -113,17 +161,16 @@ public: longlong nr= val_int(); if (null_value) return 0; - str->set(nr, &my_charset_bin); + str->set(nr, collation.collation); return str; } const char *func_name() const { return "month"; } enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() { - collation.set(&my_charset_bin); - decimals=0; - max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - maybe_null=1; + decimals= 0; + fix_char_length(2); + maybe_null= 1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -134,17 +181,20 @@ public: }; -class Item_func_monthname :public Item_func_month +class Item_func_monthname :public Item_str_func { MY_LOCALE *locale; public: - Item_func_monthname(Item *a) :Item_func_month(a) {} + Item_func_monthname(Item *a) :Item_str_func(a) {} const char *func_name() const { return "monthname"; } 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;} bool check_vcol_func_processor(uchar *int_arg) {return FALSE;} + bool check_valid_arguments_processor(uchar *int_arg) + { + return !has_date_args(); + } }; @@ -156,9 +206,9 @@ public: const char *func_name() const { return "dayofyear"; } void fix_length_and_dec() { - decimals=0; - max_length=3*MY_CHARSET_BIN_MB_MAXLEN; - maybe_null=1; + decimals= 0; + fix_char_length(3); + maybe_null= 1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -316,7 +366,7 @@ class Item_func_weekday :public Item_func bool odbc_type; public: Item_func_weekday(Item *a,bool type_arg) - :Item_func(a), odbc_type(type_arg) {} + :Item_func(a), odbc_type(type_arg) { collation.set_numeric(); } longlong val_int(); double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String *str) @@ -332,10 +382,9 @@ public: enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() { - collation.set(&my_charset_bin); - decimals=0; - max_length=1*MY_CHARSET_BIN_MB_MAXLEN; - maybe_null=1; + decimals= 0; + fix_char_length(1); + maybe_null= 1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -370,6 +419,7 @@ public: decimals= args[0]->decimals; set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); max_length=17 + (decimals ? decimals + 1 : 0); + maybe_null= 1; } void find_num_type() { hybrid_type= decimals ? DECIMAL_RESULT : INT_RESULT; } double real_op() { DBUG_ASSERT(0); return 0; } @@ -384,6 +434,8 @@ public: Item_func_unix_timestamp() :Item_func_seconds_hybrid() {} Item_func_unix_timestamp(Item *a) :Item_func_seconds_hybrid(a) {} const char *func_name() const { return "unix_timestamp"; } + 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;} /* UNIX_TIMESTAMP() depends on the current timezone @@ -407,7 +459,6 @@ public: }; - class Item_func_time_to_sec :public Item_func_seconds_hybrid { public: @@ -431,47 +482,26 @@ public: class Item_temporal_func: public Item_func { + ulonglong sql_mode; public: Item_temporal_func() :Item_func() {} Item_temporal_func(Item *a) :Item_func(a) {} Item_temporal_func(Item *a, Item *b) :Item_func(a,b) {} Item_temporal_func(Item *a, Item *b, Item *c) :Item_func(a,b,c) {} enum Item_result result_type () const { return STRING_RESULT; } + CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; } enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } String *val_str(String *str); longlong val_int(); double val_real(); - bool get_date(MYSQL_TIME *res, uint fuzzy_date) { DBUG_ASSERT(0); return 1; } + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date) { DBUG_ASSERT(0); return 1; } my_decimal *val_decimal(my_decimal *decimal_value) { return val_decimal_from_date(decimal_value); } Field *tmp_table_field(TABLE *table) { return tmp_table_field_from_field_type(table, 0); } int save_in_field(Field *field, bool no_conversions) { return save_date_in_field(field); } - void fix_length_and_dec() - { - static const uint max_time_type_width[5]= - { MAX_DATETIME_WIDTH, MAX_DATETIME_WIDTH, MAX_DATE_WIDTH, - MAX_DATETIME_WIDTH, MIN_TIME_WIDTH }; - - maybe_null= true; - max_length= max_time_type_width[mysql_type_to_time_type(field_type())+2]; - if (decimals) - { - if (decimals == NOT_FIXED_DEC) - max_length+= TIME_SECOND_PART_DIGITS + 1; - else - { - set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); - max_length+= decimals + 1; - } - } - /* - We set maybe_null to 1 as default as any bad argument with date or - time can get us to return NULL. - */ - maybe_null= 1; - } + void fix_length_and_dec(); }; @@ -509,7 +539,7 @@ public: Item_timefunc::fix_length_and_dec(); maybe_null= false; } - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); /* Abstract method that defines which time zone is used for conversion. Converts time current time in my_time_t representation to broken-down @@ -549,7 +579,7 @@ class Item_func_curdate :public Item_datefunc public: Item_func_curdate() :Item_datefunc() {} void fix_length_and_dec(); - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; bool check_vcol_func_processor(uchar *int_arg) { @@ -591,7 +621,7 @@ public: Item_temporal_func::fix_length_and_dec(); maybe_null= false; } - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; bool check_vcol_func_processor(uchar *int_arg) { @@ -630,10 +660,11 @@ public: bool const_item() const { return 0; } const char *func_name() const { return "sysdate"; } void store_now_in_TIME(MYSQL_TIME *now_time); - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); void update_used_tables() { Item_func_now::update_used_tables(); + maybe_null= false; used_tables_cache|= RAND_TABLE_BIT; } }; @@ -644,7 +675,7 @@ class Item_func_from_days :public Item_datefunc public: Item_func_from_days(Item *a) :Item_datefunc(a) {} const char *func_name() const { return "from_days"; } - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) @@ -678,7 +709,7 @@ class Item_func_from_unixtime :public Item_temporal_func Item_func_from_unixtime(Item *a) :Item_temporal_func(a) {} const char *func_name() const { return "from_unixtime"; } void fix_length_and_dec(); - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); }; @@ -711,7 +742,7 @@ class Item_func_convert_tz :public Item_temporal_func Item_temporal_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {} const char *func_name() const { return "convert_tz"; } void fix_length_and_dec(); - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); void cleanup(); }; @@ -720,7 +751,7 @@ class Item_func_sec_to_time :public Item_timefunc { public: Item_func_sec_to_time(Item *item) :Item_timefunc(item) {} - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); void fix_length_and_dec() { decimals= args[0]->decimals; @@ -732,9 +763,7 @@ public: class Item_date_add_interval :public Item_temporal_func { - String value; enum_field_types cached_field_type; - public: const interval_type int_type; // keep it public const bool date_sub_interval; // keep it public @@ -743,9 +772,9 @@ public: const char *func_name() const { return "date_add_interval"; } void fix_length_and_dec(); enum_field_types field_type() const { return cached_field_type; } - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); bool eq(const Item *item, bool binary_cmp) const; - virtual void print(String *str, enum_query_type query_type); + void print(String *str, enum_query_type query_type); }; @@ -761,7 +790,7 @@ 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; - virtual void print(String *str, enum_query_type query_type); + void print(String *str, enum_query_type query_type); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} bool check_valid_arguments_processor(uchar *int_arg) @@ -840,7 +869,7 @@ class Item_date_typecast :public Item_temporal_typecast public: Item_date_typecast(Item *a) :Item_temporal_typecast(a) {} const char *func_name() const { return "cast_as_date"; } - bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *cast_type() const { return "date"; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; } }; @@ -852,7 +881,7 @@ public: Item_time_typecast(Item *a, uint dec_arg) :Item_temporal_typecast(a) { decimals= dec_arg; } const char *func_name() const { return "cast_as_time"; } - bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *cast_type() const { return "time"; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } }; @@ -866,7 +895,7 @@ public: const char *func_name() const { return "cast_as_datetime"; } const char *cast_type() const { return "datetime"; } enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } - bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); }; @@ -876,7 +905,7 @@ public: Item_func_makedate(Item *a,Item *b) :Item_temporal_func(a,b) {} const char *func_name() const { return "makedate"; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; } - bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); }; @@ -891,8 +920,8 @@ public: :Item_temporal_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; } enum_field_types field_type() const { return cached_field_type; } void fix_length_and_dec(); - bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); - virtual void print(String *str, enum_query_type query_type); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); + void print(String *str, enum_query_type query_type); const char *func_name() const { return "add_time"; } }; @@ -907,7 +936,7 @@ public: decimals= max(args[0]->decimals, args[1]->decimals); Item_timefunc::fix_length_and_dec(); } - bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); }; class Item_func_maketime :public Item_timefunc @@ -917,7 +946,7 @@ public: :Item_timefunc(a, b, c) {} const char *func_name() const { return "maketime"; } - bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); }; @@ -963,20 +992,20 @@ enum date_time_format USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT }; -class Item_func_get_format :public Item_str_func +class Item_func_get_format :public Item_str_ascii_func { public: const timestamp_type type; // keep it public Item_func_get_format(timestamp_type type_arg, Item *a) - :Item_str_func(a), type(type_arg) + :Item_str_ascii_func(a), type(type_arg) {} - String *val_str(String *str); + String *val_str_ascii(String *str); const char *func_name() const { return "get_format"; } void fix_length_and_dec() { maybe_null= 1; decimals=0; - max_length=17*MY_CHARSET_BIN_MB_MAXLEN; + fix_length_and_charset(17, default_charset()); } virtual void print(String *str, enum_query_type query_type); }; @@ -991,7 +1020,7 @@ public: Item_func_str_to_date(Item *a, Item *b) :Item_temporal_func(a, b), const_item(false) {} - bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *func_name() const { return "str_to_date"; } enum_field_types field_type() const { return cached_field_type; } void fix_length_and_dec(); @@ -1003,5 +1032,13 @@ class Item_func_last_day :public Item_datefunc public: Item_func_last_day(Item *a) :Item_datefunc(a) {} const char *func_name() const { return "last_day"; } - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); }; + + +/* Function prototypes */ + +bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, + timestamp_type type, String *str); + +#endif /* ITEM_TIMEFUNC_INCLUDED */ |