Description:
DECIMAL results are truncated without errors or warnings when using derived table
How to repeat:
create table t(t1 decimal(65,30));
insert into t values(99999999999999999999999999999999999.999999999999999999999999999999), (99999999999999999999999999999999999.999999999999999999999999999999);
1.
mysql> select * from (select 1+99999999999999999999999999999999999.999999999999999999999999999999);
+----------------------------------------------------------------------+
| 1+99999999999999999999999999999999999.999999999999999999999999999999 |
+----------------------------------------------------------------------+
| 99999999999999999999999999999999999.999999999999999999999999999999 |
+----------------------------------------------------------------------+
1 row in set (0.00 sec)
2.
mysql> select * from (select sum(t1) from t);
+--------------------------------------------------------------------+
| sum(t1) |
+--------------------------------------------------------------------+
| 99999999999999999999999999999999999.999999999999999999999999999999 |
+--------------------------------------------------------------------+
1 row in set (0.01 sec)
3.
mysql> set optimizer_switch='derived_merge=on';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from (select t1+99999999999999999999999999999999999.999999999999999999999999999999 from t);
+-----------------------------------------------------------------------+
| t1+99999999999999999999999999999999999.999999999999999999999999999999 |
+-----------------------------------------------------------------------+
| 199999999999999999999999999999999999.999999999999999999999999999998 |
| 199999999999999999999999999999999999.999999999999999999999999999998 |
+-----------------------------------------------------------------------+
2 rows in set (0.00 sec)
4.
mysql> set optimizer_switch='derived_merge=off';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from (select t1+99999999999999999999999999999999999.999999999999999999999999999999 from t);
+-----------------------------------------------------------------------+
| t1+99999999999999999999999999999999999.999999999999999999999999999999 |
+-----------------------------------------------------------------------+
| 99999999999999999999999999999999999.999999999999999999999999999999 |
| 99999999999999999999999999999999999.999999999999999999999999999999 |
+-----------------------------------------------------------------------+
2 rows in set (0.00 sec)
Suggested fix:
Example 1, 2, 4 return truncated results without warnings or errors when using derived table. Actually, function my_decimal2binary (called by Field_new_decimal::store_value) ignore the overflow error and only return E_DEC_OVERFLOW, but the return value is discarded.
In addition, Example 3, 4 return different results only due to different variable settings, this is obviously unsuitable.
This question is related with Bug #103278. I want to know whether the following way is feasible if only a warning is required?
my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, decimal_value, ptr, precision, dec) ->
my_decimal2binary(E_DEC_FATAL_ERROR, decimal_value, ptr, precision, dec);
Is there any better way? Thank you very much.