1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-08 14:22:09 +03:00

A join patch for MCOL-4609, MCOL-4610, MCOL-4619, MCOL-4650, MCOL-4651

This patch is fixing the following bugs:

- MCOL-4609 TreeNode::getIntVal() does not round: implicit DECIMAL->INT cast is not MariaDB compatible
- MCOL-4610 TreeNode::getUintVal() looses precision for narrow decimal
- MCOL-4619 TreeNode::getUintVal() does not round: Implicit DECIMAL->UINT conversion is not like in InnoDB
- MCOL-4650 TreeNode::getIntVal() looses precision for narrow decimal
- MCOL-4651 SEC_TO_TIME(hugePositiveDecimal) returns a negative time
This commit is contained in:
Alexander Barkov
2021-03-30 15:08:36 +04:00
parent cf46db946b
commit 30fe666a8f
5 changed files with 233 additions and 50 deletions

View File

@@ -721,16 +721,7 @@ inline int64_t TreeNode::getIntVal()
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
{
return static_cast<int64_t>(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<uint64_t>(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:

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<int64_t>(decimal.getIntegralPart());
}
return (int64_t) decimal.value / helpers::powerOf10_c[decimal.scale];
return decimal.toSInt64Round();
}

View File

@@ -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: