Merge mysql.com:/misc/mysql/24907/50-24907

into  mysql.com:/misc/mysql/24907/51-24907
parents dfe6c177 6889c829
......@@ -1509,6 +1509,26 @@ SELECT 1 FROM t1 GROUP BY @b := @a, @b;
1
1
DROP TABLE t1;
CREATE TABLE t1 SELECT 0.123456789012345678901234567890123456 AS f1;
Warnings:
Note 1265 Data truncated for column 'f1' at row 1
DESC t1;
Field Type Null Key Default Extra
f1 decimal(31,30) NO 0.000000000000000000000000000000
SELECT f1 FROM t1;
f1
0.123456789012345678901234567890
DROP TABLE t1;
CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
Warnings:
Warning 1264 Out of range value adjusted for column 'f1' at row 1
DESC t1;
Field Type Null Key Default Extra
f1 decimal(59,30) NO 0.000000000000000000000000000000
SELECT f1 FROM t1;
f1
99999999999999999999999999999.999999999999999999999999999999
DROP TABLE t1;
End of 5.0 tests
select cast(143.481 as decimal(4,1));
cast(143.481 as decimal(4,1))
......
......@@ -1205,6 +1205,27 @@ SELECT 1 FROM t1 GROUP BY @b := @a, @b;
DROP TABLE t1;
#
# Bug #24907: unpredictable (display) precission, if input precission
# increases
#
# As per 10.1.1. Overview of Numeric Types, type (new) DECIMAL has a
# maxmimum precision of 30 places after the decimal point. Show that
# temp field creation beyond that works and throws a truncation warning.
# DECIMAL(37,36) should be adjusted to DECIMAL(31,30).
CREATE TABLE t1 SELECT 0.123456789012345678901234567890123456 AS f1;
DESC t1;
SELECT f1 FROM t1;
DROP TABLE t1;
# too many decimal places, AND too many digits altogether (90 = 45+45).
# should preserve integers (65 = 45+20)
CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
DESC t1;
SELECT f1 FROM t1;
DROP TABLE t1;
--echo End of 5.0 tests
#
......
......@@ -9185,9 +9185,43 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
new_field->set_derivation(item->collation.derivation);
break;
case DECIMAL_RESULT:
new_field= new Field_new_decimal(item->max_length, maybe_null, item->name,
item->decimals, item->unsigned_flag);
{
uint8 dec= item->decimals;
uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
uint8 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
*/
overflow= my_decimal_precision_to_length(intg + dec, dec,
item->unsigned_flag) - len;
if (overflow > 0)
dec= max(0, dec - overflow); // too long, discard fract
else
len -= item->decimals - dec; // corrected value fits
}
new_field= new Field_new_decimal(len, maybe_null, item->name,
table, dec, item->unsigned_flag);
break;
}
case ROW_RESULT:
default:
// This case should never be choosen
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment