1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-29 08:21:15 +03:00

MCOL-641 Add support for functions (Part 1).

This commit is contained in:
Gagan Goel
2020-04-19 23:27:43 -04:00
committed by Roman Nozdrin
parent 554c6da8e8
commit cfe35b5c7f
28 changed files with 2102 additions and 462 deletions

View File

@ -256,14 +256,24 @@ public:
(datatypes::Decimal::isWideDecimalType(decimal.precision)) ?
decimal.s128Value : decimal.value;
int128_t scaleMultiplier, result;
int128_t scaleMultiplier;
int32_t scaleDiff = fResultType.scale - decimal.scale;
datatypes::getScaleDivisor(scaleMultiplier, abs(scaleDiff));
// WIP MCOL-641 Unconditionall overflow check
datatypes::MultiplicationOverflowCheck mul;
decimal.s128Value = (scaleDiff > 0
&& mul(decimal.s128Value, scaleMultiplier, result))
? result : decimal.s128Value / scaleMultiplier;
if (scaleMultiplier > 1)
{
if (scaleDiff > 0)
{
// WIP MCOL-641 Unconditionall overflow check
datatypes::MultiplicationNoOverflowCheck mul;
mul(decimal.s128Value, scaleMultiplier, decimal.s128Value);
}
else
{
decimal.s128Value = (int128_t)(decimal.s128Value > 0 ?
(__float128)decimal.s128Value / scaleMultiplier + 0.5 :
(__float128)decimal.s128Value / scaleMultiplier - 0.5);
}
}
}
else if (fResultType.colWidth == utils::MAXLEGACYWIDTH)
{

View File

@ -63,17 +63,16 @@ typedef execplan::CalpontSystemCatalog::ColType Type;
*/
struct IDB_Decimal
{
IDB_Decimal(): value(0), scale(0), precision(0)
IDB_Decimal(): s128Value(0), value(0), scale(0), precision(0)
{
s128Value = 0;
}
IDB_Decimal(int64_t val, int8_t s, uint8_t p) :
value (val),
IDB_Decimal(int64_t val, int8_t s, uint8_t p, int128_t val128 = 0) :
s128Value(val128),
value(val),
scale(s),
precision(p)
{
s128Value = 0;
}
int decimalComp(const IDB_Decimal& d) const
@ -117,13 +116,32 @@ struct IDB_Decimal
bool operator==(const IDB_Decimal& rhs) const
{
if (utils::widthByPrecision(precision) == 16)
if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return s128Value == rhs.s128Value;
else
return (datatypes::Decimal::compare(*this, rhs) == 0);
}
else if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision <= datatypes::INT64MAXPRECISION)
{
const_cast<IDB_Decimal&>(rhs).s128Value = rhs.value;
if (scale == rhs.scale)
return s128Value == rhs.s128Value;
else
return (datatypes::Decimal::compare(*this, rhs) == 0);
}
else if (precision <= datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return (int128_t) value == rhs.s128Value;
else
return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) == 0);
}
else
{
if (scale == rhs.scale)
@ -135,13 +153,32 @@ struct IDB_Decimal
bool operator>(const IDB_Decimal& rhs) const
{
if (utils::widthByPrecision(precision) == 16)
if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return s128Value > rhs.s128Value;
else
return (datatypes::Decimal::compare(*this, rhs) > 0);
}
else if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision <= datatypes::INT64MAXPRECISION)
{
IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value);
if (scale == rhstmp.scale)
return s128Value > rhstmp.s128Value;
else
return (datatypes::Decimal::compare(*this, rhstmp) > 0);
}
else if (precision <= datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return (int128_t) value > rhs.s128Value;
else
return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) > 0);
}
else
{
if (scale == rhs.scale)
@ -153,13 +190,32 @@ struct IDB_Decimal
bool operator<(const IDB_Decimal& rhs) const
{
if (utils::widthByPrecision(precision) == 16)
if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return s128Value < rhs.s128Value;
else
return (datatypes::Decimal::compare(*this, rhs) < 0);
}
else if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision <= datatypes::INT64MAXPRECISION)
{
IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value);
if (scale == rhstmp.scale)
return s128Value < rhstmp.s128Value;
else
return (datatypes::Decimal::compare(*this, rhstmp) < 0);
}
else if (precision <= datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return (int128_t) value < rhs.s128Value;
else
return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) < 0);
}
else
{
if (scale == rhs.scale)
@ -171,13 +227,32 @@ struct IDB_Decimal
bool operator>=(const IDB_Decimal& rhs) const
{
if (utils::widthByPrecision(precision) == 16)
if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return s128Value >= rhs.s128Value;
else
return (datatypes::Decimal::compare(*this, rhs) >= 0);
}
else if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision <= datatypes::INT64MAXPRECISION)
{
IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value);
if (scale == rhstmp.scale)
return s128Value >= rhstmp.s128Value;
else
return (datatypes::Decimal::compare(*this, rhstmp) >= 0);
}
else if (precision <= datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return (int128_t) value >= rhs.s128Value;
else
return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) >= 0);
}
else
{
if (scale == rhs.scale)
@ -189,13 +264,32 @@ struct IDB_Decimal
bool operator<=(const IDB_Decimal& rhs) const
{
if (utils::widthByPrecision(precision) == 16)
if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return s128Value <= rhs.s128Value;
else
return (datatypes::Decimal::compare(*this, rhs) <= 0);
}
else if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision <= datatypes::INT64MAXPRECISION)
{
IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value);
if (scale == rhstmp.scale)
return s128Value <= rhstmp.s128Value;
else
return (datatypes::Decimal::compare(*this, rhstmp) <= 0);
}
else if (precision <= datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return (int128_t) value <= rhs.s128Value;
else
return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) <= 0);
}
else
{
if (scale == rhs.scale)
@ -207,13 +301,32 @@ struct IDB_Decimal
bool operator!=(const IDB_Decimal& rhs) const
{
if (utils::widthByPrecision(precision) == 16)
if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return s128Value != rhs.s128Value;
else
return (datatypes::Decimal::compare(*this, rhs) != 0);
}
else if (precision > datatypes::INT64MAXPRECISION &&
rhs.precision <= datatypes::INT64MAXPRECISION)
{
IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value);
if (scale == rhstmp.scale)
return s128Value != rhstmp.s128Value;
else
return (datatypes::Decimal::compare(*this, rhstmp) != 0);
}
else if (precision <= datatypes::INT64MAXPRECISION &&
rhs.precision > datatypes::INT64MAXPRECISION)
{
if (scale == rhs.scale)
return (int128_t) value != rhs.s128Value;
else
return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) != 0);
}
else
{
if (scale == rhs.scale)
@ -308,7 +421,7 @@ struct Result
{
Result(): intVal(0), uintVal(0), origIntVal(0), dummy(0),
doubleVal(0), longDoubleVal(0), floatVal(0), boolVal(false),
strVal(""), decimalVal(IDB_Decimal(0, 0, 0)),
strVal(""), decimalVal(IDB_Decimal()),
valueConverted(false) {}
int64_t intVal;
uint64_t uintVal;
@ -783,7 +896,10 @@ inline const std::string& TreeNode::getStrVal(const std::string& timeZone)
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
dataconvert::DataConvert::decimalToString(fResult.decimalVal.value, fResult.decimalVal.scale, tmp, 22, fResultType.colDataType);
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
dataconvert::DataConvert::decimalToString(&fResult.decimalVal.s128Value, fResult.decimalVal.scale, tmp, utils::MAXLENGTH16BYTES, fResultType.colDataType);
else
dataconvert::DataConvert::decimalToString(fResult.decimalVal.value, fResult.decimalVal.scale, tmp, 22, fResultType.colDataType);
fResult.strVal = std::string(tmp);
break;
}
@ -880,7 +996,20 @@ inline int64_t TreeNode::getIntVal()
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
return (int64_t)(fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale));
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
{
int128_t scaleDivisor;
datatypes::getScaleDivisor(scaleDivisor, fResult.decimalVal.scale);
int128_t tmpval = fResult.decimalVal.s128Value / scaleDivisor;
return datatypes::Decimal::getInt64FromWideDecimal(tmpval);
}
else
{
return (int64_t)(fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale));
}
}
case CalpontSystemCatalog::DATE:
@ -1062,8 +1191,15 @@ inline double TreeNode::getDoubleVal()
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
// this may not be accurate. if this is problematic, change to pre-calculated power array.
return (double)(fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale));
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
{
return datatypes::Decimal::getDoubleFromWideDecimal(fResult.decimalVal.s128Value, fResult.decimalVal.scale);
}
else
{
// this may not be accurate. if this is problematic, change to pre-calculated power array.
return (double)(fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale));
}
}
case CalpontSystemCatalog::DATE: