diff options
author | Alexander Barkov <bar@mariadb.com> | 2020-07-31 10:42:44 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2020-07-31 17:45:39 +0400 |
commit | dc513dff911d72eaaf9f752f390fef8d1ef9a4b0 (patch) | |
tree | 3af27646a38985babb5e2094aecf4e144060d4bd /sql/item_func.cc | |
parent | a773d932678a0b205f43d8a1aaa416d843d66bc8 (diff) | |
download | mariadb-git-dc513dff911d72eaaf9f752f390fef8d1ef9a4b0.tar.gz |
MDEV-23351 Rounding functions return wrong data types for DATE input
Fixing ROUND(date,0), TRUNCATE(date,x), FLOOR(date), CEILING(date)
to return the `int(8) unsigned` data type.
Details:
1. Cleanup: moving virtual implementations
- Type_handler_temporal_result::Item_func_int_val_fix_length_and_dec()
- Type_handler_temporal_result::Item_func_round_fix_length_and_dec()
to Type_handler_date_common. Other temporal data type handlers
override these methods anyway. So they were only DATE specific.
This change makes the code clearer.
2. Backporting DTCollation_numeric from 10.5, to reuse the code easier.
3. Adding the `preferred_attrs` argument to Item_func_round::fix_arg_int(). Now
Type_handler_xxx::Item_func_round_val_fix_length_and_dec() work as follows:
- The INT-alike and YEAR handlers copy preferred_attrs from args[0].
- The DATE handler passes explicit attributes, to get `int(8) unsigned`.
- The hex hybrid handler passes NULL, so fix_arg_int() calculates attributes.
4. Type_handler_date_common::Item_func_int_val_fix_length_and_dec()
now sets the type handler and attributes to get `int(8) unsigned`.
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index 8e36804888b..6b19933fd48 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2455,13 +2455,16 @@ void Item_func_round::fix_arg_datetime() (without extending to DECIMAL). - If `preferred` is not NULL, then the code tries to preserve the given data type handler and - data type attributes of the argument. + the data type attributes `preferred_attrs`. - If `preferred` is NULL, then the code fully calculates attributes using args[0]->decimal_precision() and chooses between INT and BIGINT, depending on attributes. + @param [IN] preferred_attrs - The preferred data type attributes for + simple cases. */ -void Item_func_round::fix_arg_int(const Type_handler *preferred) +void Item_func_round::fix_arg_int(const Type_handler *preferred, + const Type_std_attributes *preferred_attrs) { DBUG_ASSERT(args[0]->decimals == 0); if (args[1]->const_item()) @@ -2477,7 +2480,7 @@ void Item_func_round::fix_arg_int(const Type_handler *preferred) int length_can_increase= MY_TEST(!truncate && val1.neg()); if (preferred) { - Type_std_attributes::set(args[0]); + Type_std_attributes::set(preferred_attrs); if (!length_can_increase) { // Preserve the exact data type and attributes |