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

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

This commit is contained in:
Gagan Goel
2020-07-13 17:52:24 -04:00
committed by Roman Nozdrin
parent bd0d5af123
commit 6aea838360
50 changed files with 578 additions and 125 deletions

View File

@ -285,6 +285,45 @@ class Decimal
return static_cast<uint64_t>(value);
}
/**
@brief The method converts a wide decimal value to an uint32_t.
*/
static inline uint32_t getUInt32FromWideDecimal(const int128_t& value)
{
if (value > static_cast<int128_t>(UINT32_MAX))
return UINT32_MAX;
else if (value < 0)
return 0;
return static_cast<uint32_t>(value);
}
/**
@brief The method converts a wide decimal value to an int32_t.
*/
static inline int32_t getInt32FromWideDecimal(const int128_t& value)
{
if (value > static_cast<int128_t>(INT32_MAX))
return INT32_MAX;
else if (value < static_cast<int128_t>(INT32_MIN))
return INT32_MIN;
return static_cast<int32_t>(value);
}
/**
@brief The method converts a wide decimal value to an uint64_t.
*/
static inline uint64_t getUInt64FromWideDecimal(const int128_t& value)
{
if (value > static_cast<int128_t>(UINT64_MAX))
return UINT64_MAX;
else if (value < 0)
return 0;
return static_cast<uint64_t>(value);
}
/**
@brief The method converts a __float128 value to a double.
*/

View File

@ -236,7 +236,8 @@ ConstantColumn::ConstantColumn(const int64_t val, TYPE type) :
fResultType.colWidth = 8;
}
ConstantColumn::ConstantColumn(const uint64_t val, TYPE type) :
ConstantColumn::ConstantColumn(const uint64_t val, TYPE type,
int8_t scale, uint8_t precision) :
ReturnedColumn(),
fType(type)
{
@ -252,7 +253,8 @@ ConstantColumn::ConstantColumn(const uint64_t val, TYPE type) :
fResult.longDoubleVal = (long double)fResult.uintVal;
fResult.decimalVal.value = fResult.uintVal;
fResult.decimalVal.s128Value = fResult.uintVal;
fResult.decimalVal.scale = 0;
fResult.decimalVal.scale = scale;
fResult.decimalVal.precision = precision;
fResultType.colDataType = CalpontSystemCatalog::UBIGINT;
fResultType.colWidth = 8;
}

View File

