Bug #105509 DECIMAL results are truncated without errors when using derived table
Submitted: 10 Nov 2021 1:59 Modified: 10 Nov 2021 6:00
Reporter: Xiaodi Z Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: DML Severity:S2 (Serious)
Version:8.0.25, 8.0.27, 5.7.35 OS:Any
Assigned to: CPU Architecture:Any
Tags: decimal, derived table, overflow

[10 Nov 2021 1:59] Xiaodi Z
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.
[10 Nov 2021 6:00] MySQL Verification Team
Hello Xiaodi Z,

Thank you for the report and test case.

regards,
Umesh