1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-01 06:46:55 +03:00

MCOL-4188 Fix regressions in CEIL()/CHAR() for narrow decimals.

In addition, a regression in a WHERE clause with a WF field
as the LHS and an addition operation on two WF fields on the RHS
is also fixed. The issue was SimpleColumn::getDecimalVal() was
setting precision = 19, with the value of one of the operands of the
addition operation being set in VDecimal::value instead of
VDecimal::s128Value. addSubtractExecute() in mcs_decimal.cpp makes the
assumption that if precision > 18 and precision <= 38, we need to
fetch the wide s128Value, not the narrow value field. So we are
fixing the precision set in SimpleColumn::getDecimalVal().
This commit is contained in:
Gagan Goel
2020-11-09 18:45:22 -05:00
committed by Roman Nozdrin
parent 6fd7916c56
commit 007b8a5082
5 changed files with 44 additions and 36 deletions

View File

@ -335,20 +335,18 @@ public:
// the original decimal scale is stored in scale field, which is no use for double. // the original decimal scale is stored in scale field, which is no use for double.
if (fResultType.precision == -1) if (fResultType.precision == -1)
{ {
IDB_Decimal rv;
if (fResultType.colDataType == CalpontSystemCatalog::DOUBLE) if (fResultType.colDataType == CalpontSystemCatalog::DOUBLE)
{ {
rv.scale = fResultType.scale; IDB_Decimal rv(
rv.precision = 15; (int64_t)(TreeNode::getDoubleVal() * IDB_pow[fResultType.scale]),
rv.value = (int64_t)(TreeNode::getDoubleVal() * IDB_pow[rv.scale]); fResultType.scale, 15);
return rv; return rv;
} }
else if (fResultType.colDataType == CalpontSystemCatalog::LONGDOUBLE) else if (fResultType.colDataType == CalpontSystemCatalog::LONGDOUBLE)
{ {
IDB_Decimal rv; IDB_Decimal rv (
rv.scale = fResultType.scale; (int64_t)(TreeNode::getLongDoubleVal() * IDB_pow[fResultType.scale]),
rv.precision = 19; fResultType.scale, fResultType.precision);
rv.value = (int64_t)(TreeNode::getLongDoubleVal() * IDB_pow[rv.scale]);
return rv; return rv;
} }
} }

View File

@ -62,6 +62,9 @@ class IDB_Decimal: public datatypes::VDecimal
public: public:
using datatypes::VDecimal::VDecimal; using datatypes::VDecimal::VDecimal;
IDB_Decimal(int64_t val, int8_t s, uint8_t p, const int128_t &val128 = 0) :
VDecimal(val, s, p, val128) {}
inline void operator=(const datatypes::TSInt128& rhs) inline void operator=(const datatypes::TSInt128& rhs)
{ {
value = 0; scale = 0; precision = 0; value = 0; scale = 0; precision = 0;

View File

@ -640,8 +640,10 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull)
isNull = true; isNull = true;
else else
{ {
fResult.decimalVal.value = row.getIntField<1>(fInputIndex); fResult.decimalVal = IDB_Decimal(
fResult.decimalVal.scale = (unsigned)fResultType.scale; row.getIntField<1>(fInputIndex),
fResultType.scale,
fResultType.precision);
} }
break; break;
@ -653,8 +655,10 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull)
isNull = true; isNull = true;
else else
{ {
fResult.decimalVal.value = row.getIntField<2>(fInputIndex); fResult.decimalVal = IDB_Decimal(
fResult.decimalVal.scale = (unsigned)fResultType.scale; row.getIntField<2>(fInputIndex),
fResultType.scale,
fResultType.precision);
} }
break; break;
@ -666,8 +670,10 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull)
isNull = true; isNull = true;
else else
{ {
fResult.decimalVal.value = row.getIntField<4>(fInputIndex); fResult.decimalVal = IDB_Decimal(
fResult.decimalVal.scale = (unsigned)fResultType.scale; row.getIntField<4>(fInputIndex),
fResultType.scale,
fResultType.precision);
} }
break; break;
@ -679,8 +685,10 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull)
isNull = true; isNull = true;
else else
{ {
fResult.decimalVal.value = row.getIntField<8>(fInputIndex); fResult.decimalVal = IDB_Decimal(
fResult.decimalVal.scale = (unsigned)fResultType.scale; row.getIntField<8>(fInputIndex),
fResultType.scale,
fResultType.precision);
} }
break; break;
@ -688,13 +696,14 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull)
case 16: case 16:
{ {
datatypes::TSInt128 dec(row.getBinaryField<int128_t>(fInputIndex)); int128_t val;
if (dec == datatypes::Decimal128Null) row.getInt128Field(fInputIndex, val);
if (val == datatypes::Decimal128Null)
isNull = true; isNull = true;
else else
{ {
fResult.decimalVal = dec; fResult.decimalVal = IDB_Decimal(0, fResultType.scale, fResultType.precision, val);
fResult.decimalVal.scale = (unsigned)fResultType.scale;
} }
break; break;

View File

@ -75,6 +75,12 @@ int64_t Func_ceil::getIntVal(Row& row,
case execplan::CalpontSystemCatalog::DECIMAL: case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL: case execplan::CalpontSystemCatalog::UDECIMAL:
{ {
if (op_ct.scale == 0)
{
ret = parm[0]->data()->getIntVal(row, isNull);
break;
}
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull); IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull) if (isNull)
@ -222,6 +228,12 @@ uint64_t Func_ceil::getUintVal(Row& row,
case execplan::CalpontSystemCatalog::DECIMAL: case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL: case execplan::CalpontSystemCatalog::UDECIMAL:
{ {
if (op_ct.scale == 0)
{
ret = parm[0]->data()->getIntVal(row, isNull);
break;
}
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull); IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull) if (isNull)

View File

@ -134,7 +134,7 @@ string Func_char::getStrVal(Row& row,
case execplan::CalpontSystemCatalog::DECIMAL: case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL: case execplan::CalpontSystemCatalog::UDECIMAL:
{ {
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull); IDB_Decimal d = rc->getDecimalVal(row, isNull);
if (ct.colWidth == datatypes::MAXDECIMALWIDTH) if (ct.colWidth == datatypes::MAXDECIMALWIDTH)
{ {
@ -154,30 +154,16 @@ string Func_char::getStrVal(Row& row,
tmpval++; tmpval++;
value = datatypes::Decimal::getInt32FromWideDecimal(tmpval); value = datatypes::Decimal::getInt32FromWideDecimal(tmpval);
// WIP MCOL-641
/*if ( !getChar((int64_t)tmpval, buf) )
{
isNull = true;
return "";
}*/
} }
else else
{ {
double dscale = d.scale; double dscale = d.scale;
// get decimal and round up // get decimal and round up
int value = d.value / pow(10.0, dscale); value = d.value / pow(10.0, dscale);
int lefto = (d.value - value * pow(10.0, dscale)) / pow(10.0, dscale - 1); int lefto = (d.value - value * pow(10.0, dscale)) / pow(10.0, dscale - 1);
if ( lefto > 4 ) if ( lefto > 4 )
value++; value++;
// WIP MCOL-641
/*if ( !getChar((int64_t)value, buf) )
{
isNull = true;
return "";
}*/
} }
} }
break; break;