@ -73,7 +73,8 @@ public:
/**
* ctor
*/
ConstantColumn(const uint64_t val, TYPE type = NUM); // deprecate
ConstantColumn(const uint64_t val, TYPE type = NUM,
int8_t scale = 0, uint8_t precision = 0); // deprecate
//There are more ctors below...
/**

View File

@ -259,11 +259,12 @@ public:
int128_t scaleMultiplier;
int32_t scaleDiff = fResultType.scale - decimal.scale;
datatypes::getScaleDivisor(scaleMultiplier, abs(scaleDiff));
if (scaleMultiplier > 1)
{
if (scaleDiff > 0)
{
// WIP MCOL-641 Unconditionall overflow check
// WIP MCOL-641 Unconditional overflow check
datatypes::MultiplicationNoOverflowCheck mul;
mul(decimal.s128Value, scaleMultiplier, decimal.s128Value);
}

View File

@ -219,8 +219,7 @@ inline IDB_Decimal SimpleColumn_UINT<len>::getDecimalVal(rowgroup::Row& row, boo
isNull = true;
fResult.decimalVal.value = (uint64_t)row.getUintField<len>(fInputIndex);
// WIP MCOL-641
fResult.decimalVal.precision = datatypes::INT64MAXPRECISION+1;
fResult.decimalVal.precision = datatypes::INT64MAXPRECISION;
fResult.decimalVal.scale = 0;
return fResult.decimalVal;
}

View File

@ -725,6 +725,9 @@ inline bool TreeNode::getBoolVal()
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
return (fResult.decimalVal.s128Value != 0);
else
return (fResult.decimalVal.value != 0);
default:

View File

@ -3173,7 +3173,8 @@ ReturnedColumn* buildReturnedColumn(
if (item->unsigned_flag)
{
rc = new ConstantColumn((uint64_t)item->val_uint(), ConstantColumn::NUM);
rc = new ConstantColumn((uint64_t)item->val_uint(), ConstantColumn::NUM,
(int8_t) item->decimal_scale(), (uint8_t) item->decimal_precision());
}
else
{

View File

@ -84,7 +84,7 @@ public:
makeAbsRids = m;
}
bool willPrefetch();
const int64_t getLastLbid();
int64_t getLastLbid();
void getLBIDList(uint32_t loopCount, std::vector<int64_t>* lbids);
virtual SCommand duplicate();

View File

@ -237,6 +237,9 @@ inline bool getBool(rowgroup::Row& row,
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
return false;
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) && !isNull)
@ -246,8 +249,7 @@ inline bool getBool(rowgroup::Row& row,
return (!numericLE(val, pm[2]->data()->getDecimalVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) &&
return numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDecimalVal(row, isNull));
}

View File

@ -56,8 +56,12 @@ bool getUIntValFromParm(
const execplan::SPTP& parm,
uint64_t& value,
bool& isNull,
const string& timeZone)
const string& timeZone,
bool& isBigVal,
int128_t& bigval)
{
isBigVal = false;
switch (parm->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
@ -104,10 +108,12 @@ bool getUIntValFromParm(
if (parm->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
{
isBigVal = true;
if (parm->data()->resultType().colDataType == execplan::CalpontSystemCatalog::UDECIMAL &&
d.value < 0)
{
value = 0;
bigval = 0;
break;
}
@ -126,12 +132,7 @@ bool getUIntValFromParm(
if (tmpval < 0 && lefto < -4)
tmpval--;
if (tmpval > static_cast<int128_t>(INT64_MAX))
tmpval = INT64_MAX;
else if (tmpval < static_cast<int128_t>(INT64_MIN))
tmpval = INT64_MIN;
value = tmpval;
bigval = tmpval;
}
else
{
@ -229,15 +230,39 @@ int64_t Func_bitand::getIntVal(Row& row,
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
int128_t bigval1 = 0;
int128_t bigval2 = 0;
bool isBigVal1;
bool isBigVal2;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (LIKELY(!isBigVal1 && !isBigVal2))
{
return val1 & val2;
}
// Type promotion to int128_t
if (!isBigVal1)
bigval1 = val1;
if (!isBigVal2)
bigval2 = val2;
int128_t res = bigval1 & bigval2;
if (res > static_cast<int128_t>(UINT64_MAX))
res = UINT64_MAX;
else if (res < static_cast<int128_t>(INT64_MIN))
res = INT64_MIN;
return (int64_t) res;
}
@ -265,15 +290,39 @@ int64_t Func_leftshift::getIntVal(Row& row,
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
int128_t bigval1 = 0;
int128_t bigval2 = 0;
bool isBigVal1;
bool isBigVal2;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
{
std::ostringstream oss;
oss << "leftshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (LIKELY(!isBigVal1 && !isBigVal2))
{
return val1 << val2;
}
// Type promotion to int128_t
if (!isBigVal1)
bigval1 = val1;
if (!isBigVal2)
bigval2 = val2;
int128_t res = bigval1 << bigval2;
if (res > static_cast<int128_t>(UINT64_MAX))
res = UINT64_MAX;
else if (res < static_cast<int128_t>(INT64_MIN))
res = INT64_MIN;
return (int64_t) res;
}
@ -301,15 +350,39 @@ int64_t Func_rightshift::getIntVal(Row& row,
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
int128_t bigval1 = 0;
int128_t bigval2 = 0;
bool isBigVal1;
bool isBigVal2;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
{
std::ostringstream oss;
oss << "rightshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (LIKELY(!isBigVal1 && !isBigVal2))
{
return val1 >> val2;
}
// Type promotion to int128_t
if (!isBigVal1)
bigval1 = val1;
if (!isBigVal2)
bigval2 = val2;
int128_t res = bigval1 >> bigval2;
if (res > static_cast<int128_t>(UINT64_MAX))
res = UINT64_MAX;
else if (res < static_cast<int128_t>(INT64_MIN))
res = INT64_MIN;
return (int64_t) res;
}
@ -337,15 +410,39 @@ int64_t Func_bitor::getIntVal(Row& row,
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
int128_t bigval1 = 0;
int128_t bigval2 = 0;
bool isBigVal1;
bool isBigVal2;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
{
std::ostringstream oss;
oss << "bitor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (LIKELY(!isBigVal1 && !isBigVal2))
{
return val1 | val2;
}
// Type promotion to int128_t
if (!isBigVal1)
bigval1 = val1;
if (!isBigVal2)
bigval2 = val2;
int128_t res = bigval1 | bigval2;
if (res > static_cast<int128_t>(UINT64_MAX))
res = UINT64_MAX;
else if (res < static_cast<int128_t>(INT64_MIN))
res = INT64_MIN;
return (int64_t) res;
}
uint64_t Func_bitor::getUintVal(rowgroup::Row& row,
@ -381,15 +478,39 @@ int64_t Func_bitxor::getIntVal(Row& row,
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
int128_t bigval1 = 0;
int128_t bigval2 = 0;
bool isBigVal1;
bool isBigVal2;
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
{
std::ostringstream oss;
oss << "bitxor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (LIKELY(!isBigVal1 && !isBigVal2))
{
return val1 ^ val2;
}
// Type promotion to int128_t
if (!isBigVal1)
bigval1 = val1;
if (!isBigVal2)
bigval2 = val2;
int128_t res = bigval1 ^ bigval2;
if (res > static_cast<int128_t>(UINT64_MAX))
res = UINT64_MAX;
else if (res < static_cast<int128_t>(INT64_MIN))
res = INT64_MIN;
return (int64_t) res;
}
@ -403,6 +524,20 @@ CalpontSystemCatalog::ColType Func_bit_count::operationType( FunctionParm& fp, C
return resultType;
}
inline int64_t bitCount(uint64_t val)
{
// Refer to Hacker's Delight Chapter 5
// for the bit counting algo used here
val = val - ((val >> 1) & 0x5555555555555555);
val = (val & 0x3333333333333333) + ((val >> 2) & 0x3333333333333333);
val = (val + (val >> 4)) & 0x0F0F0F0F0F0F0F0F;
val = val + (val >> 8);
val = val + (val >> 16);
val = val + (val >> 32);
return (int64_t)(val & 0x000000000000007F);
}
int64_t Func_bit_count::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
@ -416,24 +551,25 @@ int64_t Func_bit_count::getIntVal(Row& row,
uint64_t val = 0;
if (!getUIntValFromParm(row, parm[0], val, isNull, timeZone()))
int128_t bigval = 0;
bool isBigVal;
if (!getUIntValFromParm(row, parm[0], val, isNull, timeZone(), isBigVal, bigval))
{
std::ostringstream oss;
oss << "bit_count: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
// Refer to Hacker's Delight Chapter 5
// for the bit counting algo used here
val = val - ((val >> 1) & 0x5555555555555555);
val = (val & 0x3333333333333333) + ((val >> 2) & 0x3333333333333333);
val = (val + (val >> 4)) & 0x0F0F0F0F0F0F0F0F;
val = val + (val >> 8);
val = val + (val >> 16);
val = val + (val >> 32);
return (int64_t)(val & 0x000000000000007F);
if (LIKELY(!isBigVal))
{
return bitCount(val);
}
else
{
return (bitCount(*reinterpret_cast<uint64_t*>(&bigval)) +
bitCount(*(reinterpret_cast<uint64_t*>(&bigval) + 1)));
}
}

View File

@ -329,7 +329,6 @@ inline uint64_t searched_case_cmp(Row& row,
uint64_t whereCount = hasElse ? (parm.size() - 1) / 2 : parm.size() / 2;
bool foundIt = false;
for (i = 0; i < whereCount; i++)
{
if (parm[i]->getBoolVal(row, isNull))
@ -364,8 +363,6 @@ CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp,
uint64_t simple = simpleCase ? 1 : 0;
bool hasElse = (((fp.size()-simple) % 2) != 0); // if 1, then ELSE exist
uint64_t parmCount = hasElse ? (fp.size() - 2) : (fp.size() - 1);
uint64_t whereCount = hasElse ? (fp.size() - 2 + simple) / 2 : (fp.size() - 1) / 2 + simple;
@ -393,6 +390,7 @@ CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp,
allStringO = false;
oct = op.operationType();
}
i += 1;
}

View File

@ -212,13 +212,62 @@ uint64_t Func_ceil::getUintVal(Row& row,
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
ret = (uint64_t)parm[0]->data()->getIntVal(row, isNull);
}
break;
// ceil(decimal(X,Y)) leads to this path if X, Y allows to
// downcast to INT otherwise Func_ceil::getDecimalVal() is called
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
// negative scale is not supported by CNX yet
if (d.scale > 0)
{
if (d.scale > datatypes::INT128MAXPRECISION)
{
std::ostringstream oss;
oss << "ceil: datatype of " << execplan::colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) d.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
{
int128_t tmp = d.s128Value;
int128_t scaleDivisor;
datatypes::getScaleDivisor(scaleDivisor, d.scale);
d.s128Value /= scaleDivisor;
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (d.s128Value * scaleDivisor)) > 0)
d.s128Value += 1;
ret = datatypes::Decimal::getUInt64FromWideDecimal(d.s128Value);
}
else
{
int64_t tmp = d.value;
d.value /= helpers::powerOf10_c[d.scale];
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (d.value * helpers::powerOf10_c[d.scale])) > 0)
d.value += 1;
ret = (uint64_t) d.value;
}
}
}
break;
case CalpontSystemCatalog::UBIGINT:
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::UMEDINT:

View File

@ -153,8 +153,8 @@ string Func_char::getStrVal(Row& row,
if (lefto > 4)
tmpval++;
if (tmpval > static_cast<int128_t>(INT64_MAX))
tmpval = INT64_MAX;
value = datatypes::Decimal::getInt32FromWideDecimal(tmpval);
// WIP MCOL-641
/*if ( !getChar((int64_t)tmpval, buf) )
{
@ -201,6 +201,7 @@ string Func_char::getStrVal(Row& row,
numBytes += getChar(value, pBuf);
}
isNull = false;
/* Check whether we got a well-formed string */
MY_STRCOPY_STATUS status;

