Details
- 
    Bug 
- 
    Status: Closed (View Workflow)
- 
    Major 
- 
    Resolution: Fixed
- 
    5.5.1, 5.6.1, 6.1.1
- 
    None
- 
        2021-5
Description
The code for the DECIMAL data type in TreeNode::getUintVal() performs calculations in double format. This approach looses precision for huge numbers.
| case CalpontSystemCatalog::DECIMAL: | 
| case CalpontSystemCatalog::UDECIMAL: | 
|         { | 
| return (uint64_t)(fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale)); | 
|         }
 | 
| DROP TABLE IF EXISTS t1; | 
| CREATE TABLE t1 (a DECIMAL(18,0)) ENGINE=ColumnStore; | 
| INSERT INTO t1 VALUES (9999999999999999); | 
| INSERT INTO t1 VALUES (99999999999999998); | 
| INSERT INTO t1 VALUES (999999999999999997); | 
| SELECT a, CAST(a DIV 1 AS UNSIGNED) FROM t1; | 
| +--------------------+---------------------------+ | 
| | a                  | CAST(a DIV 1 AS UNSIGNED) | | 
| +--------------------+---------------------------+ | 
| |   9999999999999999 |         10000000000000000 | | 
| |  99999999999999998 |        100000000000000000 | | 
| | 999999999999999997 |       1000000000000000000 | | 
| +--------------------+---------------------------+
 | 
Looks wrong. Values in the first and the second columns are expected to be equal.
Note:
- the problem is repeatable for narrow decimal in 5.5 and 5.6
- the problem is not repeatable for wide decimal in 5.6:
DROP TABLE IF EXISTS t1; CREATE TABLE t1 (a DECIMAL(30,0)) ENGINE=ColumnStore; INSERT INTO t1 VALUES (9999999999999999); INSERT INTO t1 VALUES (99999999999999998); INSERT INTO t1 VALUES (999999999999999997); SELECT a, CAST(a DIV 1 AS UNSIGNED) FROM t1; +--------------------+---------------------------+| a | CAST(a DIV 1 AS UNSIGNED) |+--------------------+---------------------------+| 9999999999999999 | 9999999999999999 || 99999999999999998 | 99999999999999998 || 999999999999999997 | 999999999999999997 |+--------------------+---------------------------+