diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-12-02 10:49:16 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-12-02 10:49:16 +0400 |
commit | cd828fb9163bb59865341559b0879f8f6a55ece9 (patch) | |
tree | 963c030ef3c9f36d8fd891cae19fd3855b43a0be | |
parent | 47a8c6c39713e03dfba46d82d013b1be7380ee43 (diff) | |
download | mariadb-git-cd828fb9163bb59865341559b0879f8f6a55ece9.tar.gz |
MDEV-9215 Detect cmp_type() and result_type() from field_type()
Part4: Deriving Item_temporal_hybrid_func from Type_handler_hybrid_field_type
-rw-r--r-- | sql/item_timefunc.cc | 36 | ||||
-rw-r--r-- | sql/item_timefunc.h | 42 |
2 files changed, 44 insertions, 34 deletions
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2faf7a7d347..4cc9f6dc5bc 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1558,9 +1558,9 @@ String *Item_temporal_hybrid_func::val_str_ascii(String *str) return (String *) 0; /* Check that the returned timestamp type matches to the function type */ - DBUG_ASSERT(cached_field_type == MYSQL_TYPE_STRING || + DBUG_ASSERT(field_type() == MYSQL_TYPE_STRING || ltime.time_type == MYSQL_TIMESTAMP_NONE || - mysql_type_to_time_type(cached_field_type) == ltime.time_type); + mysql_type_to_time_type(field_type()) == ltime.time_type); return str; } @@ -2081,7 +2081,7 @@ void Item_date_add_interval::fix_length_and_dec() (This is because you can't know if the string contains a DATE, MYSQL_TIME or DATETIME argument) */ - cached_field_type= MYSQL_TYPE_STRING; + set_handler_by_field_type(MYSQL_TYPE_STRING); arg0_field_type= args[0]->field_type(); uint interval_dec= 0; if (int_type == INTERVAL_MICROSECOND || @@ -2095,25 +2095,25 @@ void Item_date_add_interval::fix_length_and_dec() arg0_field_type == MYSQL_TYPE_TIMESTAMP) { decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec); - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); } else if (arg0_field_type == MYSQL_TYPE_DATE) { if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH) - cached_field_type= arg0_field_type; + set_handler_by_field_type(arg0_field_type); else { decimals= interval_dec; - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); } } else if (arg0_field_type == MYSQL_TYPE_TIME) { decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME), interval_dec); if (int_type >= INTERVAL_DAY && int_type != INTERVAL_YEAR_MONTH) - cached_field_type= arg0_field_type; + set_handler_by_field_type(arg0_field_type); else - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); } else decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec); @@ -2126,7 +2126,7 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) INTERVAL interval; if (args[0]->get_date(ltime, - cached_field_type == MYSQL_TYPE_TIME ? + field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0) || get_interval_value(args[1], int_type, &interval)) return (null_value=1); @@ -2630,20 +2630,20 @@ void Item_func_add_time::fix_length_and_dec() - Otherwise the result is MYSQL_TYPE_STRING */ - cached_field_type= MYSQL_TYPE_STRING; + set_handler_by_field_type(MYSQL_TYPE_STRING); arg0_field_type= args[0]->field_type(); if (arg0_field_type == MYSQL_TYPE_DATE || arg0_field_type == MYSQL_TYPE_DATETIME || arg0_field_type == MYSQL_TYPE_TIMESTAMP || is_date) { - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), args[1]->temporal_precision(MYSQL_TYPE_TIME)); } else if (arg0_field_type == MYSQL_TYPE_TIME) { - cached_field_type= MYSQL_TYPE_TIME; + set_handler_by_field_type(MYSQL_TYPE_TIME); decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME), args[1]->temporal_precision(MYSQL_TYPE_TIME)); } @@ -2669,7 +2669,7 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) longlong seconds; int l_sign= sign; - if (cached_field_type == MYSQL_TYPE_DATETIME) + if (Item_func_add_time::field_type() == MYSQL_TYPE_DATETIME) { // TIMESTAMP function OR the first argument is DATE/DATETIME/TIMESTAMP if (get_arg0_date(&l_time1, 0) || @@ -3149,7 +3149,7 @@ void Item_func_str_to_date::fix_length_and_dec() #endif } - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); decimals= TIME_SECOND_PART_DIGITS; if ((const_item= args[1]->const_item())) { @@ -3164,24 +3164,24 @@ void Item_func_str_to_date::fix_length_and_dec() get_date_time_result_type(format->ptr(), format->length()); switch (cached_format_type) { case DATE_ONLY: - cached_field_type= MYSQL_TYPE_DATE; + set_handler_by_field_type(MYSQL_TYPE_DATE); break; case TIME_MICROSECOND: decimals= 6; /* fall through */ case TIME_ONLY: - cached_field_type= MYSQL_TYPE_TIME; + set_handler_by_field_type(MYSQL_TYPE_TIME); break; case DATE_TIME_MICROSECOND: decimals= 6; /* fall through */ case DATE_TIME: - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); break; } } } - cached_timestamp_type= mysql_type_to_time_type(cached_field_type); + cached_timestamp_type= mysql_type_to_time_type(field_type()); Item_temporal_func::fix_length_and_dec(); } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 32ba8f221de..2bfa31c604d 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -495,7 +495,6 @@ public: Item_temporal_func(THD *thd, Item *a, Item *b): Item_func(thd, a, b) {} Item_temporal_func(THD *thd, Item *a, Item *b, Item *c): Item_func(thd, a, b, c) {} enum Item_result result_type () const { return STRING_RESULT; } - enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } Item_result cmp_type() const { return TIME_RESULT; } String *val_str(String *str); longlong val_int() { return val_int_from_date(); } @@ -515,20 +514,20 @@ public: Abstract class for functions returning TIME, DATE, DATETIME or string values, whose data type depends on parameters and is set at fix_fields time. */ -class Item_temporal_hybrid_func: public Item_temporal_func +class Item_temporal_hybrid_func: public Item_temporal_func, + public Type_handler_hybrid_field_type { protected: - enum_field_types cached_field_type; // TIME, DATE, DATETIME or STRING String ascii_buf; // Conversion buffer public: Item_temporal_hybrid_func(THD *thd, Item *a, Item *b): Item_temporal_func(thd, a, b) {} - enum_field_types field_type() const { return cached_field_type; } - Item_result cmp_type() const - { - return cached_field_type == MYSQL_TYPE_STRING ? - STRING_RESULT : TIME_RESULT; - } + enum_field_types field_type() const + { return Type_handler_hybrid_field_type::field_type(); } + enum Item_result result_type () const + { return Type_handler_hybrid_field_type::result_type(); } + enum Item_result cmp_type () const + { return Type_handler_hybrid_field_type::cmp_type(); } CHARSET_INFO *charset_for_protocol() const { /* @@ -538,7 +537,7 @@ public: (which is fixed from @@collation_connection in fix_length_and_dec). */ DBUG_ASSERT(fixed == 1); - return cached_field_type == MYSQL_TYPE_STRING ? + return Item_temporal_hybrid_func::field_type() == MYSQL_TYPE_STRING ? collation.collation : &my_charset_bin; } /** @@ -581,6 +580,17 @@ public: }; +class Item_datetimefunc :public Item_temporal_func +{ +public: + Item_datetimefunc(THD *thd): Item_temporal_func(thd) {} + Item_datetimefunc(THD *thd, Item *a): Item_temporal_func(thd, a) {} + Item_datetimefunc(THD *thd, Item *a, Item *b, Item *c): + Item_temporal_func(thd, a, b ,c) {} + enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } +}; + + /* Abstract CURTIME function. Children should define what time zone is used */ class Item_func_curtime :public Item_timefunc @@ -665,11 +675,11 @@ public: /* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */ -class Item_func_now :public Item_temporal_func +class Item_func_now :public Item_datetimefunc { MYSQL_TIME ltime; public: - Item_func_now(THD *thd, uint dec): Item_temporal_func(thd) { decimals= dec; } + Item_func_now(THD *thd, uint dec): Item_datetimefunc(thd) { decimals= dec; } bool fix_fields(THD *, Item **); void fix_length_and_dec() { @@ -759,11 +769,11 @@ public: }; -class Item_func_from_unixtime :public Item_temporal_func +class Item_func_from_unixtime :public Item_datetimefunc { Time_zone *tz; public: - Item_func_from_unixtime(THD *thd, Item *a): Item_temporal_func(thd, a) {} + Item_func_from_unixtime(THD *thd, Item *a): Item_datetimefunc(thd, a) {} const char *func_name() const { return "from_unixtime"; } void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); @@ -784,7 +794,7 @@ class Time_zone; tables can be used during this function calculation for loading time zone descriptions. */ -class Item_func_convert_tz :public Item_temporal_func +class Item_func_convert_tz :public Item_datetimefunc { /* If time zone parameters are constants we are caching objects that @@ -796,7 +806,7 @@ class Item_func_convert_tz :public Item_temporal_func Time_zone *from_tz, *to_tz; public: Item_func_convert_tz(THD *thd, Item *a, Item *b, Item *c): - Item_temporal_func(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {} + Item_datetimefunc(thd, 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, ulonglong fuzzy_date); |