View File

@ -749,9 +749,12 @@ int64_t Func_date_add::getIntVal(rowgroup::Row& row,
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (parm[0]->data()->resultType().scale)
if (parm[0]->data()->resultType().scale == 0)
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
else
isNull = true;
break;
}

View File

@ -363,6 +363,7 @@ string Func_date_format::getStrVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -383,6 +384,11 @@ string Func_date_format::getStrVal(rowgroup::Row& row,
dt.msecond = (uint32_t)((val & 0xfffff));
}
}
else
{
isNull = true;
return "";
}
break;

View File

@ -118,6 +118,7 @@ int64_t Func_day::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -132,6 +133,10 @@ int64_t Func_day::getIntVal(rowgroup::Row& row,
return (uint32_t)((val >> 38) & 0x3f);
}
}
else
{
isNull = true;
}
break;

View File

@ -138,6 +138,7 @@ int64_t Func_dayname::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -154,6 +155,11 @@ int64_t Func_dayname::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -136,6 +136,7 @@ int64_t Func_dayofweek::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -152,6 +153,11 @@ int64_t Func_dayofweek::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -135,6 +135,7 @@ int64_t Func_dayofyear::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));

View File

@ -71,6 +71,7 @@ string Func_elt::getStrVal(rowgroup::Row& row,
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);

