mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Bug #45261 : Crash, stored procedure + decimal
Bug #48370 Absolutely wrong calculations with GROUP BY and decimal fields when using IF Added the test cases in the above two bugs for regression testing. Added additional tests that demonstrate a incomplete fix. Added a new factory method for Field_new_decimal to create a field from an (decimal returning) Item. In the new method made sure that all the precision and length variables are capped in a proper way. This is required because Item's can have larger precision than the decimal fields and thus need to be capped when creating a field based on an Item type. Fixed the wrong typecast to Item_decimal.
This commit is contained in:
@@ -9466,47 +9466,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
|
||||
new_field->set_derivation(item->collation.derivation);
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
uint8 dec= item->decimals;
|
||||
uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
|
||||
uint32 len= item->max_length;
|
||||
|
||||
/*
|
||||
Trying to put too many digits overall in a DECIMAL(prec,dec)
|
||||
will always throw a warning. We must limit dec to
|
||||
DECIMAL_MAX_SCALE however to prevent an assert() later.
|
||||
*/
|
||||
|
||||
if (dec > 0)
|
||||
{
|
||||
signed int overflow;
|
||||
|
||||
dec= min(dec, DECIMAL_MAX_SCALE);
|
||||
|
||||
/*
|
||||
If the value still overflows the field with the corrected dec,
|
||||
we'll throw out decimals rather than integers. This is still
|
||||
bad and of course throws a truncation warning.
|
||||
+1: for decimal point
|
||||
*/
|
||||
|
||||
const int required_length=
|
||||
my_decimal_precision_to_length(intg + dec, dec,
|
||||
item->unsigned_flag);
|
||||
|
||||
overflow= required_length - len;
|
||||
|
||||
if (overflow > 0)
|
||||
dec= max(0, dec - overflow); // too long, discard fract
|
||||
else
|
||||
/* Corrected value fits. */
|
||||
len= required_length;
|
||||
}
|
||||
|
||||
new_field= new Field_new_decimal(len, maybe_null, item->name,
|
||||
dec, item->unsigned_flag);
|
||||
new_field= Field_new_decimal::create_from_item(item);
|
||||
break;
|
||||
}
|
||||
case ROW_RESULT:
|
||||
default:
|
||||
// This case should never be choosen
|
||||
|
||||
Reference in New Issue
Block a user