diff --git a/datatypes/mcs_decimal.h b/datatypes/mcs_decimal.h index 46cf0b88d..45b3ee67b 100644 --- a/datatypes/mcs_decimal.h +++ b/datatypes/mcs_decimal.h @@ -584,6 +584,28 @@ class Decimal: public TSInt128 return !this->operator==(rhs); } + Decimal integralWideRound(const int128_t& scaleDivisor = 0) const + { + int128_t scaleDivisorInt = scaleDivisor; + if(UNLIKELY(!scaleDivisorInt)) + { + datatypes::getScaleDivisor(scaleDivisorInt, scale); + } + lldiv_t div = lldiv(s128Value, scaleDivisorInt); + + if (datatypes::abs(div.rem) * 2 >= scaleDivisorInt) + { + return Decimal(value, + scale, + precision, + (div.quot < 0) ? div.quot-- : div.quot++); + } + return Decimal(value, + scale, + precision, + div.quot); + } + inline bool isTSInt128ByPrecision() const { return precision > INT64MAXPRECISION diff --git a/datatypes/mcs_int128.h b/datatypes/mcs_int128.h index d8bacd8a8..2b0f24010 100644 --- a/datatypes/mcs_int128.h +++ b/datatypes/mcs_int128.h @@ -112,7 +112,7 @@ struct is_uint128_t { static const bool value = true; }; -inline int128_t abs(int128_t& x) +inline int128_t abs(int128_t x) { return (x >= 0) ? x : -x; } diff --git a/dbcon/execplan/constantcolumn.cpp b/dbcon/execplan/constantcolumn.cpp index 0ec49139c..8579f2fe0 100644 --- a/dbcon/execplan/constantcolumn.cpp +++ b/dbcon/execplan/constantcolumn.cpp @@ -328,7 +328,7 @@ void ConstantColumn::serialize(messageqcpp::ByteStream& b) const b << (uint8_t)fResult.boolVal; b << fResult.strVal; b << (uint64_t)fResult.decimalVal.value; - b << (uint128_t)fResult.decimalVal.s128Value; + b << fResult.decimalVal.s128Value; b << (uint8_t)fResult.decimalVal.scale; b << (uint8_t)fResult.decimalVal.precision; } @@ -353,7 +353,7 @@ void ConstantColumn::unserialize(messageqcpp::ByteStream& b) b >> (uint8_t&)fResult.boolVal; b >> fResult.strVal; b >> (uint64_t&)fResult.decimalVal.value; - b >> (uint128_t&)fResult.decimalVal.s128Value; + b >> fResult.decimalVal.s128Value; b >> (uint8_t&)fResult.decimalVal.scale; b >> (uint8_t&)fResult.decimalVal.precision; } diff --git a/dbcon/execplan/functioncolumn.h b/dbcon/execplan/functioncolumn.h index 59dacc2ef..57d39431d 100644 --- a/dbcon/execplan/functioncolumn.h +++ b/dbcon/execplan/functioncolumn.h @@ -270,9 +270,7 @@ public: } else { - decimal.s128Value = (int128_t)(decimal.s128Value > 0 ? - (__float128)decimal.s128Value / scaleMultiplier + 0.5 : - (__float128)decimal.s128Value / scaleMultiplier - 0.5); + decimal = decimal.integralWideRound(); } } } diff --git a/dbcon/execplan/predicateoperator.cpp b/dbcon/execplan/predicateoperator.cpp index 75d91996c..b132a5a25 100644 --- a/dbcon/execplan/predicateoperator.cpp +++ b/dbcon/execplan/predicateoperator.cpp @@ -125,8 +125,6 @@ bool PredicateOperator::operator!=(const TreeNode* t) const return (!(*this == t)); } -//FIXME: VARBINARY??? -//FIXME: BINARY??? void PredicateOperator::setOpType(Type& l, Type& r) { fOperationType = l; // Default to left side. Modify as needed. @@ -763,7 +761,6 @@ bool PredicateOperator::getBoolVal(rowgroup::Row& row, bool& isNull, ReturnedCol return strTrimCompare(val1, rop->getStrVal(row, isNull)) && !isNull; } - //FIXME: ??? case execplan::CalpontSystemCatalog::VARBINARY: case execplan::CalpontSystemCatalog::BLOB: return false; diff --git a/dbcon/execplan/treenode.h b/dbcon/execplan/treenode.h index 4d98a9816..ba504b04b 100644 --- a/dbcon/execplan/treenode.h +++ b/dbcon/execplan/treenode.h @@ -1038,56 +1038,30 @@ inline IDB_Decimal TreeNode::getDecimalVal() throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: non-support conversion from binary string"); case CalpontSystemCatalog::BIGINT: - { - idbassert(fResultType.scale == 0); - - if (fResultType.isWideDecimalPrecision()) - fResult.decimalVal = IDB_Decimal(0, 0, fResultType.precision, - (int128_t)fResult.intVal); - else - fResult.decimalVal = IDB_Decimal(fResult.intVal, 0, - fResultType.precision); - - break; - } - case CalpontSystemCatalog::MEDINT: case CalpontSystemCatalog::INT: case CalpontSystemCatalog::SMALLINT: case CalpontSystemCatalog::TINYINT: { idbassert(fResultType.scale == 0); - - fResult.decimalVal = IDB_Decimal(fResult.intVal, 0, - fResultType.precision); - + fResult.decimalVal = IDB_Decimal(fResult.intVal, + 0, + fResultType.precision, + fResult.intVal); break; } case CalpontSystemCatalog::UBIGINT: - { - idbassert(fResultType.scale == 0); - - if (fResultType.isWideDecimalPrecision()) - fResult.decimalVal = IDB_Decimal(0, 0, fResultType.precision, - (int128_t)fResult.uintVal); - else - fResult.decimalVal = IDB_Decimal((int64_t)fResult.uintVal, 0, - fResultType.precision); - - break; - } - case CalpontSystemCatalog::UMEDINT: case CalpontSystemCatalog::UINT: case CalpontSystemCatalog::USMALLINT: case CalpontSystemCatalog::UTINYINT: { idbassert(fResultType.scale == 0); - - fResult.decimalVal = IDB_Decimal((int64_t)fResult.uintVal, 0, - fResultType.precision); - + fResult.decimalVal = IDB_Decimal((int64_t)fResult.uintVal, + 0, + fResultType.precision, + fResult.uintVal); break; } @@ -1108,8 +1082,11 @@ inline IDB_Decimal TreeNode::getDecimalVal() } else { - fResult.decimalVal = IDB_Decimal((int64_t)lroundl(dlScaled), - fResultType.scale, fResultType.precision); + int64_t val = (int64_t)lroundl(dlScaled); + fResult.decimalVal = IDB_Decimal(val, + fResultType.scale, + fResultType.precision, + val); } break; diff --git a/dbcon/execplan/windowfunctioncolumn.cpp b/dbcon/execplan/windowfunctioncolumn.cpp index f574dbf8b..499ff4421 100644 --- a/dbcon/execplan/windowfunctioncolumn.cpp +++ b/dbcon/execplan/windowfunctioncolumn.cpp @@ -393,7 +393,7 @@ void WindowFunctionColumn::adjustResultType() if (fFunctionParms[0]->resultType().colDataType == CalpontSystemCatalog::DECIMAL || fFunctionParms[0]->resultType().colDataType == CalpontSystemCatalog::UDECIMAL) { - fResultType.colWidth = sizeof(int128_t); + fResultType.colWidth = datatypes::MAXDECIMALWIDTH; } else { @@ -696,14 +696,17 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull) case 16: { - int128_t val; - row.getInt128Field(fInputIndex, val); + datatypes::TSInt128 val = row.getTSInt128Field(fInputIndex); - if (val == datatypes::Decimal128Null) + if (val.isNull()) + { isNull = true; + } else { - fResult.decimalVal = IDB_Decimal(0, fResultType.scale, fResultType.precision, val); + fResult.decimalVal = IDB_Decimal(val, + fResultType.scale, + fResultType.precision); } break;