From 0df1a5189f9acc567928ca468b03ec12bb63f239 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Mon, 19 Dec 2016 15:06:04 +0000 Subject: [PATCH] MCOL-389 Add int/string handling for mod() Func_mod uses double instead of int for char casting. This patch adds int handling and uses it where appropriate. --- utils/funcexp/func_mod.cpp | 204 +++++++++++++++++++++++++++++++++++ utils/funcexp/functor_real.h | 15 +++ 2 files changed, 219 insertions(+) diff --git a/utils/funcexp/func_mod.cpp b/utils/funcexp/func_mod.cpp index eae21b4fb..6da3e5a76 100644 --- a/utils/funcexp/func_mod.cpp +++ b/utils/funcexp/func_mod.cpp @@ -176,6 +176,210 @@ double Func_mod::getDoubleVal(Row& row, return mod; } +int64_t Func_mod::getIntVal(Row& row, + FunctionParm& parm, + bool& isNull, + CalpontSystemCatalog::ColType& operationColType) +{ + if ( parm.size() < 2 ) { + isNull = true; + return 0; + } + + int64_t div = parm[1]->data()->getIntVal(row, isNull); + + if ( div == 0 ) { + isNull = true; + return 0; + } + + int64_t mod = 0; + + switch (parm[0]->data()->resultType().colDataType) + { + case execplan::CalpontSystemCatalog::BIGINT: + case execplan::CalpontSystemCatalog::INT: + case execplan::CalpontSystemCatalog::MEDINT: + case execplan::CalpontSystemCatalog::TINYINT: + case execplan::CalpontSystemCatalog::SMALLINT: + case execplan::CalpontSystemCatalog::CHAR: + case execplan::CalpontSystemCatalog::VARCHAR: + { + int64_t value = parm[0]->data()->getIntVal(row, isNull); + + mod = value % div; + } + break; + + case execplan::CalpontSystemCatalog::UBIGINT: + case execplan::CalpontSystemCatalog::UINT: + case execplan::CalpontSystemCatalog::UMEDINT: + case execplan::CalpontSystemCatalog::UTINYINT: + case execplan::CalpontSystemCatalog::USMALLINT: + { + uint64_t udiv = parm[1]->data()->getIntVal(row, isNull); + uint64_t uvalue = parm[0]->data()->getUintVal(row, isNull); + + mod = uvalue % udiv; + } + break; + + case execplan::CalpontSystemCatalog::DOUBLE: + case execplan::CalpontSystemCatalog::UDOUBLE: + { + double value = parm[0]->data()->getDoubleVal(row, isNull); + + mod = fmod(value,div); + } + break; + + case execplan::CalpontSystemCatalog::FLOAT: + case execplan::CalpontSystemCatalog::UFLOAT: + { + float value = parm[0]->data()->getFloatVal(row, isNull); + + mod = fmod(value,div); + } + break; + + case execplan::CalpontSystemCatalog::DECIMAL: + case execplan::CalpontSystemCatalog::UDECIMAL: + { + IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull); + int64_t value = d.value / helpers::power(d.scale); + + mod = value % div; + } + break; + + default: + { + std::ostringstream oss; + oss << "mod: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType); + throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT); + } + } + + return mod; +} + +uint64_t Func_mod::getUIntVal(Row& row, + FunctionParm& parm, + bool& isNull, + CalpontSystemCatalog::ColType& operationColType) +{ + if ( parm.size() < 2 ) { + isNull = true; + return 0; + } + + int64_t div = parm[1]->data()->getIntVal(row, isNull); + + if ( div == 0 ) { + isNull = true; + return 0; + } + + uint64_t mod = 0; + + switch (parm[0]->data()->resultType().colDataType) + { + case execplan::CalpontSystemCatalog::BIGINT: + case execplan::CalpontSystemCatalog::INT: + case execplan::CalpontSystemCatalog::MEDINT: + case execplan::CalpontSystemCatalog::TINYINT: + case execplan::CalpontSystemCatalog::SMALLINT: + case execplan::CalpontSystemCatalog::CHAR: + case execplan::CalpontSystemCatalog::VARCHAR: + { + int64_t value = parm[0]->data()->getIntVal(row, isNull); + + mod = value % div; + } + break; + + case execplan::CalpontSystemCatalog::UBIGINT: + case execplan::CalpontSystemCatalog::UINT: + case execplan::CalpontSystemCatalog::UMEDINT: + case execplan::CalpontSystemCatalog::UTINYINT: + case execplan::CalpontSystemCatalog::USMALLINT: + { + uint64_t udiv = parm[1]->data()->getIntVal(row, isNull); + uint64_t uvalue = parm[0]->data()->getUintVal(row, isNull); + + mod = uvalue % udiv; + } + break; + + case execplan::CalpontSystemCatalog::DOUBLE: + case execplan::CalpontSystemCatalog::UDOUBLE: + { + double value = parm[0]->data()->getDoubleVal(row, isNull); + + mod = fmod(value,div); + } + break; + + case execplan::CalpontSystemCatalog::FLOAT: + case execplan::CalpontSystemCatalog::UFLOAT: + { + float value = parm[0]->data()->getFloatVal(row, isNull); + + mod = fmod(value,div); + } + break; + + case execplan::CalpontSystemCatalog::DECIMAL: + case execplan::CalpontSystemCatalog::UDECIMAL: + { + IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull); + int64_t value = d.value / helpers::power(d.scale); + + mod = value % div; + } + break; + + default: + { + std::ostringstream oss; + oss << "mod: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType); + throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT); + } + } + + return mod; +} + +std::string Func_mod::getStrVal(Row& row, + FunctionParm& fp, + bool& isNull, + CalpontSystemCatalog::ColType& op_ct) +{ + if ( fp.size() < 2 ) { + isNull = true; + return std::string(); + } + + switch (fp[0]->data()->resultType().colDataType) + { + case execplan::CalpontSystemCatalog::BIGINT: + case execplan::CalpontSystemCatalog::INT: + case execplan::CalpontSystemCatalog::MEDINT: + case execplan::CalpontSystemCatalog::TINYINT: + case execplan::CalpontSystemCatalog::SMALLINT: + case execplan::CalpontSystemCatalog::UBIGINT: + case execplan::CalpontSystemCatalog::UINT: + case execplan::CalpontSystemCatalog::UMEDINT: + case execplan::CalpontSystemCatalog::UTINYINT: + case execplan::CalpontSystemCatalog::USMALLINT: + return intToString(getIntVal(row, fp, isNull, op_ct)); + break; + + default: + return doubleToString(getDoubleVal(row, fp, isNull, op_ct)); + break; + } +} } // namespace funcexp // vim:ts=4 sw=4: diff --git a/utils/funcexp/functor_real.h b/utils/funcexp/functor_real.h index ebc2d08eb..e90a2ecf9 100644 --- a/utils/funcexp/functor_real.h +++ b/utils/funcexp/functor_real.h @@ -323,6 +323,21 @@ public: FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); + + int64_t getIntVal(rowgroup::Row& row, + FunctionParm& parm, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& operationColType); + + uint64_t getUIntVal(rowgroup::Row& row, + FunctionParm& parm, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& operationColType); + + std::string getStrVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); };