diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-08-22 14:17:04 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-08-22 15:09:59 +0400 |
commit | 235cf969d21ba3406a9325d952fda47c589e58d6 (patch) | |
tree | 850e3fe62f7d4baec24847bd15808402bda48517 /sql/item_func.cc | |
parent | 7b4de10477a7bdb51656d827ad2d914d29a4be4c (diff) | |
download | mariadb-git-235cf969d21ba3406a9325d952fda47c589e58d6.tar.gz |
MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE()
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index ce01ef1a686..ced1d69caa9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2338,6 +2338,42 @@ void Item_func_round::fix_arg_double() } +void Item_func_round::fix_arg_temporal(const Type_handler *h, + uint int_part_length) +{ + set_handler(h); + if (args[1]->const_item() && !args[1]->is_expensive()) + { + Longlong_hybrid_null dec= args[1]->to_longlong_hybrid_null(); + fix_attributes_temporal(int_part_length, + dec.is_null() ? args[0]->decimals : + dec.to_uint(TIME_SECOND_PART_DIGITS)); + } + else + fix_attributes_temporal(int_part_length, args[0]->decimals); +} + + +void Item_func_round::fix_arg_time() +{ + fix_arg_temporal(&type_handler_time2, MIN_TIME_WIDTH); +} + + +void Item_func_round::fix_arg_datetime() +{ + /* + Day increment operations are not supported for '0000-00-00', + see get_date_from_daynr() for details. Therefore, expressions like + ROUND('0000-00-00 23:59:59.999999') + return NULL. + */ + if (!truncate) + maybe_null= true; + fix_arg_temporal(&type_handler_datetime2, MAX_DATETIME_WIDTH); +} + + void Item_func_round::fix_arg_int() { if (args[1]->const_item()) @@ -2477,6 +2513,36 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value) } +bool Item_func_round::time_op(THD *thd, MYSQL_TIME *to) +{ + DBUG_ASSERT(args[0]->type_handler()->mysql_timestamp_type() == + MYSQL_TIMESTAMP_TIME); + Time::Options opt(Time::default_flags_for_get_date(), + truncate ? TIME_FRAC_TRUNCATE : TIME_FRAC_ROUND, + Time::DATETIME_TO_TIME_DISALLOW); + Longlong_hybrid_null dec= args[1]->to_longlong_hybrid_null(); + Time *tm= new (to) Time(thd, args[0], opt, + dec.to_uint(TIME_SECOND_PART_DIGITS)); + null_value= !tm->is_valid_time() || dec.is_null(); + DBUG_ASSERT(maybe_null || !null_value); + return null_value; +} + + +bool Item_func_round::date_op(THD *thd, MYSQL_TIME *to, date_mode_t fuzzydate) +{ + DBUG_ASSERT(args[0]->type_handler()->mysql_timestamp_type() == + MYSQL_TIMESTAMP_DATETIME); + Datetime::Options opt(thd, truncate ? TIME_FRAC_TRUNCATE : TIME_FRAC_ROUND); + Longlong_hybrid_null dec= args[1]->to_longlong_hybrid_null(); + Datetime *tm= new (to) Datetime(thd, args[0], opt, + dec.to_uint(TIME_SECOND_PART_DIGITS)); + null_value= !tm->is_valid_datetime() || dec.is_null(); + DBUG_ASSERT(maybe_null || !null_value); + return null_value; +} + + void Item_func_rand::seed_random(Item *arg) { /* |