diff options
author | Georgi Kodinov <joro@sun.com> | 2009-11-20 12:10:47 +0200 |
---|---|---|
committer | Georgi Kodinov <joro@sun.com> | 2009-11-20 12:10:47 +0200 |
commit | c2c334918f31e64bfc1ed253cd70744a0a350cc8 (patch) | |
tree | 6dd67d2e2233b91b60411032a36b63de5922949d /sql/sql_select.cc | |
parent | 3f6825653e789ca66adebeb01642457a7447fc73 (diff) | |
download | mariadb-git-c2c334918f31e64bfc1ed253cd70744a0a350cc8.tar.gz |
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.
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 41 |
1 files changed, 1 insertions, 40 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 18fc3b20748..569d8183ab6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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 |