1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

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`.
This commit is contained in:
Alexander Barkov
2020-07-31 10:42:44 +04:00
parent a773d93267
commit dc513dff91
6 changed files with 61 additions and 13 deletions

View File

@ -2742,6 +2742,17 @@ public:
};
class DTCollation_numeric: public DTCollation
{
public:
DTCollation_numeric()
:DTCollation(charset_info(), DERIVATION_NUMERIC, MY_REPERTOIRE_NUMERIC)
{ }
static const CHARSET_INFO *charset_info() { return &my_charset_numeric; }
static const DTCollation & singleton();
};
static inline uint32
char_to_byte_length_safe(size_t char_length_arg, uint32 mbmaxlen_arg)
{
@ -4658,8 +4669,6 @@ public:
bool Item_func_between_fix_length_and_dec(Item_func_between *func) const;
bool Item_func_in_fix_comparator_compatible_types(THD *thd,
Item_func_in *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
bool Item_func_plus_fix_length_and_dec(Item_func_plus *) const;
@ -5486,6 +5495,8 @@ public:
longlong Item_func_min_max_val_int(Item_func_min_max *) const;
my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
my_decimal *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_hybrid_func_fix_attributes(THD *thd,
const char *name,
Type_handler_hybrid_field_type *,