diff --git a/dbcon/execplan/treenode.h b/dbcon/execplan/treenode.h index e319c95ba..25554b2ea 100644 --- a/dbcon/execplan/treenode.h +++ b/dbcon/execplan/treenode.h @@ -721,16 +721,7 @@ inline int64_t TreeNode::getIntVal() case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: - { - if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH) - { - return static_cast(fResult.decimalVal.getIntegralPart()); - } - else - { - return (int64_t)(fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale)); - } - } + return fResult.decimalVal.toSInt64Round(); case CalpontSystemCatalog::DATE: case CalpontSystemCatalog::DATETIME: @@ -775,16 +766,7 @@ inline uint64_t TreeNode::getUintVal() case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: - { - if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH) - { - return static_cast(fResult.decimalVal.getIntegralPart()); - } - else - { - return (uint64_t)(fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale)); - } - } + return fResult.decimalVal.toUInt64Round(); case CalpontSystemCatalog::DATE: case CalpontSystemCatalog::DATETIME: diff --git a/mtr/basic/r/type_decimal.result b/mtr/basic/r/type_decimal.result index c223ef3a9..2ba3eb861 100644 --- a/mtr/basic/r/type_decimal.result +++ b/mtr/basic/r/type_decimal.result @@ -3582,3 +3582,126 @@ a CAST(a AS UNSIGNED) CAST(a AS SIGNED) -9.49999999999999999 0 -9 9.49999999999999999 9 9 DROP TABLE t1; +# +# MCOL-4609 TreeNode::getIntVal() does not round: implicit DECIMAL->INT cast is not MariaDB compatible +# +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (1.4),(1.5); +SELECT a, RAND(a), RAND(CAST(a AS DECIMAL(10,1))) FROM t1; +a RAND(a) RAND(CAST(a AS DECIMAL(10,1))) +1.4 0.40540353712197724 0.40540353712197724 +1.5 0.6555866465490187 0.6555866465490187 +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(30,1)); +INSERT INTO t1 VALUES (1.4),(1.5); +SELECT a, RAND(a), RAND(CAST(a AS DECIMAL(10,1))) FROM t1; +a RAND(a) RAND(CAST(a AS DECIMAL(10,1))) +1.4 0.40540353712197724 0.40540353712197724 +1.5 0.6555866465490187 0.6555866465490187 +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (1.4),(1.5); +SELECT TRUNCATE(1.2345, a) FROM t1; +TRUNCATE(1.2345, a) +1.2000 +1.2300 +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(30,1)); +INSERT INTO t1 VALUES (1.4),(1.5); +SELECT TRUNCATE(1.2345, a) FROM t1; +TRUNCATE(1.2345, a) +1.2000 +1.2300 +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (15.4),(15.5),(16.0); +SELECT a, CONV(16,a,10) FROM t1; +a CONV(16,a,10) +15.4 21 +15.5 22 +16.0 22 +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(30,1)); +INSERT INTO t1 VALUES (15.4),(15.5),(16.0); +SELECT a, CONV(16,a,10) FROM t1; +a CONV(16,a,10) +15.4 21 +15.5 22 +16.0 22 +DROP TABLE t1; +# +# MCOL-4610 TreeNode::getUintVal() looses precision for narrow decimal +# +CREATE TABLE t1 (a DECIMAL(18,0)); +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 +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(30,0)); +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 +DROP TABLE t1; +# +# MCOL-4619 TreeNode::getUintVal() does not round: Implicit DECIMAL->UINT conversion is not like in InnoDB +# +CREATE TABLE t1 (a VARCHAR(32), d DECIMAL(10,1)); +INSERT INTO t1 VALUES ('aaaa', 1.5); +SELECT LEFT(a, d) FROM t1; +LEFT(a, d) +aa +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(32), d DECIMAL(30,1)); +INSERT INTO t1 VALUES ('aaaa', 1.5); +SELECT LEFT(a, d) FROM t1; +LEFT(a, d) +aa +DROP TABLE t1; +# +# MCOL-4650 TreeNode::getIntVal() looses precision for narrow decimal +# +CREATE TABLE t1 (a DECIMAL(18,0)); +INSERT INTO t1 VALUES (9999999999999999); +INSERT INTO t1 VALUES (99999999999999998); +INSERT INTO t1 VALUES (999999999999999997); +SELECT RAND(a) FROM t1; +RAND(a) +0.8896564653978277 +0.5010456205355428 +0.866585171657228 +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(30,0)); +INSERT INTO t1 VALUES (9999999999999999); +INSERT INTO t1 VALUES (99999999999999998); +INSERT INTO t1 VALUES (999999999999999997); +SELECT RAND(a) FROM t1; +RAND(a) +0.8896564653978277 +0.5010456205355428 +0.866585171657228 +DROP TABLE t1; +# +# MCOL-4651 SEC_TO_TIME(hugePositiveDecimal) returns a negative time +# +CREATE TABLE t1 (a DECIMAL(30,1)); +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 +DROP TABLE t1; diff --git a/mtr/basic/t/type_decimal.test b/mtr/basic/t/type_decimal.test index 44f273a6c..0dfac810c 100644 --- a/mtr/basic/t/type_decimal.test +++ b/mtr/basic/t/type_decimal.test @@ -229,3 +229,108 @@ INSERT INTO t1 VALUES (9.49999999999999999); SELECT a, CAST(a AS UNSIGNED), CAST(a AS SIGNED) FROM t1; --enable_warnings DROP TABLE t1; + + +--echo # +--echo # MCOL-4609 TreeNode::getIntVal() does not round: implicit DECIMAL->INT cast is not MariaDB compatible +--echo # + +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (1.4),(1.5); +SELECT a, RAND(a), RAND(CAST(a AS DECIMAL(10,1))) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DECIMAL(30,1)); +INSERT INTO t1 VALUES (1.4),(1.5); +SELECT a, RAND(a), RAND(CAST(a AS DECIMAL(10,1))) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (1.4),(1.5); +SELECT TRUNCATE(1.2345, a) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DECIMAL(30,1)); +INSERT INTO t1 VALUES (1.4),(1.5); +SELECT TRUNCATE(1.2345, a) FROM t1; +DROP TABLE t1; + + +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (15.4),(15.5),(16.0); +SELECT a, CONV(16,a,10) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DECIMAL(30,1)); +INSERT INTO t1 VALUES (15.4),(15.5),(16.0); +SELECT a, CONV(16,a,10) FROM t1; +DROP TABLE t1; + + +--echo # +--echo # MCOL-4610 TreeNode::getUintVal() looses precision for narrow decimal +--echo # + +CREATE TABLE t1 (a DECIMAL(18,0)); +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; +DROP TABLE t1; + +CREATE TABLE t1 (a DECIMAL(30,0)); +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; +DROP TABLE t1; + + +--echo # +--echo # MCOL-4619 TreeNode::getUintVal() does not round: Implicit DECIMAL->UINT conversion is not like in InnoDB +--echo # + +CREATE TABLE t1 (a VARCHAR(32), d DECIMAL(10,1)); +INSERT INTO t1 VALUES ('aaaa', 1.5); +SELECT LEFT(a, d) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(32), d DECIMAL(30,1)); +INSERT INTO t1 VALUES ('aaaa', 1.5); +SELECT LEFT(a, d) FROM t1; +DROP TABLE t1; + + +--echo # +--echo # MCOL-4650 TreeNode::getIntVal() looses precision for narrow decimal +--echo # + +CREATE TABLE t1 (a DECIMAL(18,0)); +INSERT INTO t1 VALUES (9999999999999999); +INSERT INTO t1 VALUES (99999999999999998); +INSERT INTO t1 VALUES (999999999999999997); +SELECT RAND(a) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DECIMAL(30,0)); +INSERT INTO t1 VALUES (9999999999999999); +INSERT INTO t1 VALUES (99999999999999998); +INSERT INTO t1 VALUES (999999999999999997); +SELECT RAND(a) FROM t1; +DROP TABLE t1; + + +--echo # +--echo # MCOL-4651 SEC_TO_TIME(hugePositiveDecimal) returns a negative time +--echo # + +CREATE TABLE t1 (a DECIMAL(30,1)); +INSERT INTO t1 VALUES (9223372036854775807.0); +INSERT INTO t1 VALUES (9223372036854775807.5); +INSERT INTO t1 VALUES (18446744073709551615.0); +INSERT INTO t1 VALUES (18446744073709551615.5); +--disable_warnings +--replace_result 838:59:59.0 838:59:59.9 +SELECT a, SEC_TO_TIME(a) FROM t1 ORDER BY a; +--enable_warnings +DROP TABLE t1; diff --git a/utils/funcexp/func_cast.cpp b/utils/funcexp/func_cast.cpp index b6fcd73ca..3a6c28f32 100644 --- a/utils/funcexp/func_cast.cpp +++ b/utils/funcexp/func_cast.cpp @@ -1120,18 +1120,11 @@ int64_t Func_cast_decimal::getIntVal(Row& row, bool& isNull, CalpontSystemCatalog::ColType& operationColType) { - IDB_Decimal decimal = Func_cast_decimal::getDecimalVal(row, parm, isNull, operationColType); - - if (decimal.isTSInt128ByPrecision()) - { - return static_cast(decimal.getIntegralPart()); - } - - return (int64_t) decimal.value / helpers::powerOf10_c[decimal.scale]; + return decimal.toSInt64Round(); } diff --git a/utils/funcexp/func_sec_to_time.cpp b/utils/funcexp/func_sec_to_time.cpp index f4a9af8ad..8d5594ca8 100644 --- a/utils/funcexp/func_sec_to_time.cpp +++ b/utils/funcexp/func_sec_to_time.cpp @@ -121,28 +121,8 @@ string Func_sec_to_time::getStrVal(rowgroup::Row& row, 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; + val = parm[0]->data()->getDecimalVal(row, isNull).toSInt64Round(); + break; case execplan::CalpontSystemCatalog::CHAR: case execplan::CalpontSystemCatalog::VARCHAR: