Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
5.6.1, 6.1.1
-
None
Description
DROP TABLE IF EXISTS t1; |
CREATE TABLE t1 (a DECIMAL(30,1)) ENGINE=ColumnStore; |
INSERT INTO t1 VALUES (9223372036854775807.0); |
INSERT INTO t1 VALUES (9223372036854775807.5); |
INSERT INTO t1 VALUES (18446744073709551615.0); |
INSERT INTO t1 VALUES (18446744073709551615.5); |
SELECT a, SEC_TO_TIME(a) FROM t1 ORDER BY a; |
+------------------------+----------------+
|
| a | SEC_TO_TIME(a) |
|
+------------------------+----------------+
|
| 9223372036854775807.0 | 838:59:59.0 |
|
| 9223372036854775807.5 | -838:59:59.0 | -- bad
|
| 18446744073709551615.0 | 838:59:59.0 |
|
| 18446744073709551615.5 | -838:59:59.0 | -- bad
|
+------------------------+----------------+
|
Looks wrong. The correct result is:
DROP TABLE IF EXISTS t1; |
CREATE TABLE t1 (a DECIMAL(30,1)) ENGINE=InnoDB; |
INSERT INTO t1 VALUES (9223372036854775807.0); |
INSERT INTO t1 VALUES (9223372036854775807.5); |
INSERT INTO t1 VALUES (18446744073709551615.0); |
INSERT INTO t1 VALUES (18446744073709551615.5); |
SELECT a, SEC_TO_TIME(a) FROM t1 ORDER BY a; |
+------------------------+----------------+
|
| a | SEC_TO_TIME(a) |
|
+------------------------+----------------+
|
| 9223372036854775807.0 | 838:59:59.9 |
|
| 9223372036854775807.5 | 838:59:59.9 |
|
| 18446744073709551615.0 | 838:59:59.9 |
|
| 18446744073709551615.5 | 838:59:59.9 |
|
+------------------------+----------------+
|
Note, the microsecond value is zero in MCS because of MCOL-4608.
But at least the integer part should be fixed not to return negative values.
The problem reside in Func_sec_to_time::getStrVal():
case execplan::CalpontSystemCatalog::DECIMAL: |
case execplan::CalpontSystemCatalog::UDECIMAL: |
{
|
const string& valStr = parm[0]->data()->getStrVal(row, isNull); |
|
val = parm[0]->data()->getIntVal(row, isNull);
|
size_t x = valStr.find("."); |
|
if (x < string::npos) |
{
|
string tmp = valStr.substr(x + 1, 1);
|
char* ptr = &tmp[0]; |
int i = atoi(ptr); |
|
if (i >= 5) |
{
|
if (val > 0) |
val += 1;
|
else |
val -= 1;
|
}
|
}
|
}
|
break; |
The above code performs rounding without checking the range properly. So a huge positive integer, e.g. 9223372036854775807 wraps around to a negative value.
Attachments
Issue Links
- blocks
-
MCOL-4361 Replace pow(10.0, (double)scale) expressions with a static dictionary lookup.
- Closed