View File

@ -61,10 +61,22 @@ DateTime getDateTime(rowgroup::Row& row,
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal dec = parm[0]->data()->getDecimalVal(row, isNull);
if (parm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
{
int128_t scaleDivisor;
datatypes::getScaleDivisor(scaleDivisor, dec.scale);
val = datatypes::Decimal::getInt64FromWideDecimal(dec.s128Value / scaleDivisor);
msec = datatypes::Decimal::getUInt32FromWideDecimal(dec.s128Value % scaleDivisor);
}
else
{
val = dec.value / IDB_pow[dec.scale];
msec = dec.value % IDB_pow[dec.scale];
}
break;
}

View File

@ -91,6 +91,7 @@ string Func_hex::getStrVal(rowgroup::Row& row,
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
/* Return hex of unsigned longlong value */
double val = parm[0]->data()->getDoubleVal(row, isNull);

View File

@ -67,14 +67,19 @@ int64_t Func_hour::getIntVal(rowgroup::Row& row,
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (parm[0]->data()->resultType().scale)
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
else
{
isNull = true;
}
break;
}

View File

@ -43,7 +43,7 @@ bool boolVal(SPTP& parm, Row& row, const string& timeZone)
try
{
ret = parm->getBoolVal(row, isNull);
ret = parm->getBoolVal(row, isNull) && !isNull;
}
catch (logging::NotImplementedExcept&)
{
@ -67,6 +67,9 @@ bool boolVal(SPTP& parm, Row& row, const string& timeZone)
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
ret = (parm->data()->getDecimalVal(row, isNull).s128Value != 0);
else
ret = (parm->data()->getDecimalVal(row, isNull).value != 0);
break;
case CalpontSystemCatalog::BIGINT:

View File

@ -157,6 +157,8 @@ std::string Func_inet_ntoa::getStrVal(rowgroup::Row& row,
// else just get integer value
if ((fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DECIMAL) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::UDECIMAL) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::FLOAT) ||
(fp[0]->data()->resultType().colDataType ==

View File

@ -136,6 +136,7 @@ int64_t Func_last_day::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -152,6 +153,11 @@ int64_t Func_last_day::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -66,6 +66,7 @@ uint64_t makedate(rowgroup::Row& row,
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
@ -149,6 +150,7 @@ uint64_t makedate(rowgroup::Row& row,
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);

View File

@ -72,6 +72,7 @@ string Func_maketime::getStrVal(rowgroup::Row& row,
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
@ -135,6 +136,7 @@ string Func_maketime::getStrVal(rowgroup::Row& row,
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
@ -204,6 +206,7 @@ string Func_maketime::getStrVal(rowgroup::Row& row,
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[2]->data()->getDecimalVal(row, isNull);

View File

@ -1849,10 +1849,75 @@ string Func_format::getStrVal(Row& row,
{
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
char buf[80];
//perform rouding if needed
if ( scale < 0 )
scale = 0;
if (parm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
{
if ( scale < decimal.scale )
{
int64_t d = 0;
int128_t p = 1;
if (!isNull && parm.size() > 1)
{
d = scale;
if (!isNull)
helpers::decimalPlaceDec(d, p, decimal.scale);
}
if (isNull)
break;
int128_t x = decimal.s128Value;
if (d > 0)
{
x = x * p;
}
else if (d < 0)
{
int128_t h = p / 2; // 0.5
if ((x >= h) || (x <= -h))
{
if (x >= 0)
x += h;
else
x -= h;
if (p != 0)
x = x / p;
else
x = 0;
}
else
{
x = 0;
}
}
// negative scale is not supported by CNX yet, set d to 0.
if (decimal.scale < 0)
{
do
x *= 10;
while (++decimal.scale < 0);
}
decimal.s128Value = x;
}
dataconvert::DataConvert::decimalToString(&decimal.s128Value,
decimal.scale, buf, 80, parm[0]->data()->resultType().colDataType);
}
else
{
if ( scale < decimal.scale )
{
int64_t d = 0;
@ -1909,10 +1974,9 @@ string Func_format::getStrVal(Row& row,
decimal.value = x;
}
char buf[80];
dataconvert::DataConvert::decimalToString( decimal.value,
decimal.scale, buf, 80, parm[0]->data()->resultType().colDataType);
}
value = buf;
}
@ -1982,7 +2046,7 @@ string Func_format::getStrVal(Row& row,
// pad extra with '0'
if (*(value.data()) != '#')
{
for ( int i = 0 ; i < pad ; i ++ )
for ( int i = 0 ; i < pad ; i++ )
{
value = value.append("0");
}
@ -1996,7 +2060,7 @@ string Func_format::getStrVal(Row& row,
string::size_type pos = value.find ('-', 0);
if (pos != string::npos)
end = 1;;
end = 1;
while ((comma -= 3) > end)
{

View File

@ -110,6 +110,7 @@ int64_t Func_microsecond::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -124,6 +125,11 @@ int64_t Func_microsecond::getIntVal(rowgroup::Row& row,
microSecond = (uint32_t)((val & 0xfffff));
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -66,14 +66,19 @@ int64_t Func_minute::getIntVal(rowgroup::Row& row,
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (parm[0]->data()->resultType().scale)
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
else
{
isNull = true;
}
break;
}

View File

@ -116,6 +116,7 @@ int64_t Func_month::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -130,6 +131,10 @@ int64_t Func_month::getIntVal(rowgroup::Row& row,
return (unsigned)((val >> 44) & 0xf);
}
}
else
{
isNull = true;
}
break;

View File

@ -158,6 +158,7 @@ int64_t Func_monthname::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));

View File

@ -430,6 +430,7 @@ int32_t Func_nullif::getDateIntVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
@ -518,6 +519,7 @@ int64_t Func_nullif::getDatetimeIntVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
@ -584,6 +586,7 @@ int64_t Func_nullif::getTimeIntVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
@ -636,6 +639,7 @@ int64_t Func_nullif::getTimestampIntVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
@ -689,6 +693,7 @@ double Func_nullif::getDoubleVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
@ -779,6 +784,7 @@ long double Func_nullif::getLongDoubleVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:

View File

@ -115,6 +115,7 @@ int64_t Func_quarter::getIntVal(rowgroup::Row& row,
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
if (parm[0]->data()->resultType().scale == 0)
{

View File

@ -118,7 +118,14 @@ inline bool getBool(rowgroup::Row& row,
char buf[80];
if (pm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
{
dataconvert::DataConvert::decimalToString(&d.s128Value, d.scale, buf, 80, pm[0]->data()->resultType().colDataType);
}
else
{
dataconvert::DataConvert::decimalToString(d.value, d.scale, buf, 80, pm[0]->data()->resultType().colDataType);
}
expr = buf;
break;
@ -193,7 +200,14 @@ inline bool getBool(rowgroup::Row& row,
char buf[80];
dataconvert::DataConvert::decimalToString( d.value, d.scale, buf, 80, pm[1]->data()->resultType().colDataType);
if (pm[1]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
{
dataconvert::DataConvert::decimalToString(&d.s128Value, d.scale, buf, 80, pm[1]->data()->resultType().colDataType);
}
else
{
dataconvert::DataConvert::decimalToString(d.value, d.scale, buf, 80, pm[1]->data()->resultType().colDataType);
}
pattern = buf;
break;

View File

@ -120,6 +120,7 @@ string Func_sec_to_time::getStrVal(rowgroup::Row& row,
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
const string& valStr = parm[0]->data()->getStrVal(row, isNull);

View File

@ -66,14 +66,19 @@ int64_t Func_second::getIntVal(rowgroup::Row& row,
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (parm[0]->data()->resultType().scale)
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
else
{
isNull = true;
}
break;
}

View File

@ -145,6 +145,7 @@ dataconvert::DateTime getDateTime (rowgroup::Row& row,
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
if (parm[0]->data()->resultType().scale == 0)
{
@ -159,6 +160,11 @@ dataconvert::DateTime getDateTime (rowgroup::Row& row,
return -1;
}
}
else
{
isNull = true;
return -1;
}
break;
}

View File

@ -70,8 +70,9 @@ string Func_time::getStrVal(rowgroup::Row& row,
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (parm[0]->data()->resultType().scale)
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToTime(parm[0]->data()->getIntVal(row, isNull));
@ -81,6 +82,10 @@ string Func_time::getStrVal(rowgroup::Row& row,
//else
// return *(reinterpret_cast<uint64_t*>(&val));
}
else
{
isNull = true;
}
break;
}

View File

@ -128,6 +128,7 @@ string Func_time_format::getStrVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -145,6 +146,11 @@ string Func_time_format::getStrVal(rowgroup::Row& row,
msec = (uint32_t)((val & 0xfffff));
}
}
else
{
isNull = true;
return "";
}
break;

View File

@ -153,6 +153,7 @@ int64_t Func_time_to_sec::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -169,6 +170,11 @@ int64_t Func_time_to_sec::getIntVal(rowgroup::Row& row,
sec = (int32_t)((val >> 20) & 0x3f);
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -199,6 +199,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row,
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale != 0)
{
isNull = true;
@ -285,6 +286,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row,
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
if (parm[1]->data()->resultType().scale != 0)
{
isNull = true;

View File

@ -131,6 +131,7 @@ int64_t Func_unix_timestamp::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -147,6 +148,11 @@ int64_t Func_unix_timestamp::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -139,6 +139,7 @@ int64_t Func_week::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -155,6 +156,11 @@ int64_t Func_week::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -135,6 +135,7 @@ int64_t Func_weekday::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -151,6 +152,11 @@ int64_t Func_weekday::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -118,6 +118,7 @@ int64_t Func_year::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));

View File

@ -142,6 +142,7 @@ int64_t Func_yearweek::getIntVal(rowgroup::Row& row,
break;
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
@ -158,6 +159,11 @@ int64_t Func_yearweek::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
}
}
else
{
isNull = true;
return -1;
}
break;

View File

@ -473,6 +473,7 @@ void FuncExp::evaluate(rowgroup::Row& row, std::vector<execplan::SRCP>& expressi
case CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = expression[i]->getDecimalVal(row, isNull);
if (expression[i]->resultType().colWidth
== datatypes::MAXDECIMALWIDTH)
{