Commit cd828fb9 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-9215 Detect cmp_type() and result_type() from field_type()

Part4: Deriving Item_temporal_hybrid_func from Type_handler_hybrid_field_type
parent 47a8c6c3
......@@ -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();
}
......
......@@ -495,7 +495,6 @@ class Item_temporal_func: public Item_func
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 @@ class Item_temporal_func: public Item_func
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 @@ class Item_temporal_hybrid_func: public Item_temporal_func
(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 @@ class Item_timefunc :public Item_temporal_func
};
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 @@ class Item_func_curdate_utc :public Item_func_curdate
/* 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 @@ class Item_func_date_format :public Item_str_func
};
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment