summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-12-02 10:49:16 +0400
committerAlexander Barkov <bar@mariadb.org>2015-12-02 10:49:16 +0400
commitcd828fb9163bb59865341559b0879f8f6a55ece9 (patch)
tree963c030ef3c9f36d8fd891cae19fd3855b43a0be
parent47a8c6c39713e03dfba46d82d013b1be7380ee43 (diff)
downloadmariadb-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.cc36
-rw-r--r--sql/item_timefunc.h42
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);