Bug Report
Although in MySQL's docs:
The return value depends on the arguments:
DATE if the date argument is a DATE value and your calculations involve only YEAR, MONTH, and DAY parts (that is, no time parts).
DATETIME if the first argument is a DATETIME (or TIMESTAMP) value, or if the first argument is a DATE and the unit value uses HOURS, MINUTES, or SECONDS.
String otherwise.
But in its actual implementation:
bool Item_date_add_interval::resolve_type(THD *) {
maybe_null = true;
/*
The field type for the result of an Item_date function is defined as
follows:
- If first arg is a MYSQL_TYPE_DATETIME result is MYSQL_TYPE_DATETIME
- If first arg is a MYSQL_TYPE_DATE and the interval type uses hours,
minutes or seconds then type is MYSQL_TYPE_DATETIME.
- Otherwise the result is MYSQL_TYPE_STRING
(This is because you can't know if the string contains a DATE, MYSQL_TIME
or DATETIME argument)
*/
enum_field_types arg0_data_type = args[0]->data_type();
uint8 interval_dec = 0;
if (int_type == INTERVAL_MICROSECOND ||
(int_type >= INTERVAL_DAY_MICROSECOND &&
int_type <= INTERVAL_SECOND_MICROSECOND))
interval_dec = DATETIME_MAX_DECIMALS;
else if (int_type == INTERVAL_SECOND && args[1]->decimals > 0)
interval_dec = MY_MIN(args[1]->decimals, DATETIME_MAX_DECIMALS);
if (arg0_data_type == MYSQL_TYPE_DATETIME ||
arg0_data_type == MYSQL_TYPE_TIMESTAMP) {
uint8 dec = MY_MAX(args[0]->datetime_precision(), interval_dec);
set_data_type_datetime(dec);
} else if (arg0_data_type == MYSQL_TYPE_DATE) {
if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH)
set_data_type_date();
else
set_data_type_datetime(interval_dec);
} else if (arg0_data_type == MYSQL_TYPE_TIME) {
uint8 dec = MY_MAX(args[0]->time_precision(), interval_dec);
set_data_type_time(dec);
} else {
/* Behave as a usual string function when return type is VARCHAR. */
set_data_type_char(MAX_DATETIME_FULL_WIDTH, default_charset());
}
if (value.alloc(max_length)) return true;
return false;
}
The return type can also be Time, which is Duration in TiDB.
So currently if the arg[0] is Duration we'll get the result with the year, month and day field. Which is not a reasonable return value.
We need to cover this unexpected case.
Bug Report
Although in MySQL's docs:
But in its actual implementation:
The return type can also be
Time, which isDurationin TiDB.So currently if the arg[0] is
Durationwe'll get the result with the year, month and day field. Which is not a reasonable return value.We need to cover this unexpected case.