1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +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

@ -23,6 +23,12 @@
#include "log.h"
#include "tztime.h"
const DTCollation &DTCollation_numeric::singleton()
{
static const DTCollation_numeric tmp;
return tmp;
}
Type_handler_row type_handler_row;
Type_handler_null type_handler_null;
@ -5659,7 +5665,7 @@ bool Type_handler_row::
bool Type_handler_int_result::
Item_func_round_fix_length_and_dec(Item_func_round *item) const
{
item->fix_arg_int(this);
item->fix_arg_int(this, item->arguments()[0]);
return false;
}
@ -5667,7 +5673,7 @@ bool Type_handler_int_result::
bool Type_handler_year::
Item_func_round_fix_length_and_dec(Item_func_round *item) const
{
item->fix_arg_int(&type_handler_long); // 10.5 merge: fix to type_handler_ulong
item->fix_arg_int(&type_handler_long, item->arguments()[0]); // 10.5 merge: fix to type_handler_ulong
return false;
}
@ -5675,7 +5681,7 @@ bool Type_handler_year::
bool Type_handler_hex_hybrid::
Item_func_round_fix_length_and_dec(Item_func_round *item) const
{
item->fix_arg_int(NULL);
item->fix_arg_int(NULL, NULL);
return false;
}
@ -5713,10 +5719,12 @@ bool Type_handler_decimal_result::
}
bool Type_handler_temporal_result::
bool Type_handler_date_common::
Item_func_round_fix_length_and_dec(Item_func_round *item) const
{
item->fix_arg_double();
static const Type_std_attributes attr(8, 0/*dec*/, true/*unsigned*/,
DTCollation_numeric::singleton());
item->fix_arg_int(&type_handler_long, &attr); // 10.5 merge: fix to *_ulong
return false;
}
@ -5831,10 +5839,13 @@ bool Type_handler_decimal_result::
}
bool Type_handler_temporal_result::
bool Type_handler_date_common::
Item_func_int_val_fix_length_and_dec(Item_func_int_val *item) const
{
item->fix_length_and_dec_int_or_decimal();
static const Type_std_attributes attr(8, 0/*dec*/, true/*unsigned*/,
DTCollation_numeric::singleton());
item->Type_std_attributes::set(attr);
item->set_handler(&type_handler_long); // 10.5 merge: fix to *_ulong
return false;
}