Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
5.5.1, 5.6.1, 6.1.1
-
None
-
2021-5
Description
DROP TABLE IF EXISTS t1; |
CREATE TABLE t1 (a DECIMAL(18,17)) ENGINE=ColumnStore; |
INSERT INTO t1 VALUES (9.49999999999999999); |
SELECT a, CAST(a AS UNSIGNED), CAST(a AS SIGNED) FROM t1; |
+---------------------+---------------------+-------------------+
|
| a | CAST(a AS UNSIGNED) | CAST(a AS SIGNED) |
|
+---------------------+---------------------+-------------------+
|
| 9.49999999999999999 | 10 | 10 |
|
+---------------------+---------------------+-------------------+
|
The above looks wrong. If I change to ENGINE=InnoDB, it correctly returns:
+---------------------+---------------------+-------------------+
|
| a | CAST(a AS UNSIGNED) | CAST(a AS SIGNED) |
|
+---------------------+---------------------+-------------------+
|
| 9.49999999999999999 | 9 | 9 |
|
+---------------------+---------------------+-------------------+
|
The problem happens due to the precision loss in this code in Func_cast_unsigned::getUintVal():
}
|
else |
{
|
if (d.value < 0) |
{
|
return 0; |
}
|
|
double dscale = d.scale; |
|
uint64_t value = d.value / pow(10.0, dscale); |
int lefto = (d.value - value * pow(10.0, dscale)) / pow(10.0, dscale - 1); |
|
if ( utils::is_nonnegative(value) && lefto > 4 ) |
{
|
value++;
|
}
|
|
return value; |
}
|
Attachments
Issue Links
- blocks
-
MCOL-4361 Replace pow(10.0, (double)scale) expressions with a static dictionary lookup.
- Closed