1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

Merge pull request #1851 from mariadb-corporation/bar-develop-MCOL-4668

MCOL-4668 PERIOD_DIFF(dec_or_double1,dec_or_double2) is not as in InnoDB
This commit is contained in:
Gagan Goel
2021-04-07 02:12:50 -04:00
committed by GitHub
3 changed files with 129 additions and 127 deletions

View File

@ -0,0 +1,40 @@
#
# MCOL-4668 PERIOD_DIFF(dec_or_double1,dec_or_double2) is not as in InnoDB
#
# Narrow decimal rounding
CREATE TABLE t1 (a DECIMAL(18,1));
INSERT INTO t1 VALUES (200101.9);
SELECT PERIOD_DIFF(a, 200101) FROM t1;
PERIOD_DIFF(a, 200101)
1
DROP TABLE t1;
# Wide decimal rounding
CREATE TABLE t1 (a DECIMAL(30,1));
INSERT INTO t1 VALUES (200101.9);
SELECT PERIOD_DIFF(a, 200101) FROM t1;
PERIOD_DIFF(a, 200101)
1
DROP TABLE t1;
# Huge narrow decimal
CREATE TABLE t1 (a DECIMAL(18,0));
INSERT INTO t1 VALUES (999999999999999999);
SELECT a, PERIOD_DIFF(200101,a) FROM t1;
a PERIOD_DIFF(200101,a)
999999999999999999 24012
DROP TABLE t1;
# Huge wide decimal
CREATE TABLE t1 (a DECIMAL(30,0));
INSERT INTO t1 VALUES (9223372036854775807);
SELECT a, PERIOD_DIFF(200101,a) FROM t1;
a PERIOD_DIFF(200101,a)
9223372036854775807 24012
DROP TABLE t1;
# Huge double
CREATE TABLE t1 (a DOUBLE);
INSERT INTO t1 VALUES (9223372036854775807.0-1000);
INSERT INTO t1 VALUES (9223372036854775807.0+1000);
SELECT a, PERIOD_DIFF(200101,a) FROM t1 ORDER BY 2;
a PERIOD_DIFF(200101,a)
9.223372036854775e18 24012
9.223372036854776e18 24012
DROP TABLE t1;

View File

@ -0,0 +1,43 @@
--source ../include/have_columnstore.inc
--source ../include/combinations.myisam-columnstore.inc
--echo #
--echo # MCOL-4668 PERIOD_DIFF(dec_or_double1,dec_or_double2) is not as in InnoDB
--echo #
--echo # Narrow decimal rounding
CREATE TABLE t1 (a DECIMAL(18,1));
INSERT INTO t1 VALUES (200101.9);
SELECT PERIOD_DIFF(a, 200101) FROM t1;
DROP TABLE t1;
--echo # Wide decimal rounding
CREATE TABLE t1 (a DECIMAL(30,1));
INSERT INTO t1 VALUES (200101.9);
SELECT PERIOD_DIFF(a, 200101) FROM t1;
DROP TABLE t1;
--echo # Huge narrow decimal
CREATE TABLE t1 (a DECIMAL(18,0));
INSERT INTO t1 VALUES (999999999999999999);
SELECT a, PERIOD_DIFF(200101,a) FROM t1;
DROP TABLE t1;
--echo # Huge wide decimal
CREATE TABLE t1 (a DECIMAL(30,0));
INSERT INTO t1 VALUES (9223372036854775807);
SELECT a, PERIOD_DIFF(200101,a) FROM t1;
DROP TABLE t1;
--echo # Huge double
CREATE TABLE t1 (a DOUBLE);
INSERT INTO t1 VALUES (9223372036854775807.0-1000);
INSERT INTO t1 VALUES (9223372036854775807.0+1000);
SELECT a, PERIOD_DIFF(200101,a) FROM t1 ORDER BY 2;
DROP TABLE t1;

View File

@ -38,11 +38,11 @@ namespace funcexp
{
#define YY_PART_YEAR 70
inline int64_t convert_period_to_month(int64_t period)
inline uint64_t convert_period_to_month(uint64_t period)
{
int64_t a, b;
uint64_t a, b;
if (period == 0)
if (period == 0 || period > 999912)
return 0L;
if ((a = period / 100) < YY_PART_YEAR)
@ -55,144 +55,63 @@ inline int64_t convert_period_to_month(int64_t period)
}
int64_t getArgSInt64Val(rowgroup::Row& row, TreeNode *exp, bool& isNull)
{
switch (exp->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
case execplan::CalpontSystemCatalog::TIMESTAMP:
return exp->getIntVal(row, isNull);
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = exp->getDecimalVal(row, isNull);
return d.toSInt64Round();
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
return atoi(exp->getStrVal(row, isNull).c_str());
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
datatypes::TDouble d(exp->getDoubleVal(row, isNull));
return d.toMCSSInt64Round();
}
default:
isNull = true;
}
return 0;
}
CalpontSystemCatalog::ColType Func_period_diff::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
}
int64_t Func_period_diff::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t period1 = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
case execplan::CalpontSystemCatalog::TIMESTAMP:
{
period1 = parm[0]->data()->getIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
if (parm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
{
int128_t scaleDivisor;
datatypes::getScaleDivisor(scaleDivisor, d.scale);
int128_t tmpval = d.s128Value / scaleDivisor;
if (tmpval > static_cast<int128_t>(INT64_MAX))
tmpval = INT64_MAX;
else if (tmpval < static_cast<int128_t>(INT64_MIN))
tmpval = INT64_MIN;
period1 = tmpval;
}
else
{
period1 = d.value / pow(10.0, d.scale);
}
break;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
period1 = atoi(parm[0]->data()->getStrVal(row, isNull).c_str());
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
period1 = (int64_t) parm[0]->data()->getDoubleVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
uint64_t period1 = (uint64_t) getArgSInt64Val(row, parm[0]->data(), isNull);
if (isNull)
return 0;
int64_t period2 = 0;
switch (parm[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
case execplan::CalpontSystemCatalog::TIMESTAMP:
{
period2 = parm[1]->data()->getIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
if (parm[1]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
{
int128_t scaleDivisor;
datatypes::getScaleDivisor(scaleDivisor, d.scale);
int128_t tmpval = d.s128Value / scaleDivisor;
if (tmpval > static_cast<int128_t>(INT64_MAX))
tmpval = INT64_MAX;
else if (tmpval < static_cast<int128_t>(INT64_MIN))
tmpval = INT64_MIN;
period2 = tmpval;
}
else
{
period2 = d.value / pow(10.0, d.scale);
}
break;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
period2 = atoi(parm[1]->data()->getStrVal(row, isNull).c_str());
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
period2 = (int64_t) parm[1]->data()->getDoubleVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
uint64_t period2 = (uint64_t) getArgSInt64Val(row, parm[1]->data(), isNull);
if (isNull)
return 0;