diff --git a/datatypes/CMakeLists.txt b/datatypes/CMakeLists.txt index b632a9392..c74eaf7fc 100644 --- a/datatypes/CMakeLists.txt +++ b/datatypes/CMakeLists.txt @@ -1,6 +1,7 @@ include_directories( ${ENGINE_COMMON_INCLUDES} ) set(datatypes_LIB_SRCS + mcs_int128.cpp mcs_decimal.cpp) add_library(datatypes SHARED ${datatypes_LIB_SRCS}) diff --git a/datatypes/mcs_decimal.cpp b/datatypes/mcs_decimal.cpp index f66cc68ef..9da2894c5 100644 --- a/datatypes/mcs_decimal.cpp +++ b/datatypes/mcs_decimal.cpp @@ -198,6 +198,14 @@ namespace datatypes std::string Decimal::toString(VDecimal& value) { char buf[Decimal::MAXLENGTH16BYTES]; + if (value.s128Value == Decimal128Null) + { + return std::string("NULL"); + } + else if (value.s128Value == Decimal128Empty) + { + return std::string("EMPTY"); + } dataconvert::DataConvert::decimalToString(&value.s128Value, value.scale, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL); @@ -209,6 +217,23 @@ namespace datatypes return toString(const_cast(value)); } + std::string Decimal::toString(const int128_t& value) + { + char buf[Decimal::MAXLENGTH16BYTES]; + if (value == Decimal128Null) + { + return std::string("NULL"); + } + else if (value == Decimal128Empty) + { + return std::string("EMPTY"); + } + int128_t& constLessValue = const_cast(value); + dataconvert::DataConvert::decimalToString(&constLessValue, + 0, buf, sizeof(buf), datatypes::SystemCatalog::DECIMAL); + return std::string(buf); + } + int Decimal::compare(const VDecimal& l, const VDecimal& r) { int128_t divisorL, divisorR; diff --git a/datatypes/mcs_decimal.h b/datatypes/mcs_decimal.h index b2fd8a225..3731f1cd6 100644 --- a/datatypes/mcs_decimal.h +++ b/datatypes/mcs_decimal.h @@ -24,11 +24,12 @@ #include "mcs_basic_types.h" #include "exceptclasses.h" #include "widedecimalutils.h" +#include "mcs_int128.h" namespace datatypes { - struct VDecimal; + class VDecimal; } // A class by Fabio Fernandes pulled off of stackoverflow @@ -259,10 +260,11 @@ class Decimal VDecimal& result); /** - @brief Convenience method to put decimal into a std::string. + @brief Convenience methods to put decimal into a std::string. */ static std::string toString(VDecimal& value); static std::string toString(const VDecimal& value); + static std::string toString(const int128_t& value); /** @brief The method detects whether decimal type is wide @@ -339,20 +341,7 @@ class Decimal return static_cast(value); } - /** - @brief The method converts a __float128 value to a double. - */ - static inline double getDoubleFromFloat128(const __float128& value) - { - if (value > static_cast<__float128>(DBL_MAX)) - return DBL_MAX; - else if (value < -static_cast<__float128>(DBL_MAX)) - return -DBL_MAX; - - return static_cast(value); - } - - /** + /** @brief The method converts a wide decimal value to a double. */ static inline double getDoubleFromWideDecimal(const int128_t& value, int8_t scale) @@ -374,19 +363,6 @@ class Decimal return getDoubleFromFloat128(static_cast<__float128>(value)); } - /** - @brief The method converts a __float128 value to a long double. - */ - static inline long double getLongDoubleFromFloat128(const __float128& value) - { - if (value > static_cast<__float128>(LDBL_MAX)) - return LDBL_MAX; - else if (value < -static_cast<__float128>(LDBL_MAX)) - return -LDBL_MAX; - - return static_cast(value); - } - /** @brief The method converts a wide decimal value to a long double. */ @@ -568,19 +544,19 @@ struct NoOverflowCheck { * @brief VDecimal type * */ -struct VDecimal +class VDecimal: public TSInt128 { - VDecimal(): s128Value(0), value(0), scale(0), precision(0) + public: + VDecimal(): value(0), scale(0), precision(0) { } VDecimal(int64_t val, int8_t s, uint8_t p, const int128_t &val128 = 0) : - s128Value(val128), + TSInt128(val128), value(val), scale(s), precision(p) - { - } + { } int decimalComp(const VDecimal& d) const { @@ -843,7 +819,6 @@ struct VDecimal } } - int128_t s128Value; int64_t value; int8_t scale; // 0~38 uint8_t precision; // 1~38 diff --git a/datatypes/mcs_int128.cpp b/datatypes/mcs_int128.cpp new file mode 100644 index 000000000..abaa9a27f --- /dev/null +++ b/datatypes/mcs_int128.cpp @@ -0,0 +1,82 @@ +/* + Copyright (C) 2020 MariaDB Corporation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. +*/ + +#include "mcs_int128.h" + +namespace datatypes +{ + // The method converts a wide decimal s128Value to a double. + inline double TSInt128::getDoubleFromWideDecimal() + { + return getDoubleFromFloat128(static_cast<__float128>(s128Value)); + } + + // The method converts a wide decimal s128Value to a long double. + inline long double TSInt128::getLongDoubleFromWideDecimal() + { + return getLongDoubleFromFloat128(static_cast<__float128>(s128Value)); + } + + // The method converts a wide decimal s128Value to an int64_t, + // saturating the s128Value if necessary. + inline int64_t TSInt128::getInt64FromWideDecimal() + { + if (s128Value > static_cast(INT64_MAX)) + return INT64_MAX; + else if (s128Value < static_cast(INT64_MIN)) + return INT64_MIN; + + return static_cast(s128Value); + } + + // The method converts a wide decimal s128Value to an uint32_t. + inline uint32_t TSInt128::getUInt32FromWideDecimal() + { + if (s128Value > static_cast(UINT32_MAX)) + return UINT32_MAX; + else if (s128Value < 0) + return 0; + + return static_cast(s128Value); + } + + // The method converts a wide decimal s128Value to an uint64_t. + inline uint64_t TSInt128::getUInt64FromWideDecimal() + { + if (s128Value > static_cast(UINT64_MAX)) + return UINT64_MAX; + else if (s128Value < 0) + return 0; + + return static_cast(s128Value); + } + + // The method converts a wide decimal s128Value to an int32_t. + inline int32_t TSInt128::getInt32FromWideDecimal() + { + if (s128Value > static_cast(INT32_MAX)) + return INT32_MAX; + else if (s128Value < static_cast(INT32_MIN)) + return INT32_MIN; + + return static_cast(s128Value); + } + +} // end of namespace datatypes +// vim:ts=2 sw=2: diff --git a/datatypes/mcs_int128.h b/datatypes/mcs_int128.h new file mode 100644 index 000000000..ef8a3e262 --- /dev/null +++ b/datatypes/mcs_int128.h @@ -0,0 +1,187 @@ +/* + Copyright (C) 2020 MariaDB Corporation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. +*/ +#ifndef MCS_INT128_H_INCLUDED +#define MCS_INT128_H_INCLUDED + +#include +#include +#include +#include + +// Inline asm has three argument lists: output, input and clobber list +#if defined(__GNUC__) && (__GNUC___ > 7) + #define MACRO_VALUE_PTR_128(dst, \ + dst_restrictions, \ + src, \ + src_restrictions, \ + clobb) \ + __asm__ volatile("movups %1,%0" \ + :dst_restrictions ( *(dst) ) \ + :src_restrictions ( (src) ) \ + :clobb \ + ); + #define MACRO_PTR_PTR_128(dst, \ + dst_restrictions, \ + src, \ + src_restrictions, \ + clobb) \ + ::memcpy((dst), (src), sizeof(int128_t)); + +#else + #define MACRO_VALUE_PTR_128(dst, \ + dst_restrictions, \ + src, \ + src_restrictions, \ + clobb) \ + __asm__ volatile("movups %1,%0" \ + :dst_restrictions ( *(dst) ) \ + :src_restrictions ( (src) ) \ + :clobb \ + ); + #define MACRO_PTR_PTR_128(dst, \ + dst_restrictions, \ + src, \ + src_restrictions, \ + clobb) \ + __asm__ volatile("movdqu %1,%%xmm0;" \ + "movups %%xmm0,%0;" \ + :dst_restrictions ( *(dst) ) \ + :src_restrictions ( *(src) ) \ + :"memory", clobb \ + ); +#endif + +namespace datatypes +{ + +using int128_t = __int128; + + +// Type traits +template +struct is_allowed_numeric { + static const bool value = false; +}; + +template <> +struct is_allowed_numeric { + static const bool value = true; +}; + +template <> +struct is_allowed_numeric { + static const bool value = true; +}; + +// The method converts a __float128 s128Value to a double. +static inline double getDoubleFromFloat128(const __float128& value) +{ + if (value > static_cast<__float128>(DBL_MAX)) + return DBL_MAX; + else if (value < -static_cast<__float128>(DBL_MAX)) + return -DBL_MAX; + + return static_cast(value); +} + + +// The method converts a __float128 value to a long double. +static inline long double getLongDoubleFromFloat128(const __float128& value) +{ + if (value > static_cast<__float128>(LDBL_MAX)) + return LDBL_MAX; + else if (value < -static_cast<__float128>(LDBL_MAX)) + return -LDBL_MAX; + + return static_cast(value); +} + + +class TSInt128 +{ + public: + // A variety of ctors for aligned and unaligned arguments + TSInt128(): s128Value(0) { } + + // aligned argument + TSInt128(const int128_t& x) { s128Value = x; } + + // unaligned argument + TSInt128(const int128_t* x) { assignPtrPtr(&s128Value, x); } + + // unaligned argument + TSInt128(const unsigned char* x) { assignPtrPtr(&s128Value, x); } + + // The method copies 16 bytes from one memory cell + // into another using memcpy or SIMD. + // memcpy in gcc >= 7 is replaced with SIMD instructions + template + static inline void assignPtrPtr(D* dst, const S* src) + { + MACRO_PTR_PTR_128(dst, "=m", src, "m", "xmm0") + } + + template + static inline void storeUnaligned(D* dst, const int128_t& src) + { + MACRO_VALUE_PTR_128(dst, "=m", src, "x", "memory") + } + + // operators + template::value> > + inline bool operator<(const T& x) const + { + return s128Value < static_cast(x); + } + + template::value> > + inline bool operator==(const T& x) const + { + return s128Value == static_cast(x); + } + + // The method converts a wide decimal s128Value to a double. + inline double getDoubleFromWideDecimal(); + + // The method converts a wide decimal s128Value to a long double. + inline long double getLongDoubleFromWideDecimal(); + + // The method converts a wide decimal s128Value to an int64_t, + // saturating the s128Value if necessary. + inline int64_t getInt64FromWideDecimal(); + + // The method converts a wide decimal s128Value to an uint32_t. + inline uint32_t getUInt32FromWideDecimal(); + + // The method converts a wide decimal s128Value to an uint64_t. + inline uint64_t getUInt64FromWideDecimal(); + + // The method converts a wide decimal s128Value to an int32_t. + inline int32_t getInt32FromWideDecimal(); + + int128_t s128Value; + }; // end of class + + +} //end of namespace datatypes + +#endif // MCS_TSINT128_H_INCLUDED +// vim:ts=2 sw=2: diff --git a/dbcon/execplan/simplecolumn.cpp b/dbcon/execplan/simplecolumn.cpp index 7201a366c..64620cb15 100644 --- a/dbcon/execplan/simplecolumn.cpp +++ b/dbcon/execplan/simplecolumn.cpp @@ -635,8 +635,8 @@ void SimpleColumn::evaluate(Row& row, bool& isNull) { case 16: { - fResult.decimalVal.s128Value = - *row.getBinaryField_offset(fInputOffset); + datatypes::TSInt128::assignPtrPtr(&fResult.decimalVal.s128Value, + row.getBinaryField_offset(fInputOffset)); break; } case 1: diff --git a/dbcon/execplan/treenode.h b/dbcon/execplan/treenode.h index ad35f1768..6b2958bff 100644 --- a/dbcon/execplan/treenode.h +++ b/dbcon/execplan/treenode.h @@ -61,6 +61,12 @@ class IDB_Decimal: public datatypes::VDecimal { public: using datatypes::VDecimal::VDecimal; + + inline void operator=(const datatypes::TSInt128& rhs) + { + value = 0; scale = 0; precision = 0; + datatypes::TSInt128::operator=(rhs); + } }; diff --git a/dbcon/execplan/windowfunctioncolumn.cpp b/dbcon/execplan/windowfunctioncolumn.cpp index a6ba127fa..c16c7b44b 100644 --- a/dbcon/execplan/windowfunctioncolumn.cpp +++ b/dbcon/execplan/windowfunctioncolumn.cpp @@ -687,12 +687,12 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull) case 16: { - int128_t dec = row.getInt128Field(fInputIndex); + datatypes::TSInt128 dec(row.getBinaryField(fInputIndex)); if (dec == datatypes::Decimal128Null) isNull = true; else { - fResult.decimalVal.s128Value = dec; + fResult.decimalVal = dec; fResult.decimalVal.scale = (unsigned)fResultType.scale; } diff --git a/dbcon/joblist/batchprimitiveprocessor-jl.cpp b/dbcon/joblist/batchprimitiveprocessor-jl.cpp index aff8f4e8b..1f5707358 100644 --- a/dbcon/joblist/batchprimitiveprocessor-jl.cpp +++ b/dbcon/joblist/batchprimitiveprocessor-jl.cpp @@ -736,7 +736,7 @@ void BatchPrimitiveProcessorJL::getRowGroupData(ByteStream& in, vector* uint32_t threadID, bool* hasWideColumn, const execplan::CalpontSystemCatalog::ColType& colType) const { uint64_t tmp64; - uint128_t tmp128; + int128_t tmp128; uint8_t tmp8; RGData rgData; uint32_t rowCount; diff --git a/dbcon/joblist/lbidlist.cpp b/dbcon/joblist/lbidlist.cpp index 36725dc8e..60180c8f8 100644 --- a/dbcon/joblist/lbidlist.cpp +++ b/dbcon/joblist/lbidlist.cpp @@ -236,23 +236,15 @@ bool LBIDList::GetMinMax(T& min, T& max, int64_t& seq, int64_t lbid, if (isUnsigned(colDataType)) { - if (typeid(T) == typeid(int128_t)) - { - mmp->bigMax = 0; - mmp->bigMin = -1; - } - else - { - mmp->max = 0; - mmp->min = static_cast(numeric_limits::max()); - } + mmp->max = 0; + mmp->min = static_cast(numeric_limits::max()); } else { if (typeid(T) == typeid(int128_t)) { - utils::int128Min(mmp->bigMax); - utils::int128Max(mmp->bigMin); + mmp->bigMax = datatypes::Decimal::minInt128; + mmp->bigMin = datatypes::Decimal::maxInt128; } else { @@ -296,23 +288,15 @@ bool LBIDList::GetMinMax(T* min, T* max, int64_t* seq, if (isUnsigned(colDataType)) { - if (typeid(T) == typeid(int128_t)) - { - mmp->bigMax = 0; - mmp->bigMin = -1; - } - else - { - mmp->max = 0; - mmp->min = static_cast(numeric_limits::max()); - } + mmp->max = 0; + mmp->min = static_cast(numeric_limits::max()); } else { if (typeid(T) == typeid(int128_t)) { - utils::int128Min(mmp->bigMax); - utils::int128Max(mmp->bigMin); + mmp->bigMax = datatypes::Decimal::minInt128; + mmp->bigMin = datatypes::Decimal::maxInt128; } else { @@ -327,6 +311,7 @@ bool LBIDList::GetMinMax(T* min, T* max, int64_t* seq, return false; } + // *DRRTUY min/max should be 16 aligned here if (typeid(T) == typeid(int128_t)) { *min = entry.partition.cprange.bigLoVal; @@ -356,6 +341,7 @@ int LBIDList::getMinMaxFromEntries(T& min, T& max, int32_t& seq, if (lbid >= EMEntries[i].range.start && lbid <= lastLBID) { + // *DRRTUY min/max should be 16 aligned here if (typeid(T) == typeid(int128_t)) { min = EMEntries[i].partition.cprange.bigLoVal; @@ -426,32 +412,25 @@ void LBIDList::UpdateMinMax(T min, T max, int64_t lbid, CalpontSystemCatalog::Co } else if (datatypes::isUnsigned(type)) { - if (typeid(T) == typeid(int128_t)) - { - if (static_cast(min) < static_cast(mmp->bigMin)) - mmp->bigMin = min; + if (static_cast(min) < static_cast(mmp->min)) + mmp->min = min; - if (static_cast(max) > static_cast(mmp->bigMax)) - mmp->bigMax = max; - } - else - { - if (static_cast(min) < static_cast(mmp->min)) - mmp->min = min; - - if (static_cast(max) > static_cast(mmp->max)) - mmp->max = max; - } + if (static_cast(max) > static_cast(mmp->max)) + mmp->max = max; } else { if (typeid(T) == typeid(int128_t)) { if (min < mmp->bigMin) + { mmp->bigMin = min; + } if (max > mmp->bigMax) + { mmp->bigMax = max; + } } else { @@ -694,16 +673,8 @@ bool LBIDList::checkSingleValue(T min, T max, T value, } else if (isUnsigned(type)) { - if (typeid(T) == typeid(int128_t)) - { - return (static_cast(value) >= static_cast(min) && - static_cast(value) <= static_cast(max)); - } - else - { - return (static_cast(value) >= static_cast(min) && - static_cast(value) <= static_cast(max)); - } + return (static_cast(value) >= static_cast(min) && + static_cast(value) <= static_cast(max)); } else { @@ -727,16 +698,8 @@ bool LBIDList::checkRangeOverlap(T min, T max, T tmin, T tmax, } else if (isUnsigned(type)) { - if (typeid(T) == typeid(int128_t)) - { - return (static_cast(tmin) <= static_cast(max) && - static_cast(tmax) >= static_cast(min)); - } - else - { - return (static_cast(tmin) <= static_cast(max) && - static_cast(tmax) >= static_cast(min)); - } + return (static_cast(tmin) <= static_cast(max) && + static_cast(tmax) >= static_cast(min)); } else { @@ -806,13 +769,6 @@ bool LBIDList::CasualPartitionPredicate(const BRM::EMCasualPartition_t& cpRange, value = static_cast(val); break; } - - case 16: - { - uint128_t val = *(int128_t*)MsgDataPtr; - bigValue = static_cast(val); - break; - } } } else @@ -849,21 +805,17 @@ bool LBIDList::CasualPartitionPredicate(const BRM::EMCasualPartition_t& cpRange, case 16: { - int128_t val = *(int128_t*)MsgDataPtr; - bigValue = val; + datatypes::TSInt128::assignPtrPtr(&bigValue, MsgDataPtr); break; } } } - // Should we also check for empty here? - // TODO MCOL-641 - if (ct.isWideDecimalType()) + if (ct.isWideDecimalType() && execplan::isNull(bigValue, ct)) { - if (isNull(bigValue, ct)) continue; } - else if (isNull(value, ct)) // This will work even if the data column is unsigned. + else if (execplan::isNull(value, ct)) // This will work even if the data column is unsigned. { continue; } @@ -885,14 +837,7 @@ bool LBIDList::CasualPartitionPredicate(const BRM::EMCasualPartition_t& cpRange, } else if (bIsUnsigned) { - if (ct.colWidth != datatypes::MAXDECIMALWIDTH) - { - scan = compareVal(static_cast(cpRange.loVal), static_cast(cpRange.hiVal), static_cast(value), op, lcf); - } - else - { - scan = compareVal(static_cast(cpRange.bigLoVal), static_cast(cpRange.bigHiVal), static_cast(bigValue), op, lcf); - } + scan = compareVal(static_cast(cpRange.loVal), static_cast(cpRange.hiVal), static_cast(value), op, lcf); } else { diff --git a/dbcon/joblist/lbidlist.h b/dbcon/joblist/lbidlist.h index 0f1925332..1d666cccf 100644 --- a/dbcon/joblist/lbidlist.h +++ b/dbcon/joblist/lbidlist.h @@ -91,7 +91,7 @@ public: // Functions to handle min/max values per lbid for casual partitioning; // If pEMEntries is provided, then min/max will be extracted from that // vector, else extents in BRM will be searched. If type is unsigned, caller - // should static cast returned min and max to uint64_t/uint128_t + // should static cast returned min and max to uint64_t/int128_t template bool GetMinMax(T& min, T& max, int64_t& seq, int64_t lbid, const std::vector* pEMEntries, diff --git a/primitives/linux-port/column.cpp b/primitives/linux-port/column.cpp index 11bbe07ce..a048d984e 100644 --- a/primitives/linux-port/column.cpp +++ b/primitives/linux-port/column.cpp @@ -42,6 +42,7 @@ using namespace boost; #include "primproc.h" #include "dataconvert.h" #include "mcs_decimal.h" + using namespace logging; using namespace dbbc; using namespace primitives; @@ -765,6 +766,8 @@ inline void store(const NewColRequestHeader* in, default: std::cout << __func__ << " WARNING!!! unspecified column width." << std::endl; + [[fallthrough]]; + case 8: ptr2 += (rid << 3); memcpy(ptr1, ptr2, 8); @@ -1723,22 +1726,31 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, // Set the min and max if necessary. Ignore nulls. if (out->ValidMinMax && !isNull && !isEmpty) { + if (in->DataType == CalpontSystemCatalog::CHAR || in->DataType == CalpontSystemCatalog::VARCHAR) { // !!! colCompare is overloaded with int128_t only yet. if (colCompare(out->Min, val, COMPARE_GT, false, in->DataType, W, placeholderRegex)) + { out->Min = val; + } if (colCompare(out->Max, val, COMPARE_LT, false, in->DataType, W, placeholderRegex)) + { out->Max = val; + } } else { if (out->Min > val) + { out->Min = val; + } if (out->Max < val) + { out->Max = val; + } } } @@ -1828,6 +1840,7 @@ void PrimitiveProcessor::p_Col(NewColRequestHeader* in, NewColResultHeader* out, case 32: std::cout << __func__ << " WARNING!!! Not implemented for 32 byte data types." << std::endl; + [[fallthrough]]; default: idbassert(0); @@ -1918,7 +1931,7 @@ boost::shared_ptr parseColumnFilter case 8: ret->prestored_argVals[argIndex] = *reinterpret_cast(args->val); - break; + break; } } else @@ -1956,7 +1969,11 @@ boost::shared_ptr parseColumnFilter break; case 16: - ret->prestored_argVals128[argIndex] = *reinterpret_cast(args->val); + { + datatypes::TSInt128::assignPtrPtr(&(ret->prestored_argVals128[argIndex]), + args->val); + break; + } } } diff --git a/primitives/primproc/CMakeLists.txt b/primitives/primproc/CMakeLists.txt index aab0232ac..b8d2e3741 100644 --- a/primitives/primproc/CMakeLists.txt +++ b/primitives/primproc/CMakeLists.txt @@ -21,8 +21,6 @@ set(PrimProc_SRCS umsocketselector.cpp ../../utils/common/crashtrace.cpp) -#PrimProc_CXXFLAGS = $(march_flags) $(AM_CXXFLAGS) - add_executable(PrimProc ${PrimProc_SRCS}) add_dependencies(PrimProc loggingcpp) diff --git a/primitives/primproc/columncommand.cpp b/primitives/primproc/columncommand.cpp index fbedc0c6a..ab6fbe223 100644 --- a/primitives/primproc/columncommand.cpp +++ b/primitives/primproc/columncommand.cpp @@ -40,6 +40,7 @@ using namespace std; #include "primitiveserver.h" #include "primproc.h" #include "stats.h" +#include "datatypes/mcs_int128.h" using namespace messageqcpp; using namespace rowgroup; @@ -231,11 +232,7 @@ void ColumnCommand::loadData() { ByteStream::hexbyte h; utils::getEmptyRowValue(colType.colDataType, colType.colWidth, (uint8_t*)&h); - __asm__ volatile("movups %1,%0" - :"=m" ( hPtr[idx] ) // output - :"v"( h ) // input - : "memory" // clobbered - ); + datatypes::TSInt128::storeUnaligned(hPtr + idx, h); } } @@ -332,18 +329,7 @@ void ColumnCommand::process_OT_BOTH() bpp->relRids[i] = *((uint16_t*) &bpp->outputMsg[pos]); pos += 2; - int128_t* int128Ptr = reinterpret_cast(&bpp->outputMsg[pos]); - __asm__ volatile("movdqu %0,%%xmm0;" - : - :"m"( *int128Ptr ) // input - :"xmm0" // clobbered - ); - __asm__ volatile("movups %%xmm0,%0;" - : "=m" (wide128Values[i])// output - : // input - : "memory", "xmm0" // clobbered - ); - + datatypes::TSInt128::assignPtrPtr(&wide128Values[i], &bpp->outputMsg[pos]); pos += 16; } diff --git a/utils/common/any.hpp b/utils/common/any.hpp index f39d5cec2..64b6e1bd4 100755 --- a/utils/common/any.hpp +++ b/utils/common/any.hpp @@ -129,7 +129,6 @@ namespace anyimpl choose_policy { typedef big_any_policy type; }; BIG_POLICY(int128_t); - BIG_POLICY(uint128_t); /// Specializations for small types. #define SMALL_POLICY(TYPE) template<> struct \ diff --git a/utils/funcexp/func_mod.cpp b/utils/funcexp/func_mod.cpp index 1afc308f5..01432cea8 100644 --- a/utils/funcexp/func_mod.cpp +++ b/utils/funcexp/func_mod.cpp @@ -242,7 +242,7 @@ double Func_mod::getDoubleVal(Row& row, int128_t value = d.s128Value / scaleDivisor; int128_t lefto = d.s128Value % scaleDivisor; __float128 tmp = (__float128) (value % div) + (__float128) lefto / scaleDivisor; - mod = datatypes::Decimal::getDoubleFromFloat128(tmp); + mod = datatypes::getDoubleFromFloat128(tmp); } } else @@ -365,7 +365,7 @@ long double Func_mod::getLongDoubleVal(Row& row, int128_t value = d.s128Value / scaleDivisor; int128_t lefto = d.s128Value % scaleDivisor; __float128 tmp = (__float128) (value % div) + (__float128) lefto / scaleDivisor; - mod = datatypes::Decimal::getLongDoubleFromFloat128(tmp); + mod = datatypes::getLongDoubleFromFloat128(tmp); } } else diff --git a/utils/messageqcpp/bytestream.cpp b/utils/messageqcpp/bytestream.cpp index d42239eb0..bef473b1c 100644 --- a/utils/messageqcpp/bytestream.cpp +++ b/utils/messageqcpp/bytestream.cpp @@ -37,6 +37,7 @@ using namespace boost; #define BYTESTREAM_DLLEXPORT #include "bytestream.h" #undef BYTESTREAM_DLLEXPORT +#include "datatypes/mcs_int128.h" #define DEBUG_DUMP_STRINGS_LESS_THAN 0 @@ -239,15 +240,8 @@ ByteStream& ByteStream::operator<<(const uint128_t& o) { if (fBuf == 0 || (fCurInPtr - fBuf + 16U > fMaxLen + ISSOverhead)) growBuf(fMaxLen + BlockSize); - - __asm__ volatile("movups %1,%0;" - :"=m" ( *fCurInPtr ) // output - :"v"( o ) // input - : "memory" // clobbered - ); - + datatypes::TSInt128::storeUnaligned(fCurInPtr, o); fCurInPtr += 16; - return *this; } @@ -255,14 +249,8 @@ ByteStream& ByteStream::operator<<(const int128_t& o) { if (fBuf == 0 || (fCurInPtr - fBuf + 16U > fMaxLen + ISSOverhead)) growBuf(fMaxLen + BlockSize); - - __asm__ volatile("movups %1,%0;" - :"=m" ( *fCurInPtr ) // output - :"v"( o ) // input - : "memory" // clobbered - ); + datatypes::TSInt128::storeUnaligned(fCurInPtr, o); fCurInPtr += 16; - return *this; } @@ -446,38 +434,16 @@ void ByteStream::peek(uint64_t& o) const void ByteStream::peek(uint128_t& o) const { - if (length() < 16) throw underflow_error("ByteStream>uint128_t: not enough data in stream to fill datatype"); - - __asm__ volatile("movdqu %0,%%xmm0;" - : - :"m"( *fCurOutPtr ) // input - :"xmm0" // clobbered - ); - __asm__ volatile("movups %%xmm0,%0;" - : "=m" (o)// output - : // input - : "memory", "xmm0" // clobbered - ); + datatypes::TSInt128::assignPtrPtr(&o, fCurOutPtr); } void ByteStream::peek(int128_t& o) const { - if (length() < 16) throw underflow_error("ByteStream>int128_t: not enough data in stream to fill datatype"); - - __asm__ volatile("movdqu %0,%%xmm0;" - : - :"m"( *fCurOutPtr ) // input - :"xmm0" // clobbered - ); - __asm__ volatile("movups %%xmm0,%0;" - : "=m" (o)// output - : // input - : "memory", "xmm0" // clobbered - ); + datatypes::TSInt128::assignPtrPtr(&o, fCurOutPtr); } void ByteStream::peek(string& s) const diff --git a/utils/rowgroup/rowaggregation.cpp b/utils/rowgroup/rowaggregation.cpp index e9199f8fd..f51fcd022 100755 --- a/utils/rowgroup/rowaggregation.cpp +++ b/utils/rowgroup/rowaggregation.cpp @@ -244,7 +244,6 @@ const static_any::any& RowAggregation::ushortTypeId((unsigned short)1); const static_any::any& RowAggregation::uintTypeId((unsigned int)1); const static_any::any& RowAggregation::ulongTypeId((unsigned long)1); const static_any::any& RowAggregation::ullTypeId((unsigned long long)1); -const static_any::any& RowAggregation::uint128TypeId((uint128_t)1); const static_any::any& RowAggregation::floatTypeId((float)1); const static_any::any& RowAggregation::doubleTypeId((double)1); const static_any::any& RowAggregation::longdoubleTypeId((long double)1); @@ -2184,7 +2183,10 @@ void RowAggregation::doUDAF(const Row& rowIn, int64_t colIn, int64_t colOut, if (LIKELY(fRowGroupIn.getColumnWidth(colIn) == datatypes::MAXDECIMALWIDTH)) { - datum.columnData = rowIn.getInt128Field(colIn); + // We can't control boost::any asignment + // so let's get an aligned memory + datatypes::TSInt128 val = rowIn.getTSInt128Field(colIn); + datum.columnData = val.s128Value; } else if (fRowGroupIn.getColumnWidth(colIn) <= datatypes::MAXLEGACYWIDTH) { @@ -2753,7 +2755,7 @@ void RowAggregationUM::calculateAvgColumns() bool isWideDecimal = datatypes::Decimal::isWideDecimalTypeByPrecision(precision); - if (LIKELY(!isWideDecimal)) + if (!isWideDecimal) { long double sum = 0.0; long double avg = 0.0; diff --git a/utils/rowgroup/rowaggregation.h b/utils/rowgroup/rowaggregation.h index 7fb4a10dc..34cd6fd03 100644 --- a/utils/rowgroup/rowaggregation.h +++ b/utils/rowgroup/rowaggregation.h @@ -725,7 +725,6 @@ protected: static const static_any::any& ushortTypeId; static const static_any::any& uintTypeId; static const static_any::any& ulongTypeId; - static const static_any::any& uint128TypeId; static const static_any::any& ullTypeId; static const static_any::any& floatTypeId; static const static_any::any& doubleTypeId; diff --git a/utils/rowgroup/rowgroup.h b/utils/rowgroup/rowgroup.h index 2d1ba045c..45f2be327 100644 --- a/utils/rowgroup/rowgroup.h +++ b/utils/rowgroup/rowgroup.h @@ -55,6 +55,7 @@ #include "mcsv1_udaf.h" #include "branchpred.h" +#include "datatypes/mcs_int128.h" #include "../winport/winport.h" @@ -386,8 +387,8 @@ public: return 0.0; // TODO: Do something here } inline long double getLongDoubleField(uint32_t colIndex) const; - inline int128_t getInt128Field(uint32_t colIndex) const; - inline uint128_t getUint128Field(uint32_t colIndex) const; + inline void getInt128Field(uint32_t colIndex, int128_t& x) const; + inline datatypes::TSInt128 getTSInt128Field(uint32_t colIndex) const; inline uint64_t getBaseRid() const; inline uint64_t getRid() const; @@ -418,7 +419,6 @@ public: inline void setDecimalField(double val, uint32_t colIndex) { }; // TODO: Do something here inline void setLongDoubleField(const long double& val, uint32_t colIndex); inline void setInt128Field(const int128_t& val, uint32_t colIndex); - inline void setUint128Field(const uint128_t& val, uint32_t colIndex); inline void setRid(uint64_t rid); @@ -429,11 +429,11 @@ public: void setStringField(const std::string& val, uint32_t colIndex); inline void setStringField(const uint8_t*, uint32_t len, uint32_t colIndex); template - inline void setBinaryField(T* strdata, uint32_t width, uint32_t colIndex); + inline void setBinaryField(const T* value, uint32_t width, uint32_t colIndex); template - inline void setBinaryField(T* strdata, uint32_t colIndex); + inline void setBinaryField(const T* value, uint32_t colIndex); template - inline void setBinaryField_offset(T* strdata, uint32_t width, uint32_t colIndex); + inline void setBinaryField_offset(const T* value, uint32_t width, uint32_t colIndex); // support VARBINARY // Add 2-byte length at the CHARSET_INFO*beginning of the field. NULL and zero length field are // treated the same, could use one of the length bit to distinguish these two cases. @@ -821,44 +821,41 @@ inline uint32_t Row::getStringLength(uint32_t colIndex) const } template -inline void Row::setBinaryField(T* value, uint32_t width, uint32_t colIndex) +inline void Row::setBinaryField(const T* value, uint32_t width, uint32_t colIndex) { memcpy(&data[offsets[colIndex]], value, width); } template -inline void Row::setBinaryField(T* value, uint32_t colIndex) +inline void Row::setBinaryField(const T* value, uint32_t colIndex) { *reinterpret_cast(&data[offsets[colIndex]]) = *value; } +template<> +inline void Row::setBinaryField(const int128_t* value, uint32_t colIndex) +{ + datatypes::TSInt128::assignPtrPtr(&data[offsets[colIndex]], value); +} + + // This method !cannot! be applied to uint8_t* buffers. template -inline void Row::setBinaryField_offset(T* value, uint32_t width, uint32_t offset) +inline void Row::setBinaryField_offset(const T* value, uint32_t width, uint32_t offset) { *reinterpret_cast(&data[offset]) = *value; } template<> -inline void Row::setBinaryField_offset(uint8_t* value, uint32_t width, uint32_t offset) +inline void Row::setBinaryField_offset(const uint8_t* value, uint32_t width, uint32_t offset) { memcpy(&data[offset], value, width); } template<> -inline void Row::setBinaryField_offset(int128_t* value, uint32_t width, uint32_t offset) +inline void Row::setBinaryField_offset(const int128_t* value, uint32_t width, uint32_t offset) { - int128_t *dst128Ptr = reinterpret_cast(&data[offset]); - __asm__ volatile("movdqu %0,%%xmm0;" - : - :"m"( *value ) // input - :"xmm0" // clobbered - ); - __asm__ volatile("movups %%xmm0,%0;" - : "=m" (*dst128Ptr)// output - : // input - : "memory", "xmm0" // clobbered - ); + datatypes::TSInt128::assignPtrPtr(&data[offset], value); } inline void Row::setStringField(const uint8_t* strdata, uint32_t length, uint32_t colIndex) @@ -975,18 +972,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 +inline void Row::getInt128Field(uint32_t colIndex, int128_t& x) const { - return *((int128_t*) &data[offsets[colIndex]]); + datatypes::TSInt128::assignPtrPtr(&x, &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 +inline datatypes::TSInt128 Row::getTSInt128Field(uint32_t colIndex) const { - return *((uint128_t*) &data[offsets[colIndex]]); + const int128_t* ptr = getBinaryField(colIndex); + return datatypes::TSInt128(ptr); } inline uint64_t Row::getRid() const @@ -1198,12 +1192,7 @@ inline void Row::setLongDoubleField(const long double& val, uint32_t colIndex) inline void Row::setInt128Field(const int128_t& val, uint32_t colIndex) { - *((int128_t*)&data[offsets[colIndex]]) = val; -} - -inline void Row::setUint128Field(const uint128_t& val, uint32_t colIndex) -{ - *((uint128_t*)&data[offsets[colIndex]]) = val; + setBinaryField(&val, colIndex); } inline void Row::setVarBinaryField(const std::string& val, uint32_t colIndex) diff --git a/utils/udfsdk/mcsv1_udaf.cpp b/utils/udfsdk/mcsv1_udaf.cpp index cd08e3573..b9d7cdac1 100755 --- a/utils/udfsdk/mcsv1_udaf.cpp +++ b/utils/udfsdk/mcsv1_udaf.cpp @@ -285,7 +285,6 @@ const static_any::any& mcsv1_UDAF::ushortTypeId((unsigned short)1); const static_any::any& mcsv1_UDAF::uintTypeId((unsigned int)1); const static_any::any& mcsv1_UDAF::ulongTypeId((unsigned long)1); const static_any::any& mcsv1_UDAF::ullTypeId((unsigned long long)1); -const static_any::any& mcsv1_UDAF::uint128TypeId((uint128_t)1); const static_any::any& mcsv1_UDAF::floatTypeId((float)1); const static_any::any& mcsv1_UDAF::doubleTypeId((double)1); const static_any::any& mcsv1_UDAF::strTypeId(typeStr); diff --git a/utils/udfsdk/mcsv1_udaf.h b/utils/udfsdk/mcsv1_udaf.h index 6c0ea7370..ff37457ef 100755 --- a/utils/udfsdk/mcsv1_udaf.h +++ b/utils/udfsdk/mcsv1_udaf.h @@ -644,7 +644,6 @@ protected: static const static_any::any& uintTypeId; static const static_any::any& ulongTypeId; static const static_any::any& ullTypeId; - static const static_any::any& uint128TypeId; static const static_any::any& floatTypeId; static const static_any::any& doubleTypeId; static const static_any::any& strTypeId; @@ -1075,10 +1074,6 @@ inline T mcsv1_UDAF::convertAnyTo(static_any::any& valIn) { val = valIn.cast(); } - else if (valIn.compatible(uint128TypeId)) - { - val = valIn.cast(); - } else { throw std::runtime_error("mcsv1_UDAF::convertAnyTo(): input param has unrecognized type"); diff --git a/utils/windowfunction/frameboundrange.cpp b/utils/windowfunction/frameboundrange.cpp index e10cb6fbd..e2ae172e1 100644 --- a/utils/windowfunction/frameboundrange.cpp +++ b/utils/windowfunction/frameboundrange.cpp @@ -300,7 +300,8 @@ void FrameBoundExpressionRange::validate() case execplan::CalpontSystemCatalog::DECIMAL: { - if (this->fRow.getColumnWidth(this->fIndex[1]) < 16) + if (UNLIKELY(this->fRow.getColumnWidth(this->fIndex[1]) + < datatypes::MAXDECIMALWIDTH)) { int64_t tmp = this->fRow.getIntField(this->fIndex[1]); this->fIsZero = (tmp == 0); @@ -313,7 +314,7 @@ void FrameBoundExpressionRange::validate() } else { - int128_t tmp = this->fRow.getInt128Field(this->fIndex[1]); + datatypes::TSInt128 tmp = this->fRow.getTSInt128Field(this->fIndex[1]); this->fIsZero = (tmp == 0); if (tmp < 0) @@ -325,6 +326,22 @@ void FrameBoundExpressionRange::validate() break; } + case execplan::CalpontSystemCatalog::UDECIMAL: + { + if (UNLIKELY(this->fRow.getColumnWidth(this->fIndex[1]) + < datatypes::MAXDECIMALWIDTH)) + { + uint64_t tmp = this->fRow.getUintField(this->fIndex[1]); + this->fIsZero = (tmp == 0); + } + else + { + datatypes::TSInt128 tmp = this->fRow.getTSInt128Field(this->fIndex[1]); + this->fIsZero = (tmp == 0); + } + break; + } + case execplan::CalpontSystemCatalog::DOUBLE: case execplan::CalpontSystemCatalog::UDOUBLE: { @@ -369,22 +386,6 @@ void FrameBoundExpressionRange::validate() break; } - case execplan::CalpontSystemCatalog::UDECIMAL: - { - if (this->fRow.getColumnWidth(this->fIndex[1]) < 16) - { - uint64_t tmp = this->fRow.getUintField(this->fIndex[1]); - this->fIsZero = (tmp == 0); - break; - } - else - { - uint128_t tmp = this->fRow.getUint128Field(this->fIndex[1]); - this->fIsZero = (tmp == 0); - break; - } - } - case execplan::CalpontSystemCatalog::UTINYINT: case execplan::CalpontSystemCatalog::USMALLINT: case execplan::CalpontSystemCatalog::UMEDINT: diff --git a/utils/windowfunction/idborderby.cpp b/utils/windowfunction/idborderby.cpp index 69344c43e..93e2d468e 100644 --- a/utils/windowfunction/idborderby.cpp +++ b/utils/windowfunction/idborderby.cpp @@ -853,13 +853,14 @@ bool EqualCompData::operator()(Row::Pointer a, Row::Pointer b) case CalpontSystemCatalog::UDECIMAL: { // equal compare. ignore sign and null - if (fRow1.getColumnWidth(*i) < datatypes::MAXDECIMALWIDTH) + if (UNLIKELY(fRow1.getColumnWidth(*i) < datatypes::MAXDECIMALWIDTH)) { eq = (fRow1.getUintField(*i) == fRow2.getUintField(*i)); } else if (fRow1.getColumnWidth(*i) == datatypes::MAXDECIMALWIDTH) { - eq = (fRow1.getUint128Field(*i) == fRow2.getUint128Field(*i)); + eq = (*fRow1.getBinaryField(*i) == + *fRow2.getBinaryField(*i)); } break; } diff --git a/utils/windowfunction/wf_count.cpp b/utils/windowfunction/wf_count.cpp index 29987c3b4..67bc82ed4 100644 --- a/utils/windowfunction/wf_count.cpp +++ b/utils/windowfunction/wf_count.cpp @@ -78,11 +78,13 @@ boost::shared_ptr WF_count::makeFunction(int id, const st case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) + decltype(datatypes::MAXDECIMALWIDTH) width = + wc->functionParms()[0]->resultType().colWidth; + if (width < datatypes::MAXDECIMALWIDTH) { func.reset(new WF_count(id, name)); } - else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) + else if (width == 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 1a1b453cd..ff363151b 100644 --- a/utils/windowfunction/wf_lead_lag.cpp +++ b/utils/windowfunction/wf_lead_lag.cpp @@ -84,31 +84,23 @@ boost::shared_ptr WF_lead_lag::makeFunction(int id, const } case CalpontSystemCatalog::DECIMAL: + case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) + decltype(datatypes::MAXDECIMALWIDTH) width = + wc->functionParms()[0]->resultType().colWidth; + if (width < datatypes::MAXDECIMALWIDTH) { - func.reset(new WF_lead_lag(id, name)); + if (ct == CalpontSystemCatalog::UDECIMAL) + func.reset(new WF_lead_lag(id, name)); + else + func.reset(new WF_lead_lag(id, name)); } - else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) + else if (width == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_lead_lag(id, name)); } break; } - - case CalpontSystemCatalog::UDECIMAL: - { - if (wc->functionParms()[0]->resultType().colWidth < 16) - { - func.reset(new WF_lead_lag(id, name)); - } - else - { - func.reset(new WF_lead_lag(id, name)); - } - break; - } - case CalpontSystemCatalog::DOUBLE: case CalpontSystemCatalog::UDOUBLE: { @@ -319,7 +311,6 @@ boost::shared_ptr WF_lead_lag::makeFunction(int, co template void WF_lead_lag::parseParms(const std::vector&); template void WF_lead_lag::parseParms(const std::vector&); template void WF_lead_lag::parseParms(const std::vector&); -template void WF_lead_lag::parseParms(const std::vector&); template void WF_lead_lag::parseParms(const std::vector&); template void WF_lead_lag::parseParms(const std::vector&); template void WF_lead_lag::parseParms(const std::vector&); diff --git a/utils/windowfunction/wf_min_max.cpp b/utils/windowfunction/wf_min_max.cpp index f9c410362..036a393fc 100644 --- a/utils/windowfunction/wf_min_max.cpp +++ b/utils/windowfunction/wf_min_max.cpp @@ -83,10 +83,17 @@ boost::shared_ptr WF_min_max::makeFunction(int id, const } case CalpontSystemCatalog::DECIMAL: + case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < 16) + decltype(datatypes::MAXDECIMALWIDTH) width = + wc->functionParms()[0]->resultType().colWidth; + + if (width < datatypes::MAXDECIMALWIDTH) { - func.reset(new WF_min_max(id, name)); + if (ct == CalpontSystemCatalog::UDECIMAL) + func.reset(new WF_min_max(id, name)); + else + func.reset(new WF_min_max(id, name)); } else { @@ -94,19 +101,6 @@ boost::shared_ptr WF_min_max::makeFunction(int id, const } break; } - - case CalpontSystemCatalog::UDECIMAL: - { - if (wc->functionParms()[0]->resultType().colWidth < 16) - { - func.reset(new WF_min_max(id, name)); - } - else - { - func.reset(new WF_min_max(id, name)); - } - break; - } case CalpontSystemCatalog::DOUBLE: case CalpontSystemCatalog::UDOUBLE: diff --git a/utils/windowfunction/wf_nth_value.cpp b/utils/windowfunction/wf_nth_value.cpp index 41dde88fb..d838c8ec3 100644 --- a/utils/windowfunction/wf_nth_value.cpp +++ b/utils/windowfunction/wf_nth_value.cpp @@ -86,11 +86,16 @@ boost::shared_ptr WF_nth_value::makeFunction(int id, cons case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) + decltype(datatypes::MAXDECIMALWIDTH) width = + wc->functionParms()[0]->resultType().colWidth; + if (width < datatypes::MAXDECIMALWIDTH) { - func.reset(new WF_nth_value(id, name)); + if (ct == CalpontSystemCatalog::UDECIMAL) + func.reset(new WF_nth_value(id, name)); + else + func.reset(new WF_nth_value(id, name)); } - else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) + else if (width == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_nth_value(id, name)); } diff --git a/utils/windowfunction/wf_percentile.cpp b/utils/windowfunction/wf_percentile.cpp index a407d41e8..d23f9e712 100644 --- a/utils/windowfunction/wf_percentile.cpp +++ b/utils/windowfunction/wf_percentile.cpp @@ -46,8 +46,6 @@ using namespace ordering; #include "constantcolumn.h" using namespace execplan; -#include "mcs_decimal.h" - #include "windowfunctionstep.h" using namespace joblist; @@ -93,11 +91,17 @@ boost::shared_ptr WF_percentile::makeFunction(int id, con case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - if (wc->resultType().colWidth < datatypes::MAXDECIMALWIDTH) + decltype(datatypes::MAXDECIMALWIDTH) width = + wc->resultType().colWidth; + + if (width < datatypes::MAXDECIMALWIDTH) { - func.reset(new WF_percentile(id, name)); + if (ct == CalpontSystemCatalog::UDECIMAL) + func.reset(new WF_percentile(id, name)); + else + func.reset(new WF_percentile(id, name)); } - else if (wc->resultType().colWidth == datatypes::MAXDECIMALWIDTH) + else if (width == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_percentile(id, name)); } diff --git a/utils/windowfunction/wf_stats.cpp b/utils/windowfunction/wf_stats.cpp index 0dee4fa9e..d736704f8 100644 --- a/utils/windowfunction/wf_stats.cpp +++ b/utils/windowfunction/wf_stats.cpp @@ -84,11 +84,16 @@ boost::shared_ptr WF_stats::makeFunction(int id, const st case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) + decltype(datatypes::MAXDECIMALWIDTH) width = + wc->functionParms()[0]->resultType().colWidth; + if (width < datatypes::MAXDECIMALWIDTH) { - func.reset(new WF_stats(id, name)); + if (ct == CalpontSystemCatalog::UDECIMAL) + func.reset(new WF_stats(id, name)); + else + func.reset(new WF_stats(id, name)); } - else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) + else if (width == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_stats(id, name)); } diff --git a/utils/windowfunction/wf_sum_avg.cpp b/utils/windowfunction/wf_sum_avg.cpp index c008436bf..5a0fbbfc0 100644 --- a/utils/windowfunction/wf_sum_avg.cpp +++ b/utils/windowfunction/wf_sum_avg.cpp @@ -181,11 +181,17 @@ boost::shared_ptr WF_sum_avg::makeFunction(int case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - if (wc->functionParms()[0]->resultType().colWidth < datatypes::MAXDECIMALWIDTH) + decltype(datatypes::MAXDECIMALWIDTH) width = + wc->functionParms()[0]->resultType().colWidth; + + if (width < datatypes::MAXDECIMALWIDTH) { - func.reset(new WF_sum_avg(id, name)); + if (ct == CalpontSystemCatalog::UDECIMAL) + func.reset(new WF_sum_avg(id, name)); + else + func.reset(new WF_sum_avg(id, name)); } - else if (wc->functionParms()[0]->resultType().colWidth == datatypes::MAXDECIMALWIDTH) + else if (width == datatypes::MAXDECIMALWIDTH) { func.reset(new WF_sum_avg(id, name)); } diff --git a/utils/windowfunction/wf_udaf.cpp b/utils/windowfunction/wf_udaf.cpp index 62d4a2714..b7e7881dd 100644 --- a/utils/windowfunction/wf_udaf.cpp +++ b/utils/windowfunction/wf_udaf.cpp @@ -550,7 +550,6 @@ void WF_udaf::SetUDAFValue(static_any::any& valOut, int64_t colOut, static const static_any::any& uintTypeId = (unsigned int)1; static const static_any::any& ulongTypeId = (unsigned long)1; static const static_any::any& ullTypeId = (unsigned long long)1; - static const static_any::any& uint128TypeId = (uint128_t)1; static const static_any::any& floatTypeId = (float)1; static const static_any::any& doubleTypeId = (double)1; static const std::string typeStr(""); @@ -565,7 +564,6 @@ void WF_udaf::SetUDAFValue(static_any::any& valOut, int64_t colOut, int64_t intOut = 0; uint64_t uintOut = 0; int128_t int128Out = 0; - uint128_t uint128Out = 0; float floatOut = 0.0; double doubleOut = 0.0; long double longdoubleOut = 0.0; @@ -664,15 +662,6 @@ void WF_udaf::SetUDAFValue(static_any::any& valOut, int64_t colOut, longdoubleOut = int128Out; oss << longdoubleOut; } - else if (valOut.compatible(uint128TypeId)) - { - uint128Out = valOut.cast(); - uintOut = intOut = uint128Out; // may truncate - floatOut = uint128Out; - doubleOut = uint128Out; - longdoubleOut = uint128Out; - oss << longdoubleOut; - } if (valOut.compatible(strTypeId)) { diff --git a/utils/windowfunction/windowfunctiontype.cpp b/utils/windowfunction/windowfunctiontype.cpp index 738c2bd4e..d93b59683 100644 --- a/utils/windowfunction/windowfunctiontype.cpp +++ b/utils/windowfunction/windowfunctiontype.cpp @@ -58,7 +58,6 @@ using namespace joblist; #include "wf_stats.h" #include "wf_sum_avg.h" #include "wf_udaf.h" -#include "mcs_decimal.h" namespace windowfunction { @@ -310,17 +309,7 @@ template<> void WindowFunctionType::getValue(uint64_t i, string& t, CDT* template<> void WindowFunctionType::getValue(uint64_t i, int128_t& t, CDT* cdt) { - t = fRow.getInt128Field(i); - - if (cdt) - { - *cdt = execplan::CalpontSystemCatalog::DECIMAL; - } -} - -template<> void WindowFunctionType::getValue(uint64_t i, uint128_t& t, CDT* cdt) -{ - t = fRow.getUint128Field(i); + fRow.getInt128Field(i, t); if (cdt) { @@ -362,11 +351,6 @@ template<> void WindowFunctionType::setValue(uint64_t i, int128_t& t) fRow.setInt128Field(t, i); } -template<> void WindowFunctionType::setValue(uint64_t i, uint128_t& t) -{ - fRow.setUint128Field(t, i); -} - template<> void WindowFunctionType::setValue(uint64_t i, string& t) { fRow.setStringField(t, i); @@ -460,7 +444,7 @@ void WindowFunctionType::setValue(int ct, int64_t b, int64_t e, int64_t c, T* v) } else { - uint128_t iv = *v; + int128_t iv = *v; setValue(i, iv); } break; @@ -525,22 +509,22 @@ void WindowFunctionType::implicit2T(uint64_t i, T& t, int s) } case CalpontSystemCatalog::DECIMAL: - { - uint32_t w = fRow.getColumnWidth(i); - if (w < 16) - t = (T) fRow.getIntField(i); - else - t = (T) fRow.getInt128Field(i); - break; - } - case CalpontSystemCatalog::UDECIMAL: { - uint32_t w = fRow.getColumnWidth(i); - if (w < 16) - t = (T) fRow.getUintField(i); - else - t = (T) fRow.getUint128Field(i); + decltype(datatypes::MAXDECIMALWIDTH) width = + fRow.getColumnWidth(i);; + + if (width < datatypes::MAXDECIMALWIDTH) + { + t = (ct == execplan::CalpontSystemCatalog::DECIMAL) ? + (T) fRow.getIntField(i) : + (T) fRow.getUintField(i); + } + else if (width == datatypes::MAXDECIMALWIDTH) + { + datatypes::TSInt128::assignPtrPtr(&t, + fRow.getBinaryField(i)); + } break; } @@ -615,12 +599,6 @@ void WindowFunctionType::getConstValue(ConstantColumn* cc, int128_t& t t = cc->getDecimalVal(fRow, b).s128Value; } -template<> -void WindowFunctionType::getConstValue(ConstantColumn* cc, uint128_t& t, bool& b) -{ - t = cc->getDecimalVal(fRow, b).s128Value; -} - template<> void WindowFunctionType::getConstValue(ConstantColumn* cc, double& t, bool& b) { @@ -651,15 +629,12 @@ template void WindowFunctionType::implicit2T(uint64_t, float&, int); template void WindowFunctionType::implicit2T(uint64_t, double&, int); template void WindowFunctionType::implicit2T(uint64_t, long double&, int); template void WindowFunctionType::implicit2T(uint64_t, int128_t&, int); -template void WindowFunctionType::implicit2T(uint64_t, uint128_t&, int); - template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, int64_t*); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, uint64_t*); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, float*); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, double*); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, long double*); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, int128_t*); -template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, uint128_t*); void* WindowFunctionType::getNullValueByType(int ct, int pos) { diff --git a/utils/windowfunction/windowfunctiontype.h b/utils/windowfunction/windowfunctiontype.h index e08bc0611..dfda6e053 100644 --- a/utils/windowfunction/windowfunctiontype.h +++ b/utils/windowfunction/windowfunctiontype.h @@ -33,6 +33,7 @@ #include "rowgroup.h" #include "windowframe.h" #include "constantcolumn.h" +#include "mcs_decimal.h" namespace ordering { @@ -222,14 +223,16 @@ protected: virtual void* getNullValueByType(int, int); + // There are two types of getters for integral types and for + // DTs wider then 8 bytes. + void getInt128Value(uint64_t i, int128_t& x) + { + return fRow.getInt128Field(i, x); + } int64_t getIntValue(uint64_t i) { return fRow.getIntField(i); } - int128_t getInt128Value(uint64_t i) - { - return fRow.getInt128Field(i); - } double getDoubleValue(uint64_t i) { return fRow.getDoubleField(i); diff --git a/writeengine/server/we_dmlcommandproc.cpp b/writeengine/server/we_dmlcommandproc.cpp index f9c577dbd..56f8ebbc5 100644 --- a/writeengine/server/we_dmlcommandproc.cpp +++ b/writeengine/server/we_dmlcommandproc.cpp @@ -2992,7 +2992,6 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - // WIP MCOL-641 if (fetchColColwidths[fetchColPos] == datatypes::MAXDECIMALWIDTH) { int128_t* dec; @@ -3007,9 +3006,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, break; } - - // else - // fall through to integer cases + [[fallthrough]]; } /* fall through */ @@ -3360,7 +3357,6 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, { if (fetchColColwidths[fetchColPos] == datatypes::MAXDECIMALWIDTH) { - // WIP MCOL-641 int128_t* dec; char buf[datatypes::Decimal::MAXLENGTH16BYTES]; dec = row.getBinaryField(fetchColPos); @@ -3373,9 +3369,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, break; } - - // else - // fall through to integer cases + [[fallthrough]]; } /* fall through */