diff --git a/datatypes/mcs_decimal.h b/datatypes/mcs_decimal.h index 1a905bd72..fa2ed3849 100644 --- a/datatypes/mcs_decimal.h +++ b/datatypes/mcs_decimal.h @@ -285,6 +285,45 @@ class Decimal return static_cast(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(UINT32_MAX)) + return UINT32_MAX; + else if (value < 0) + return 0; + + return static_cast(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(INT32_MAX)) + return INT32_MAX; + else if (value < static_cast(INT32_MIN)) + return INT32_MIN; + + return static_cast(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(UINT64_MAX)) + return UINT64_MAX; + else if (value < 0) + return 0; + + return static_cast(value); + } + /** @brief The method converts a __float128 value to a double. */ diff --git a/dbcon/execplan/constantcolumn.cpp b/dbcon/execplan/constantcolumn.cpp index 775ad88ed..f92a59dc6 100644 --- a/dbcon/execplan/constantcolumn.cpp +++ b/dbcon/execplan/constantcolumn.cpp @@ -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; } diff --git a/dbcon/execplan/constantcolumn.h b/dbcon/execplan/constantcolumn.h index a5c0a074b..334247c47 100644 --- a/dbcon/execplan/constantcolumn.h +++ b/dbcon/execplan/constantcolumn.h @@ -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... /** diff --git a/dbcon/execplan/functioncolumn.h b/dbcon/execplan/functioncolumn.h index 4d398d9a8..874e7ef67 100644 --- a/dbcon/execplan/functioncolumn.h +++ b/dbcon/execplan/functioncolumn.h @@ -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); } diff --git a/dbcon/execplan/simplecolumn_uint.h b/dbcon/execplan/simplecolumn_uint.h index 7a6da72e4..f8b8a5c96 100644 --- a/dbcon/execplan/simplecolumn_uint.h +++ b/dbcon/execplan/simplecolumn_uint.h @@ -219,8 +219,7 @@ inline IDB_Decimal SimpleColumn_UINT::getDecimalVal(rowgroup::Row& row, boo isNull = true; fResult.decimalVal.value = (uint64_t)row.getUintField(fInputIndex); - // WIP MCOL-641 - fResult.decimalVal.precision = datatypes::INT64MAXPRECISION+1; + fResult.decimalVal.precision = datatypes::INT64MAXPRECISION; fResult.decimalVal.scale = 0; return fResult.decimalVal; } diff --git a/dbcon/execplan/treenode.h b/dbcon/execplan/treenode.h index 56f21ccdd..b23024990 100644 --- a/dbcon/execplan/treenode.h +++ b/dbcon/execplan/treenode.h @@ -725,7 +725,10 @@ inline bool TreeNode::getBoolVal() case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: - return (fResult.decimalVal.value != 0); + if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH) + return (fResult.decimalVal.s128Value != 0); + else + return (fResult.decimalVal.value != 0); default: throw logging::InvalidConversionExcept("TreeNode::getBoolVal: Invalid conversion."); diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp index 6bc80e42c..2c4c2d775 100755 --- a/dbcon/mysql/ha_mcs_execplan.cpp +++ b/dbcon/mysql/ha_mcs_execplan.cpp @@ -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 { diff --git a/primitives/primproc/columncommand.h b/primitives/primproc/columncommand.h index 1c1a29cb9..d868ce2f9 100644 --- a/primitives/primproc/columncommand.h +++ b/primitives/primproc/columncommand.h @@ -84,7 +84,7 @@ public: makeAbsRids = m; } bool willPrefetch(); - const int64_t getLastLbid(); + int64_t getLastLbid(); void getLBIDList(uint32_t loopCount, std::vector* lbids); virtual SCommand duplicate(); diff --git a/utils/common/widedecimalutils.h b/utils/common/widedecimalutils.h index 3ebdb408b..2ed5b7309 100644 --- a/utils/common/widedecimalutils.h +++ b/utils/common/widedecimalutils.h @@ -58,7 +58,7 @@ namespace utils ptr[1] = BINARYEMPTYVALUEHIGH; } - inline void setWideDecimalNullValue(int128_t* val) + inline void setWideDecimalNullValue(int128_t* val) { uint64_t* ptr = reinterpret_cast(val); ptr[0] = BINARYNULLVALUELOW; @@ -72,7 +72,7 @@ namespace utils ptr[1] = BINARYEMPTYVALUEHIGH; } - inline void int128Max(int128_t& val) + inline void int128Max(int128_t& val) { uint64_t* ptr = reinterpret_cast(&val); ptr[0] = 0xFFFFFFFFFFFFFFFF; diff --git a/utils/funcexp/func_between.cpp b/utils/funcexp/func_between.cpp index ab6aef028..f4c0eabf6 100644 --- a/utils/funcexp/func_between.cpp +++ b/utils/funcexp/func_between.cpp @@ -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)); } diff --git a/utils/funcexp/func_bitwise.cpp b/utils/funcexp/func_bitwise.cpp index beef7d290..5eb48252e 100644 --- a/utils/funcexp/func_bitwise.cpp +++ b/utils/funcexp/func_bitwise.cpp @@ -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(INT64_MAX)) - tmpval = INT64_MAX; - else if (tmpval < static_cast(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); } - return val1 & val2; + 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(UINT64_MAX)) + res = UINT64_MAX; + else if (res < static_cast(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); } - return val1 << val2; + 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(UINT64_MAX)) + res = UINT64_MAX; + else if (res < static_cast(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); } - return val1 >> val2; + 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(UINT64_MAX)) + res = UINT64_MAX; + else if (res < static_cast(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); } - return val1 | val2; + 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(UINT64_MAX)) + res = UINT64_MAX; + else if (res < static_cast(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); } - return val1 ^ val2; + 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(UINT64_MAX)) + res = UINT64_MAX; + else if (res < static_cast(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(&bigval)) + + bitCount(*(reinterpret_cast(&bigval) + 1))); + } } diff --git a/utils/funcexp/func_case.cpp b/utils/funcexp/func_case.cpp index 327c02cc0..0204d9abf 100644 --- a/utils/funcexp/func_case.cpp +++ b/utils/funcexp/func_case.cpp @@ -212,7 +212,7 @@ inline uint64_t simple_case_cmp(Row& row, for (i = 1; i <= whereCount; i++) { - if (ev == parm[i]->data()->getDecimalVal(row, isNull) && !isNull) + if (ev == parm[i]->data()->getDecimalVal(row, isNull) && !isNull) { foundIt = true; break; @@ -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)) @@ -362,9 +361,7 @@ CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp, bool simpleCase) { uint64_t simple = simpleCase ? 1 : 0; - bool hasElse = (((fp.size()-simple) % 2) != 0); // if 1, then ELSE exist - - + 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; @@ -382,8 +379,8 @@ CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp, { // for SimpleCase, we return the type of the case expression, // which will always be in position 0. - if (i == 0 && simpleCase) - { + if (i == 0 && simpleCase) + { if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR && fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT && fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) @@ -393,15 +390,16 @@ CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp, allStringO = false; oct = op.operationType(); } - i += 1; - } - // operation or result type - operation = ((i > 0+simple) && (i <= whereCount)); + i += 1; + } + + // operation or result type + operation = ((i > 0+simple) && (i <= whereCount)); if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR && - fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT && - fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) + fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT && + fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) { // this is not a string column PredicateOperator op; @@ -414,7 +412,7 @@ CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp, allStringO = false; oct = op.operationType(); } - } + } // If any parm is of string type, the result type should be string. (same as if) else if (rct.colDataType != CalpontSystemCatalog::CHAR && diff --git a/utils/funcexp/func_ceil.cpp b/utils/funcexp/func_ceil.cpp index 5714b2349..73f8a4624 100644 --- a/utils/funcexp/func_ceil.cpp +++ b/utils/funcexp/func_ceil.cpp @@ -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: diff --git a/utils/funcexp/func_char.cpp b/utils/funcexp/func_char.cpp index d3bec2ae9..f303bb8d3 100644 --- a/utils/funcexp/func_char.cpp +++ b/utils/funcexp/func_char.cpp @@ -153,8 +153,8 @@ string Func_char::getStrVal(Row& row, if (lefto > 4) tmpval++; - if (tmpval > static_cast(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; diff --git a/utils/funcexp/func_date_add.cpp b/utils/funcexp/func_date_add.cpp index 5004f5521..8c0e547fa 100644 --- a/utils/funcexp/func_date_add.cpp +++ b/utils/funcexp/func_date_add.cpp @@ -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; } diff --git a/utils/funcexp/func_date_format.cpp b/utils/funcexp/func_date_format.cpp index 105069c59..88a1ed99f 100644 --- a/utils/funcexp/func_date_format.cpp +++ b/utils/funcexp/func_date_format.cpp @@ -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; diff --git a/utils/funcexp/func_day.cpp b/utils/funcexp/func_day.cpp index c414fd5d4..9b7def395 100644 --- a/utils/funcexp/func_day.cpp +++ b/utils/funcexp/func_day.cpp @@ -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; diff --git a/utils/funcexp/func_dayname.cpp b/utils/funcexp/func_dayname.cpp index e46bfa46f..7a076435b 100644 --- a/utils/funcexp/func_dayname.cpp +++ b/utils/funcexp/func_dayname.cpp @@ -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; diff --git a/utils/funcexp/func_dayofweek.cpp b/utils/funcexp/func_dayofweek.cpp index 3a29f592d..d0b28d22e 100644 --- a/utils/funcexp/func_dayofweek.cpp +++ b/utils/funcexp/func_dayofweek.cpp @@ -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; diff --git a/utils/funcexp/func_dayofyear.cpp b/utils/funcexp/func_dayofyear.cpp index ee13730c1..cf9c37814 100644 --- a/utils/funcexp/func_dayofyear.cpp +++ b/utils/funcexp/func_dayofyear.cpp @@ -75,7 +75,7 @@ int64_t Func_dayofyear::getIntVal(rowgroup::Row& row, { dataconvert::TimeStamp timestamp(parm[0]->data()->getIntVal(row, isNull)); int64_t seconds = timestamp.second; - dataconvert::MySQLTime m_time; + dataconvert::MySQLTime m_time; dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); year = m_time.year; month = m_time.month; @@ -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)); diff --git a/utils/funcexp/func_elt.cpp b/utils/funcexp/func_elt.cpp index 2fd377dd4..b3bf6a3b3 100644 --- a/utils/funcexp/func_elt.cpp +++ b/utils/funcexp/func_elt.cpp @@ -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); diff --git a/utils/funcexp/func_from_unixtime.cpp b/utils/funcexp/func_from_unixtime.cpp index d1168d2d6..ab88e39e0 100644 --- a/utils/funcexp/func_from_unixtime.cpp +++ b/utils/funcexp/func_from_unixtime.cpp @@ -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); - val = dec.value / IDB_pow[dec.scale]; - msec = dec.value % IDB_pow[dec.scale]; + + 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; } diff --git a/utils/funcexp/func_hex.cpp b/utils/funcexp/func_hex.cpp index 97e608981..b45f6b52a 100644 --- a/utils/funcexp/func_hex.cpp +++ b/utils/funcexp/func_hex.cpp @@ -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); diff --git a/utils/funcexp/func_hour.cpp b/utils/funcexp/func_hour.cpp index 918fe193d..af949a393 100644 --- a/utils/funcexp/func_hour.cpp +++ b/utils/funcexp/func_hour.cpp @@ -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; } diff --git a/utils/funcexp/func_if.cpp b/utils/funcexp/func_if.cpp index 6d10d6829..168383b93 100644 --- a/utils/funcexp/func_if.cpp +++ b/utils/funcexp/func_if.cpp @@ -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,7 +67,10 @@ bool boolVal(SPTP& parm, Row& row, const string& timeZone) break; case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: - ret = (parm->data()->getDecimalVal(row, isNull).value != 0); + 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: case CalpontSystemCatalog::SMALLINT: diff --git a/utils/funcexp/func_inet_ntoa.cpp b/utils/funcexp/func_inet_ntoa.cpp index 0d33d5ec1..ea528ceb6 100644 --- a/utils/funcexp/func_inet_ntoa.cpp +++ b/utils/funcexp/func_inet_ntoa.cpp @@ -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 == diff --git a/utils/funcexp/func_last_day.cpp b/utils/funcexp/func_last_day.cpp index 2099ea71a..b20e8502f 100644 --- a/utils/funcexp/func_last_day.cpp +++ b/utils/funcexp/func_last_day.cpp @@ -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; diff --git a/utils/funcexp/func_makedate.cpp b/utils/funcexp/func_makedate.cpp index 8efc3f171..64c2d5e5d 100644 --- a/utils/funcexp/func_makedate.cpp +++ b/utils/funcexp/func_makedate.cpp @@ -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); diff --git a/utils/funcexp/func_maketime.cpp b/utils/funcexp/func_maketime.cpp index 3bc7b8c27..6e315c7ec 100644 --- a/utils/funcexp/func_maketime.cpp +++ b/utils/funcexp/func_maketime.cpp @@ -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); diff --git a/utils/funcexp/func_math.cpp b/utils/funcexp/func_math.cpp index 0c86cbb67..fd0c0753b 100644 --- a/utils/funcexp/func_math.cpp +++ b/utils/funcexp/func_math.cpp @@ -1849,70 +1849,134 @@ 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 ( scale < decimal.scale ) + if (parm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH) { - int64_t d = 0; - int64_t p = 1; - - if (!isNull && parm.size() > 1) + if ( scale < decimal.scale ) { - d = scale; + int64_t d = 0; + int128_t p = 1; - if (!isNull) - helpers::decimalPlaceDec(d, p, decimal.scale); - } - - if (isNull) - break; - - int64_t x = decimal.value; - - if (d > 0) - { - x = x * p; - } - else if (d < 0) - { - int64_t h = p / 2; // 0.5 - - if ((x >= h) || (x <= -h)) + if (!isNull && parm.size() > 1) { - if (x >= 0) - x += h; - else - x -= h; + d = scale; - if (p != 0) - x = x / p; + 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; + } } - else + + // negative scale is not supported by CNX yet, set d to 0. + if (decimal.scale < 0) { - x = 0; + do + x *= 10; + + while (++decimal.scale < 0); } + + decimal.s128Value = x; } - // negative scale is not supported by CNX yet, set d to 0. - if (decimal.scale < 0) - { - do - x *= 10; - - while (++decimal.scale < 0); - } - - decimal.value = x; + dataconvert::DataConvert::decimalToString(&decimal.s128Value, + decimal.scale, buf, 80, parm[0]->data()->resultType().colDataType); } + else + { + if ( scale < decimal.scale ) + { + int64_t d = 0; + int64_t p = 1; - char buf[80]; + if (!isNull && parm.size() > 1) + { + d = scale; - dataconvert::DataConvert::decimalToString( decimal.value, - decimal.scale, buf, 80, parm[0]->data()->resultType().colDataType); + if (!isNull) + helpers::decimalPlaceDec(d, p, decimal.scale); + } + + if (isNull) + break; + + int64_t x = decimal.value; + + if (d > 0) + { + x = x * p; + } + else if (d < 0) + { + int64_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.value = x; + } + + 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) { diff --git a/utils/funcexp/func_microsecond.cpp b/utils/funcexp/func_microsecond.cpp index 12b2beb70..18b1cdabb 100644 --- a/utils/funcexp/func_microsecond.cpp +++ b/utils/funcexp/func_microsecond.cpp @@ -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; diff --git a/utils/funcexp/func_minute.cpp b/utils/funcexp/func_minute.cpp index fdad4e9cf..672008048 100644 --- a/utils/funcexp/func_minute.cpp +++ b/utils/funcexp/func_minute.cpp @@ -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; } diff --git a/utils/funcexp/func_month.cpp b/utils/funcexp/func_month.cpp index ffb3f5fc1..f9cbfddd0 100644 --- a/utils/funcexp/func_month.cpp +++ b/utils/funcexp/func_month.cpp @@ -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; diff --git a/utils/funcexp/func_monthname.cpp b/utils/funcexp/func_monthname.cpp index f04c37158..7d41e3ba4 100644 --- a/utils/funcexp/func_monthname.cpp +++ b/utils/funcexp/func_monthname.cpp @@ -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)); diff --git a/utils/funcexp/func_nullif.cpp b/utils/funcexp/func_nullif.cpp index 90c546ea3..886c58f9c 100644 --- a/utils/funcexp/func_nullif.cpp +++ b/utils/funcexp/func_nullif.cpp @@ -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: diff --git a/utils/funcexp/func_quarter.cpp b/utils/funcexp/func_quarter.cpp index c1dcda89e..35b9d93f4 100644 --- a/utils/funcexp/func_quarter.cpp +++ b/utils/funcexp/func_quarter.cpp @@ -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) { diff --git a/utils/funcexp/func_regexp.cpp b/utils/funcexp/func_regexp.cpp index 120a727e6..4a484c8e3 100644 --- a/utils/funcexp/func_regexp.cpp +++ b/utils/funcexp/func_regexp.cpp @@ -118,7 +118,14 @@ inline bool getBool(rowgroup::Row& row, char buf[80]; - dataconvert::DataConvert::decimalToString(d.value, d.scale, buf, 80, pm[0]->data()->resultType().colDataType); + 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; diff --git a/utils/funcexp/func_sec_to_time.cpp b/utils/funcexp/func_sec_to_time.cpp index afb532ec1..ff808a975 100644 --- a/utils/funcexp/func_sec_to_time.cpp +++ b/utils/funcexp/func_sec_to_time.cpp @@ -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); diff --git a/utils/funcexp/func_second.cpp b/utils/funcexp/func_second.cpp index 475f7495e..ff09bf320 100644 --- a/utils/funcexp/func_second.cpp +++ b/utils/funcexp/func_second.cpp @@ -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; } diff --git a/utils/funcexp/func_str_to_date.cpp b/utils/funcexp/func_str_to_date.cpp index c4b0226f2..3a4c165ac 100644 --- a/utils/funcexp/func_str_to_date.cpp +++ b/utils/funcexp/func_str_to_date.cpp @@ -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; } diff --git a/utils/funcexp/func_time.cpp b/utils/funcexp/func_time.cpp index 70202ac63..89d95b021 100644 --- a/utils/funcexp/func_time.cpp +++ b/utils/funcexp/func_time.cpp @@ -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(&val)); } + else + { + isNull = true; + } break; } diff --git a/utils/funcexp/func_time_format.cpp b/utils/funcexp/func_time_format.cpp index 5dd2f666a..c77e46934 100644 --- a/utils/funcexp/func_time_format.cpp +++ b/utils/funcexp/func_time_format.cpp @@ -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; diff --git a/utils/funcexp/func_time_to_sec.cpp b/utils/funcexp/func_time_to_sec.cpp index e19ce2f81..b8ab898b8 100644 --- a/utils/funcexp/func_time_to_sec.cpp +++ b/utils/funcexp/func_time_to_sec.cpp @@ -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; diff --git a/utils/funcexp/func_timediff.cpp b/utils/funcexp/func_timediff.cpp index 3c629933f..184200528 100644 --- a/utils/funcexp/func_timediff.cpp +++ b/utils/funcexp/func_timediff.cpp @@ -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; diff --git a/utils/funcexp/func_unix_timestamp.cpp b/utils/funcexp/func_unix_timestamp.cpp index 29a8f483a..4c43eaebb 100644 --- a/utils/funcexp/func_unix_timestamp.cpp +++ b/utils/funcexp/func_unix_timestamp.cpp @@ -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; diff --git a/utils/funcexp/func_week.cpp b/utils/funcexp/func_week.cpp index af024cfe4..874e95b42 100644 --- a/utils/funcexp/func_week.cpp +++ b/utils/funcexp/func_week.cpp @@ -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; diff --git a/utils/funcexp/func_weekday.cpp b/utils/funcexp/func_weekday.cpp index 04ca938b4..e8b59e620 100644 --- a/utils/funcexp/func_weekday.cpp +++ b/utils/funcexp/func_weekday.cpp @@ -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; diff --git a/utils/funcexp/func_year.cpp b/utils/funcexp/func_year.cpp index 2c5ec41f9..68f60ac20 100644 --- a/utils/funcexp/func_year.cpp +++ b/utils/funcexp/func_year.cpp @@ -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)); diff --git a/utils/funcexp/func_yearweek.cpp b/utils/funcexp/func_yearweek.cpp index 91bb60a8c..07e111c22 100644 --- a/utils/funcexp/func_yearweek.cpp +++ b/utils/funcexp/func_yearweek.cpp @@ -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; diff --git a/utils/funcexp/funcexp.cpp b/utils/funcexp/funcexp.cpp index d9dc24180..3cf0373b9 100644 --- a/utils/funcexp/funcexp.cpp +++ b/utils/funcexp/funcexp.cpp @@ -473,6 +473,7 @@ void FuncExp::evaluate(rowgroup::Row& row, std::vector& expressi case CalpontSystemCatalog::UDECIMAL: { IDB_Decimal val = expression[i]->getDecimalVal(row, isNull); + if (expression[i]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) {