|
These methods:
Item_date_add_interval::get_date()
|
Item_func_add_time::get_date()
|
have tests for field_type(). This is not friendly to new data types, which might want to have these functions in addition to the currently supported data types DATETIME, DATE, TIME.
Near future candidates:
- TIMESTAMP: Soon we'll change the temporal arithmetic to preserve the MYSQL_TYPE_TIMESTAMP type (MDEV-15750).
- TIMESTAMP WITH TIME ZONE
Also, we'll introduce INTERVAL data types natively and it will be possible to use intervals outside of the temporal arithmetic context, e.g.:
CREATE TABLE t1 (a INTERVAL HOUR TO SECOND);
|
INSERT INTO t1 VALUES (INTERVAL '10:20:30' HOUR TO SECOND);
|
SELECT * FROM t1 WHERE COALESCE(a, INTERVAL '00:00:00' HOUR TO SECOND) = INTERVAL '10:00:00' HOUR TO SECOND;
|
So, these syntax tricks:
| bit_expr '+' INTERVAL_SYM expr interval %prec '+'
|
{
|
$$= new (thd->mem_root) Item_date_add_interval(thd, $1, $4, $5, 0);
|
if (unlikely($$ == NULL))
|
MYSQL_YYABORT;
|
}
|
| DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
|
{
|
$$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 0);
|
if (unlikely($$ == NULL))
|
MYSQL_YYABORT;
|
}
|
will disappear soon. The syntax for interval expressions will migrate to the rule simple_expr. Expressions starting with the INTERVAL keyword will become normal expressions with they own Type_handler.
To make it possible for new data types to add their own implementations for ADDTIME()/SUBTIME(), DATE_ADD(), DATE_SUB(), as well as for the operators + and -, we'll do the following:
- Introduce a new class Item_handled_func, with approximately this prototype:
class Item_handled_func: public Item_func
|
{
|
public:
|
class Handler
|
{
|
public:
|
virtual ~Handler() { }
|
virtual String *val_str(Item_handled_func *, String *) const= 0;
|
virtual String *val_str_ascii(Item_handled_func *, String *) const= 0;
|
virtual double val_real(Item_handled_func *) const= 0;
|
virtual longlong val_int(Item_handled_func *) const= 0;
|
virtual my_decimal *val_decimal(Item_handled_func *, my_decimal *) const= 0;
|
virtual bool get_date(Item_handled_func *, MYSQL_TIME *, ulonglong fuzzydate) const= 0;
|
virtual const Type_handler *return_type_handler() const= 0;
|
virtual bool fix_length_and_dec(Item_handled_func *) const= 0;
|
};
|
protected:
|
const Handler *m_func_handler;
|
public:
|
Item_handled_func(THD *thd, Item *a)
|
:Item_func(thd, a), m_func_handler(NULL) { }
|
Item_handled_func(THD *thd, Item *a, Item *b)
|
:Item_func(thd, a, b), m_func_handler(NULL) { }
|
void set_func_handler(const Handler *handler)
|
{
|
m_func_handler= handler;
|
}
|
const Type_handler *type_handler() const
|
{
|
return m_func_handler->return_type_handler();
|
}
|
String *val_str(String *to)
|
{
|
return m_func_handler->val_str(this, to);
|
}
|
String *val_str_ascii(String *to)
|
{
|
return m_func_handler->val_str_ascii(this, to);
|
}
|
double val_real()
|
{
|
return m_func_handler->val_real(this);
|
}
|
longlong val_int()
|
{
|
return m_func_handler->val_int(this);
|
}
|
my_decimal *val_decimal(my_decimal *to)
|
{
|
return m_func_handler->val_decimal(this, to);
|
}
|
bool get_date(MYSQL_TIME *to, ulonglong fuzzydate)
|
{
|
return m_func_handler->get_date(this, to, fuzzydate);
|
}
|
};
|
- Change Item_func_add_time, Item_date_add_interval, Item_func_str_to_date to derive from the new class Item_handled_func.
- Remove class Item_temporal_hybrid_func
- Add handler classes for the former Item_temporal_hybrid_func descendants:
Item_handled_func::Handler
|
Func_handler_temporal_hybrid
|
Func_handler_date_add_interval
|
Func_handler_date_add_interval_datetime
|
Func_handler_date_add_interval_date
|
Func_handler_date_add_interval_time
|
Func_handler_date_add_interval_string
|
Func_handler_add_time
|
Func_handler_add_time_datetime
|
Func_handler_add_time_time
|
Func_handler_add_time_string
|
Func_handler_str_to_date_datetime
|
Func_handler_str_to_date_datetime_sec
|
Func_handler_str_to_date_datetime_usec
|
Func_handler_str_to_date_date
|
Func_handler_str_to_date_time
|
Func_handler_str_to_date_time_sec
|
Func_handler_str_to_date_time_usec
|
- Move the code from Item_func_xxx::get_date() and Item_func_xxx::fix_length_and_dec() to the corresponding methods in Func_handler_xxx
After this change:
Note, after this change, the fix_length_and_dec() part will sill have conditions testing field_type(). This is OK. This main goal of this task is to remove field_type() tests from get_date()! The remaining tests in fix_length_and_dec() will be removed in a separate change, when we add a registry of overloaded functions (in a way similar to how we added Type_aggregator for comparison functions and for CASE and its abbreviations).
Note, this task does not touch Item_func_plus and Item_func_minus. Eventually they'll also be changed to derive from Item_handled_func, in a separate task.
|