diff --git a/datatypes/mcs_decimal.h b/datatypes/mcs_decimal.h index b87db7ebf..94aa2a50b 100644 --- a/datatypes/mcs_decimal.h +++ b/datatypes/mcs_decimal.h @@ -82,7 +82,7 @@ constexpr uint8_t MAXLEGACYWIDTH = 8U; constexpr uint8_t MAXSCALEINC4AVG = 4U; constexpr int8_t IGNOREPRECISION = -1; -const int64_t mcs_pow_10[19] = +const uint64_t mcs_pow_10[20] = { 1ULL, 10ULL, @@ -103,6 +103,7 @@ const int64_t mcs_pow_10[19] = 10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL, + 10000000000000000000ULL, }; const int128_t mcs_pow_10_128[20] = { diff --git a/dbcon/execplan/windowfunctioncolumn.cpp b/dbcon/execplan/windowfunctioncolumn.cpp index 21f09aa06..a6ba127fa 100644 --- a/dbcon/execplan/windowfunctioncolumn.cpp +++ b/dbcon/execplan/windowfunctioncolumn.cpp @@ -52,8 +52,6 @@ using namespace rowgroup; #include "joblisttypes.h" using namespace joblist; -#include "widedecimalutils.h" - #ifdef _MSC_VER #define strcasecmp stricmp #endif @@ -389,7 +387,8 @@ void WindowFunctionColumn::adjustResultType() if (boost::iequals(fFunctionName, "SUM") || boost::iequals(fFunctionName, "AVG") || - boost::iequals(fFunctionName, "AVG_DISTINCT")) + boost::iequals(fFunctionName, "AVG_DISTINCT") || + boost::iequals(fFunctionName, "PERCENTILE")) { if (fFunctionParms[0]->resultType().colDataType == CalpontSystemCatalog::DECIMAL || fFunctionParms[0]->resultType().colDataType == CalpontSystemCatalog::UDECIMAL) @@ -689,7 +688,7 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull) case 16: { int128_t dec = row.getInt128Field(fInputIndex); - if (utils::isWideDecimalNullValue(dec)) + if (dec == datatypes::Decimal128Null) isNull = true; else { diff --git a/utils/regr/moda.cpp b/utils/regr/moda.cpp index e1bc44a9a..7bc5b427d 100644 --- a/utils/regr/moda.cpp +++ b/utils/regr/moda.cpp @@ -21,6 +21,7 @@ #include "moda.h" #include "bytestream.h" #include "objectreader.h" +#include "columnwidth.h" using namespace mcsv1sdk; @@ -186,7 +187,7 @@ mcsv1_UDAF::ReturnCode moda::init(mcsv1Context* context, { context->setColWidth(8); } - else + else if (utils::widthByPrecision(colTypes[0].precision)) { context->setColWidth(16); } diff --git a/utils/rowgroup/rowgroup.h b/utils/rowgroup/rowgroup.h index 669220c21..748bf3dfa 100644 --- a/utils/rowgroup/rowgroup.h +++ b/utils/rowgroup/rowgroup.h @@ -962,11 +962,15 @@ inline long double Row::getLongDoubleField(uint32_t colIndex) const return *((long double*) &data[offsets[colIndex]]); } +// !!! Never ever try to remove inline from this f() b/c it returns +// non-integral 16 byte DT inline int128_t Row::getInt128Field(uint32_t colIndex) const { return *((int128_t*) &data[offsets[colIndex]]); } +// !!! Never ever try to remove inline from this f() b/c it returns +// non-integral 16 byte DT inline uint128_t Row::getUint128Field(uint32_t colIndex) const { return *((uint128_t*) &data[offsets[colIndex]]); diff --git a/utils/windowfunction/idborderby.cpp b/utils/windowfunction/idborderby.cpp index 6814ed4ad..1028d3e1d 100644 --- a/utils/windowfunction/idborderby.cpp +++ b/utils/windowfunction/idborderby.cpp @@ -856,11 +856,11 @@ bool EqualCompData::operator()(Row::Pointer a, Row::Pointer b) case CalpontSystemCatalog::UDECIMAL: { // equal compare. ignore sign and null - if (fRow1.getColumnWidth(*i) < 16) + if (fRow1.getColumnWidth(*i) < datatypes::MAXDECIMALWIDTH) { eq = (fRow1.getUintField(*i) == fRow2.getUintField(*i)); } - else + else if (fRow1.getColumnWidth(*i) == datatypes::MAXDECIMALWIDTH) { eq = (fRow1.getUint128Field(*i) == fRow2.getUint128Field(*i)); } diff --git a/utils/windowfunction/wf_count.cpp b/utils/windowfunction/wf_count.cpp index d7e9b104e..29987c3b4 100644 --- a/utils/windowfunction/wf_count.cpp +++ b/utils/windowfunction/wf_count.cpp @@ -78,11 +78,11 @@ boost::shared_ptr WF_count::makeFunction(int id, const st case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < 16) + if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) { func.reset(new WF_count(id, name)); } - else + else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_count(id, name)); } diff --git a/utils/windowfunction/wf_lead_lag.cpp b/utils/windowfunction/wf_lead_lag.cpp index f8aa32ca1..1a1b453cd 100644 --- a/utils/windowfunction/wf_lead_lag.cpp +++ b/utils/windowfunction/wf_lead_lag.cpp @@ -85,11 +85,11 @@ boost::shared_ptr WF_lead_lag::makeFunction(int id, const case CalpontSystemCatalog::DECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < 16) + if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) { func.reset(new WF_lead_lag(id, name)); } - else + else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_lead_lag(id, name)); } diff --git a/utils/windowfunction/wf_nth_value.cpp b/utils/windowfunction/wf_nth_value.cpp index 73b0bf1be..41dde88fb 100644 --- a/utils/windowfunction/wf_nth_value.cpp +++ b/utils/windowfunction/wf_nth_value.cpp @@ -84,31 +84,19 @@ boost::shared_ptr WF_nth_value::makeFunction(int id, cons } case CalpontSystemCatalog::DECIMAL: + case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < 16) + if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) { func.reset(new WF_nth_value(id, name)); } - else + else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_nth_value(id, name)); } break; } - case CalpontSystemCatalog::UDECIMAL: - { - if (wc->functionParms()[0]->resultType().colWidth < 16) - { - func.reset(new WF_nth_value(id, name)); - } - else - { - func.reset(new WF_nth_value(id, name)); - } - break; - } - case CalpontSystemCatalog::DOUBLE: case CalpontSystemCatalog::UDOUBLE: { diff --git a/utils/windowfunction/wf_percentile.cpp b/utils/windowfunction/wf_percentile.cpp index 8aaeba9f6..a407d41e8 100644 --- a/utils/windowfunction/wf_percentile.cpp +++ b/utils/windowfunction/wf_percentile.cpp @@ -46,6 +46,8 @@ using namespace ordering; #include "constantcolumn.h" using namespace execplan; +#include "mcs_decimal.h" + #include "windowfunctionstep.h" using namespace joblist; @@ -89,31 +91,19 @@ boost::shared_ptr WF_percentile::makeFunction(int id, con } case CalpontSystemCatalog::DECIMAL: + case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < 16) + if (wc->resultType().colWidth < datatypes::MAXDECIMALWIDTH) { func.reset(new WF_percentile(id, name)); } - else + else if (wc->resultType().colWidth == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_percentile(id, name)); } break; } - case CalpontSystemCatalog::UDECIMAL: - { - if (wc->functionParms()[0]->resultType().colWidth < 16) - { - func.reset(new WF_percentile(id, name)); - } - else - { - func.reset(new WF_percentile(id, name)); - } - break; - } - case CalpontSystemCatalog::DOUBLE: case CalpontSystemCatalog::UDOUBLE: { diff --git a/utils/windowfunction/wf_stats.cpp b/utils/windowfunction/wf_stats.cpp index 1804ad432..0dee4fa9e 100644 --- a/utils/windowfunction/wf_stats.cpp +++ b/utils/windowfunction/wf_stats.cpp @@ -82,30 +82,18 @@ boost::shared_ptr WF_stats::makeFunction(int id, const st } case CalpontSystemCatalog::DECIMAL: + case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < 16) + if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) { func.reset(new WF_stats(id, name)); } - else + else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_stats(id, name)); } break; } - - case CalpontSystemCatalog::UDECIMAL: - { - if (wc->functionParms()[0]->resultType().colWidth < 16) - { - func.reset(new WF_stats(id, name)); - } - else - { - func.reset(new WF_stats(id, name)); - } - break; - } case CalpontSystemCatalog::DOUBLE: case CalpontSystemCatalog::UDOUBLE: diff --git a/utils/windowfunction/wf_sum_avg.cpp b/utils/windowfunction/wf_sum_avg.cpp index b61fb9928..007bb1fc7 100644 --- a/utils/windowfunction/wf_sum_avg.cpp +++ b/utils/windowfunction/wf_sum_avg.cpp @@ -52,35 +52,49 @@ using namespace joblist; namespace windowfunction { -template -void WF_sum_avg::checkSumLimit(long double val, long double sum) -{ -} template -inline void WF_sum_avg::checkSumLimit(int128_t val, int128_t sum) +inline void WF_sum_avg::checkSumLimit(T_IN& val, T_OUT& sum) +{ } + +template<> +inline void WF_sum_avg::checkSumLimit(int128_t& val, int128_t& sum) { - if (((sum >= 0) && ((fMax128 - sum) < val)) || - ((sum < 0) && ((fMin128 - sum) > val))) - { - string errStr = "SUM(int128_t)"; - errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_OVERFLOW, errStr); - cerr << errStr << endl; - throw IDBExcept(errStr, ERR_WF_OVERFLOW); - } + datatypes::AdditionOverflowCheck ofCheckOp; + ofCheckOp(sum, val); } -template -inline void WF_sum_avg::checkSumLimit(uint128_t val, uint128_t sum) -{ - if ((fMaxu128 - sum) < val) - { - string errStr = "SUM(uint128_t)"; - errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_OVERFLOW, errStr); - cerr << errStr << endl; - throw IDBExcept(errStr, ERR_WF_OVERFLOW); - } -} +template<> +inline void WF_sum_avg::checkSumLimit(long double& val, long double& sum) +{ } + +template<> +inline void WF_sum_avg::checkSumLimit(float&, long double&) +{ } + +template<> +inline void WF_sum_avg::checkSumLimit(long&, long double&) +{ } + +template<> +inline void WF_sum_avg::checkSumLimit(unsigned long&, long double&) +{ } +template<> +inline void WF_sum_avg::checkSumLimit(double&, long double&) +{ } + +template<> +void WF_sum_avg::checkSumLimit(int128_t& val, int128_t& sum); +template<> +void WF_sum_avg::checkSumLimit(long double& val, long double& sum); +template<> +void WF_sum_avg::checkSumLimit(float&, long double&); +template<> +void WF_sum_avg::checkSumLimit(long&, long double&); +template<> +void WF_sum_avg::checkSumLimit(unsigned long&, long double&); +template<> +void WF_sum_avg::checkSumLimit(double&, long double&); template int128_t WF_sum_avg::calculateAvg(int128_t sum, uint64_t count, int scale) @@ -118,41 +132,6 @@ int128_t WF_sum_avg::calculateAvg(int128_t sum, uint64_t count, int return avg; } -template -uint128_t WF_sum_avg::calculateAvg(uint128_t sum, uint64_t count, int scale) -{ - uint128_t avg = 0; - uint128_t factor; - datatypes::getScaleDivisor(factor, scale); - if (scale > 0) - { - if ((sum * factor) / factor == sum) - { - avg = sum * factor; - avg /= count; - } - else - { - // scale won't fit before divide, we're gonna lose precision. - avg = sum / count; - if ((avg * factor) / factor != avg) // Still won't fit - { - string errStr = string("AVG(int)"); - errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_OVERFLOW, errStr); - cerr << errStr << endl; - throw IDBExcept(errStr, ERR_WF_OVERFLOW); - } - avg *= factor; - } - } - else - { - avg = sum / count; - } - avg += 0.5; - return avg; -} - template inline long double WF_sum_avg::calculateAvg(long double sum, uint64_t count, int scale) { @@ -188,31 +167,19 @@ boost::shared_ptr WF_sum_avg::makeFunction(int } case CalpontSystemCatalog::DECIMAL: + case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < 16) + if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) { func.reset(new WF_sum_avg(id, name)); } - else + else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_sum_avg(id, name)); } break; } - case CalpontSystemCatalog::UDECIMAL: - { - if (wc->functionParms()[0]->resultType().colWidth < 16) - { - func.reset(new WF_sum_avg(id, name)); - } - else - { - func.reset(new WF_sum_avg(id, name)); - } - break; - } - case CalpontSystemCatalog::DOUBLE: case CalpontSystemCatalog::UDOUBLE: { diff --git a/utils/windowfunction/wf_sum_avg.h b/utils/windowfunction/wf_sum_avg.h index b86a9c16d..6ecc37314 100644 --- a/utils/windowfunction/wf_sum_avg.h +++ b/utils/windowfunction/wf_sum_avg.h @@ -39,9 +39,6 @@ public: WindowFunctionType(id, name), fDistinct(id != WF__SUM && id != WF__AVG) { resetData(); - utils::int128Max(fMax128); - utils::int128Min(fMin128); - utils::uint128Max(fMaxu128); } // pure virtual in base @@ -58,19 +55,17 @@ protected: uint64_t fCount; bool fDistinct; std::set fSet; - int128_t fMax128; - int128_t fMin128; - uint128_t fMaxu128; - void checkSumLimit(long double val, long double sum); - void checkSumLimit(int128_t val, int128_t sum); - void checkSumLimit(uint128_t val, uint128_t sum); - + void checkSumLimit(T_IN& val, T_OUT& sum); + int128_t calculateAvg(int128_t sum, uint64_t count, int scale); - uint128_t calculateAvg(uint128_t sum, uint64_t count, int scale); long double calculateAvg(long double sum, uint64_t count, int scale); }; +template<> +void WF_sum_avg::checkSumLimit(long double& val, long double& sum); + + } // namespace #endif // UTILS_WF_SUM_AVG_H diff --git a/writeengine/server/we_dmlcommandproc.cpp b/writeengine/server/we_dmlcommandproc.cpp index dbbc5162c..0a17d5128 100644 --- a/writeengine/server/we_dmlcommandproc.cpp +++ b/writeengine/server/we_dmlcommandproc.cpp @@ -423,7 +423,7 @@ uint8_t WE_DMLCommandProc::processSingleInsert(messageqcpp::ByteStream& bs, std: // call the write engine to write the rows int error = NO_ERROR; - // WIP + // MCOL-641 WIP fWEWrapper.setDebugLevel(WriteEngine::DEBUG_3); cout << "inserting a row with transaction id " << txnid.id << endl; fWEWrapper.setIsInsert(true);