diff --git a/dbcon/dmlpackageproc/dmlpackageprocessor.cpp b/dbcon/dmlpackageproc/dmlpackageprocessor.cpp index 19f8bc0ce..ad5bd1df0 100644 --- a/dbcon/dmlpackageproc/dmlpackageprocessor.cpp +++ b/dbcon/dmlpackageproc/dmlpackageprocessor.cpp @@ -52,6 +52,7 @@ using namespace joblist; using namespace messageqcpp; #include "tablelockdata.h" #include "exceptclasses.h" +#include "widedecimalutils.h" namespace { @@ -510,8 +511,8 @@ int DMLPackageProcessor::commitBatchAutoOnTransaction(uint64_t uniqueId, BRM::Tx aInfo.firstLbid = *iter; aInfo.max = numeric_limits::min(); // Not used aInfo.min = numeric_limits::max(); // Not used - dataconvert::DataConvert::int128Min(aInfo.bigMax); // Not used - dataconvert::DataConvert::int128Max(aInfo.bigMin); // Not used + utils::int128Min(aInfo.bigMax); // Not used + utils::int128Max(aInfo.bigMin); // Not used aInfo.seqNum = -1; cpInfos.push_back(aInfo); ++iter; diff --git a/dbcon/joblist/lbidlist.cpp b/dbcon/joblist/lbidlist.cpp index 90697bbfc..bc7ca9303 100644 --- a/dbcon/joblist/lbidlist.cpp +++ b/dbcon/joblist/lbidlist.cpp @@ -28,6 +28,7 @@ #include "brm.h" #include "brmtypes.h" #include "dataconvert.h" +#include "widedecimalutils.h" #include "mcs_decimal.h" #define IS_VERBOSE (fDebug >= 4) @@ -251,8 +252,8 @@ bool LBIDList::GetMinMax(T& min, T& max, int64_t& seq, int64_t lbid, { if (typeid(T) == typeid(__int128)) { - dataconvert::DataConvert::int128Min(mmp->bigMax); - dataconvert::DataConvert::int128Max(mmp->bigMin); + utils::int128Min(mmp->bigMax); + utils::int128Max(mmp->bigMin); } else { @@ -274,8 +275,8 @@ bool LBIDList::GetMinMax(T& min, T& max, int64_t& seq, int64_t lbid, return false; } -//TODO MCOL-641 Do we need support here? -bool LBIDList::GetMinMax(int64_t* min, int64_t* max, int64_t* seq, +template +bool LBIDList::GetMinMax(T* min, T* max, int64_t* seq, int64_t lbid, const tr1::unordered_map& entries, execplan::CalpontSystemCatalog::ColDataType colDataType) { @@ -296,13 +297,29 @@ bool LBIDList::GetMinMax(int64_t* min, int64_t* max, int64_t* seq, if (isUnsigned(colDataType)) { - mmp->max = 0; - mmp->min = static_cast(numeric_limits::max()); + if (typeid(T) == typeid(__int128)) + { + mmp->bigMax = 0; + mmp->bigMin = -1; + } + else + { + mmp->max = 0; + mmp->min = static_cast(numeric_limits::max()); + } } else { - mmp->max = numeric_limits::min(); - mmp->min = numeric_limits::max(); + if (typeid(T) == typeid(__int128)) + { + utils::int128Min(mmp->bigMax); + utils::int128Max(mmp->bigMin); + } + else + { + mmp->max = numeric_limits::min(); + mmp->min = numeric_limits::max(); + } } mmp->isValid = entry.partition.cprange.isValid; @@ -311,9 +328,19 @@ bool LBIDList::GetMinMax(int64_t* min, int64_t* max, int64_t* seq, return false; } - *min = entry.partition.cprange.lo_val; - *max = entry.partition.cprange.hi_val; + if (typeid(T) == typeid(__int128)) + { + *min = entry.partition.cprange.bigLoVal; + *max = entry.partition.cprange.bigHiVal; + } + else + { + *min = entry.partition.cprange.lo_val; + *max = entry.partition.cprange.hi_val; + } + *seq = entry.partition.cprange.sequenceNum; + return true; } @@ -653,11 +680,14 @@ inline bool LBIDList::compareVal(const T& Min, const T& Max, const T& value, cha return true; } -bool LBIDList::checkSingleValue(int64_t min, int64_t max, int64_t value, +template +bool LBIDList::checkSingleValue(T min, T max, T value, execplan::CalpontSystemCatalog::ColDataType type) { if (isCharType(type)) { + // MCOL-641 LBIDList::CasualPartitionDataType() returns false if + // width > 8 for a character type, so T cannot be __int128 here uint64_t mmin = order_swap(min); uint64_t mmax = order_swap(max); uint64_t vvalue = order_swap(value); @@ -665,8 +695,16 @@ bool LBIDList::checkSingleValue(int64_t min, int64_t max, int64_t value, } else if (isUnsigned(type)) { - return (static_cast(value) >= static_cast(min) && - static_cast(value) <= static_cast(max)); + if (typeid(T) == typeid(__int128)) + { + 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)); + } } else { @@ -674,11 +712,14 @@ bool LBIDList::checkSingleValue(int64_t min, int64_t max, int64_t value, } } -bool LBIDList::checkRangeOverlap(int64_t min, int64_t max, int64_t tmin, int64_t tmax, +template +bool LBIDList::checkRangeOverlap(T min, T max, T tmin, T tmax, execplan::CalpontSystemCatalog::ColDataType type) { if (isCharType(type)) { + // MCOL-641 LBIDList::CasualPartitionDataType() returns false if + // width > 8 for a character type, so T cannot be __int128 here uint64_t min2 = order_swap(min); uint64_t max2 = order_swap(max); uint64_t tmin2 = order_swap(tmin); @@ -687,8 +728,16 @@ bool LBIDList::checkRangeOverlap(int64_t min, int64_t max, int64_t tmin, int64_t } else if (isUnsigned(type)) { - return (static_cast(tmin) <= static_cast(max) && - static_cast(tmax) >= static_cast(min)); + if (typeid(T) == typeid(__int128)) + { + 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)); + } } else { @@ -708,8 +757,7 @@ bool LBIDList::CasualPartitionPredicate(const BRM::EMCasualPartition_t& cpRange, bool scan = true; int64_t value = 0; __int128 bigValue = 0; - dataconvert::Int128Pod_t* bigValuePod; - bigValuePod = reinterpret_cast(&bigValue); + uint64_t* int128Ptr = reinterpret_cast(&bigValue); bool bIsUnsigned = execplan::isUnsigned(ct.colDataType); bool bIsChar = execplan::isCharType(ct.colDataType); @@ -759,12 +807,13 @@ bool LBIDList::CasualPartitionPredicate(const BRM::EMCasualPartition_t& cpRange, uint64_t val = *(int64_t*)MsgDataPtr; value = static_cast(val); } + case 16: { unsigned __int128 val; - bigValuePod = reinterpret_cast(&val); - bigValuePod->lo = *reinterpret_cast(MsgDataPtr); - bigValuePod->hi = *(reinterpret_cast(MsgDataPtr) + 1); + int128Ptr = reinterpret_cast(&val); + int128Ptr[0] = *reinterpret_cast(MsgDataPtr); + int128Ptr[1] = *(reinterpret_cast(MsgDataPtr) + 1); bigValue = static_cast<__int128>(val); } } @@ -799,10 +848,11 @@ bool LBIDList::CasualPartitionPredicate(const BRM::EMCasualPartition_t& cpRange, int64_t val = *(int64_t*)MsgDataPtr; value = val; } + case 16: { - bigValuePod->lo = *reinterpret_cast(MsgDataPtr); - bigValuePod->hi = *(reinterpret_cast(MsgDataPtr) + 1); + int128Ptr[0] = *reinterpret_cast(MsgDataPtr); + int128Ptr[1] = *(reinterpret_cast(MsgDataPtr) + 1); } } } @@ -918,6 +968,16 @@ bool LBIDList::GetMinMax(int64_t& min, int64_t& max, int64_t& seq, int6 const std::vector* pEMEntries, execplan::CalpontSystemCatalog::ColDataType colDataType); +template +bool LBIDList::GetMinMax<__int128>(__int128* min, __int128* max, int64_t* seq, + int64_t lbid, const tr1::unordered_map& entries, + execplan::CalpontSystemCatalog::ColDataType colDataType); + +template +bool LBIDList::GetMinMax(int64_t* min, int64_t* max, int64_t* seq, + int64_t lbid, const tr1::unordered_map& entries, + execplan::CalpontSystemCatalog::ColDataType colDataType); + template void LBIDList::UpdateMinMax<__int128>(__int128 min, __int128 max, int64_t lbid, execplan::CalpontSystemCatalog::ColDataType type, bool validData = true); @@ -926,6 +986,22 @@ template void LBIDList::UpdateMinMax(int64_t min, int64_t max, int64_t lbid, execplan::CalpontSystemCatalog::ColDataType type, bool validData = true); +template +bool LBIDList::checkSingleValue<__int128>(__int128 min, __int128 max, __int128 value, + execplan::CalpontSystemCatalog::ColDataType type); + +template +bool LBIDList::checkSingleValue(int64_t min, int64_t max, int64_t value, + execplan::CalpontSystemCatalog::ColDataType type); + +template +bool LBIDList::checkRangeOverlap<__int128>(__int128 min, __int128 max, __int128 tmin, __int128 tmax, + execplan::CalpontSystemCatalog::ColDataType type); + +template +bool LBIDList::checkRangeOverlap(int64_t min, int64_t max, int64_t tmin, int64_t tmax, + execplan::CalpontSystemCatalog::ColDataType type); + } //namespace joblist // vim:ts=4 sw=4: diff --git a/dbcon/joblist/lbidlist.h b/dbcon/joblist/lbidlist.h index 0b2fccca6..934f42924 100644 --- a/dbcon/joblist/lbidlist.h +++ b/dbcon/joblist/lbidlist.h @@ -91,13 +91,14 @@ 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 + // should static cast returned min and max to uint64_t/uint128_t template bool GetMinMax(T& min, T& max, int64_t& seq, int64_t lbid, const std::vector* pEMEntries, execplan::CalpontSystemCatalog::ColDataType type); - bool GetMinMax(int64_t* min, int64_t* max, int64_t* seq, int64_t lbid, + template + bool GetMinMax(T* min, T* max, int64_t* seq, int64_t lbid, const std::tr1::unordered_map& entries, execplan::CalpontSystemCatalog::ColDataType type); @@ -115,10 +116,12 @@ public: const execplan::CalpontSystemCatalog::ColType& ct, const uint8_t BOP); - bool checkSingleValue(int64_t min, int64_t max, int64_t value, + template + bool checkSingleValue(T min, T max, T value, execplan::CalpontSystemCatalog::ColDataType type); - bool checkRangeOverlap(int64_t min, int64_t max, int64_t tmin, int64_t tmax, + template + bool checkRangeOverlap(T min, T max, T tmin, T tmax, execplan::CalpontSystemCatalog::ColDataType type); // check the column data type and the column size to determine if it diff --git a/dbcon/joblist/primitivestep.h b/dbcon/joblist/primitivestep.h index 603bc6ebd..e57443ff3 100644 --- a/dbcon/joblist/primitivestep.h +++ b/dbcon/joblist/primitivestep.h @@ -1327,7 +1327,8 @@ public: * Note that it is an adder not a setter. For an extent to be scanned, all calls * must have a non-empty intersection. */ - void addCPPredicates(uint32_t OID, const std::vector& vals, bool isRange); + void addCPPredicates(uint32_t OID, const std::vector<__int128>& vals, bool isRange, + bool isSmallSideWideDecimal); /* semijoin adds */ void setJoinFERG(const rowgroup::RowGroup& rg); @@ -1509,13 +1510,16 @@ private: /* Pseudo column filter processing. Think about refactoring into a separate class. */ bool processPseudoColFilters(uint32_t extentIndex, boost::shared_ptr > dbRootPMMap) const; - bool processOneFilterType(int8_t colWidth, int64_t value, uint32_t type) const; - bool processSingleFilterString(int8_t BOP, int8_t colWidth, int64_t val, const uint8_t* filterString, + template + bool processOneFilterType(int8_t colWidth, T value, uint32_t type) const; + template + bool processSingleFilterString(int8_t BOP, int8_t colWidth, T val, const uint8_t* filterString, uint32_t filterCount) const; bool processSingleFilterString_ranged(int8_t BOP, int8_t colWidth, int64_t min, int64_t max, const uint8_t* filterString, uint32_t filterCount) const; bool processLBIDFilter(const BRM::EMEntry& emEntry) const; - bool compareSingleValue(uint8_t COP, int64_t val1, int64_t val2) const; + template + bool compareSingleValue(uint8_t COP, T val1, T val2) const; bool compareRange(uint8_t COP, int64_t min, int64_t max, int64_t val) const; bool hasPCFilter, hasPMFilter, hasRIDFilter, hasSegmentFilter, hasDBRootFilter, hasSegmentDirFilter, hasPartitionFilter, hasMaxFilter, hasMinFilter, hasLBIDFilter, hasExtentIDFilter; diff --git a/dbcon/joblist/pseudocc-jl.cpp b/dbcon/joblist/pseudocc-jl.cpp index 8ad0ccb2e..65b5a2317 100644 --- a/dbcon/joblist/pseudocc-jl.cpp +++ b/dbcon/joblist/pseudocc-jl.cpp @@ -46,23 +46,57 @@ void PseudoCCJL::runCommand(ByteStream& bs) const { if (function == PSEUDO_EXTENTMAX) { - int64_t max = extents[currentExtentIndex].partition.cprange.hi_val; - int64_t min = extents[currentExtentIndex].partition.cprange.lo_val; + if (!datatypes::Decimal::isWideDecimalType(colType)) + { + int64_t max = extents[currentExtentIndex].partition.cprange.hi_val; + int64_t min = extents[currentExtentIndex].partition.cprange.lo_val; - if (extents[currentExtentIndex].partition.cprange.isValid == BRM::CP_VALID && max >= min) - bs << max; + if (extents[currentExtentIndex].partition.cprange.isValid == BRM::CP_VALID && max >= min) + bs << max; + else + bs << utils::getNullValue(colType.colDataType, colType.colWidth); + } else - bs << utils::getNullValue(colType.colDataType, colType.colWidth); + { + int128_t max = extents[currentExtentIndex].partition.cprange.bigHiVal; + int128_t min = extents[currentExtentIndex].partition.cprange.bigLoVal; + + if (extents[currentExtentIndex].partition.cprange.isValid == BRM::CP_VALID && max >= min) + bs << (uint128_t) max; + else + { + int128_t int128Null; + utils::setWideDecimalNullValue(int128Null); + bs << (uint128_t) int128Null; + } + } } else if (function == PSEUDO_EXTENTMIN) { - int64_t max = extents[currentExtentIndex].partition.cprange.hi_val; - int64_t min = extents[currentExtentIndex].partition.cprange.lo_val; + if (!datatypes::Decimal::isWideDecimalType(colType)) + { + int64_t max = extents[currentExtentIndex].partition.cprange.hi_val; + int64_t min = extents[currentExtentIndex].partition.cprange.lo_val; - if (extents[currentExtentIndex].partition.cprange.isValid == BRM::CP_VALID && max >= min) - bs << min; + if (extents[currentExtentIndex].partition.cprange.isValid == BRM::CP_VALID && max >= min) + bs << min; + else + bs << utils::getNullValue(colType.colDataType, colType.colWidth); + } else - bs << utils::getNullValue(colType.colDataType, colType.colWidth); + { + int128_t max = extents[currentExtentIndex].partition.cprange.bigHiVal; + int128_t min = extents[currentExtentIndex].partition.cprange.bigLoVal; + + if (extents[currentExtentIndex].partition.cprange.isValid == BRM::CP_VALID && max >= min) + bs << (uint128_t) min; + else + { + int128_t int128Null; + utils::setWideDecimalNullValue(int128Null); + bs << (uint128_t) int128Null; + } + } } else if (function == PSEUDO_EXTENTID) bs << extents[currentExtentIndex].range.start; diff --git a/dbcon/joblist/rowestimator.cpp b/dbcon/joblist/rowestimator.cpp index 21369332f..1a5e5f73d 100644 --- a/dbcon/joblist/rowestimator.cpp +++ b/dbcon/joblist/rowestimator.cpp @@ -140,12 +140,13 @@ uint64_t RowEstimator::adjustValue(const execplan::CalpontSystemCatalog::ColType // Estimates the number of distinct values given a min/max range. When the range has not been set, // rules from the requirements are used based on the column type. +template uint32_t RowEstimator::estimateDistinctValues(const execplan::CalpontSystemCatalog::ColType& ct, - const uint64_t& min, - const uint64_t& max, + const T& min, + const T& max, const char cpStatus) { - uint64_t ret = 10; + T ret = 10; // If no casual partitioning info available for extent. These rules were defined in the requirements. if (cpStatus != BRM::CP_VALID) @@ -199,7 +200,7 @@ uint32_t RowEstimator::estimateDistinctValues(const execplan::CalpontSystemCatal ret = max - min + 1; } - if (ret > fRowsPerExtent) + if (ret > (T) fRowsPerExtent) { ret = fRowsPerExtent; } @@ -210,7 +211,10 @@ uint32_t RowEstimator::estimateDistinctValues(const execplan::CalpontSystemCatal // Returns a floating point number between 0 and 1 representing the percentage of matching rows for the given predicate against // the given range. This function is used for estimating an individual operation such as col1 = 2. template -float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, char op, uint8_t lcf, uint32_t distinctValues, char cpStatus) +float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, + char op, uint8_t lcf, + uint32_t distinctValues, char cpStatus, + const execplan::CalpontSystemCatalog::ColType& ct) { float factor = 1.0; @@ -220,7 +224,10 @@ float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, case COMPARE_NGE: if (cpStatus == BRM::CP_VALID) { - factor = (1.0 * value - min) / (max - min + 1); + if (!datatypes::Decimal::isWideDecimalType(ct)) + factor = (1.0 * value - min) / (max - min + 1); + else + factor = ((__float128) value - min) / (max - min + 1); } break; @@ -229,7 +236,10 @@ float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, case COMPARE_NGT: if (cpStatus == BRM::CP_VALID) { - factor = (1.0 * value - min + 1) / (max - min + 1); + if (!datatypes::Decimal::isWideDecimalType(ct)) + factor = (1.0 * value - min + 1) / (max - min + 1); + else + factor = ((__float128) value - min + 1) / (max - min + 1); } break; @@ -238,7 +248,10 @@ float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, case COMPARE_NLE: if (cpStatus == BRM::CP_VALID) { - factor = (1.0 * max - value) / (1.0 * max - min + 1); + if (!datatypes::Decimal::isWideDecimalType(ct)) + factor = (1.0 * max - value) / (1.0 * max - min + 1); + else + factor = (1.0 * max - value) / (1.0 * max - min + 1); } break; @@ -248,7 +261,10 @@ float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, if (cpStatus == BRM::CP_VALID) { // TODO: Best way to convert to floating point arithmetic? - factor = (1.0 * max - value + 1) / (max - min + 1); + if (!datatypes::Decimal::isWideDecimalType(ct)) + factor = (1.0 * max - value + 1) / (max - min + 1); + else + factor = (1.0 * max - value + 1) / (max - min + 1); } break; @@ -287,11 +303,26 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, float factor = 1.0; float tempFactor = 1.0; + uint64_t adjustedMin, adjustedMax; + uint128_t adjustedBigMin, adjustedBigMax; + uint32_t distinctValuesEstimate; + // Adjust values based on column type and estimate the - uint64_t adjustedMin = adjustValue(ct, emEntry.partition.cprange.lo_val); - uint64_t adjustedMax = adjustValue(ct, emEntry.partition.cprange.hi_val); - uint32_t distinctValuesEstimate = estimateDistinctValues( - ct, adjustedMin, adjustedMax, emEntry.partition.cprange.isValid); + if (!datatypes::Decimal::isWideDecimalType(ct)) + { + adjustedMin = adjustValue(ct, emEntry.partition.cprange.lo_val); + adjustedMax = adjustValue(ct, emEntry.partition.cprange.hi_val); + distinctValuesEstimate = estimateDistinctValues( + ct, adjustedMin, adjustedMax, emEntry.partition.cprange.isValid); + } + else + { + adjustedBigMin = emEntry.partition.cprange.bigLoVal; + adjustedBigMax = emEntry.partition.cprange.bigHiVal; + distinctValuesEstimate = estimateDistinctValues( + ct, adjustedBigMin, adjustedBigMax, emEntry.partition.cprange.isValid); + } + // Loop through the operations and estimate the percentage of rows that will qualify. // For example, there are two operations for "col1 > 5 and col1 < 10": @@ -300,6 +331,7 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, int length = bs->length(), pos = 0; const char* msgDataPtr = (const char*) bs->buf(); int64_t value = 0; + int128_t bigValue = 0; bool firstQualifyingOrCondition = true; uint16_t comparisonLimit = (NOPS <= fMaxComparisons) ? NOPS : fMaxComparisons; @@ -343,6 +375,18 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, break; } + case 16: + { + if (ct.colDataType == execplan::CalpontSystemCatalog::DECIMAL || + ct.colDataType == execplan::CalpontSystemCatalog::UDECIMAL) + { + uint128_t val = *(uint128_t*)msgDataPtr; + bigValue = static_cast(val); + break; + } + /* fall through */ + } + case 8: default: { @@ -377,6 +421,18 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, break; } + case 16: + { + if (ct.colDataType == execplan::CalpontSystemCatalog::DECIMAL || + ct.colDataType == execplan::CalpontSystemCatalog::UDECIMAL) + { + int128_t val = *(int128_t*)msgDataPtr; + bigValue = static_cast(val); + break; + } + /* fall through */ + } + case 8: default: { @@ -404,15 +460,33 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, // Get the factor for the individual operation. if (bIsUnsigned) { - tempFactor = estimateOpFactor( - adjustedMin, adjustedMax, adjustValue(ct, value), op, lcf, - distinctValuesEstimate, emEntry.partition.cprange.isValid); + if (!datatypes::Decimal::isWideDecimalType(ct)) + { + tempFactor = estimateOpFactor( + adjustedMin, adjustedMax, adjustValue(ct, value), op, lcf, + distinctValuesEstimate, emEntry.partition.cprange.isValid, ct); + } + else + { + tempFactor = estimateOpFactor( + adjustedBigMin, adjustedBigMax, bigValue, op, lcf, + distinctValuesEstimate, emEntry.partition.cprange.isValid, ct); + } } else { - tempFactor = estimateOpFactor( - adjustedMin, adjustedMax, adjustValue(ct, value), op, lcf, - distinctValuesEstimate, emEntry.partition.cprange.isValid); + if (!datatypes::Decimal::isWideDecimalType(ct)) + { + tempFactor = estimateOpFactor( + adjustedMin, adjustedMax, adjustValue(ct, value), op, lcf, + distinctValuesEstimate, emEntry.partition.cprange.isValid, ct); + } + else + { + tempFactor = estimateOpFactor( + adjustedBigMin, adjustedBigMax, bigValue, op, lcf, + distinctValuesEstimate, emEntry.partition.cprange.isValid, ct); + } } #if ROW_EST_DEBUG @@ -611,4 +685,16 @@ uint64_t RowEstimator::estimateRowsForNonCPColumn(ColumnCommandJL& colCmd) return estimatedRows; } +template +uint32_t RowEstimator::estimateDistinctValues(const execplan::CalpontSystemCatalog::ColType& ct, + const int128_t& min, + const int128_t& max, + const char cpStatus); + +template +uint32_t RowEstimator::estimateDistinctValues(const execplan::CalpontSystemCatalog::ColType& ct, + const int64_t& min, + const int64_t& max, + const char cpStatus); + } //namespace joblist diff --git a/dbcon/joblist/rowestimator.h b/dbcon/joblist/rowestimator.h index 477bc2b30..a4c702a44 100644 --- a/dbcon/joblist/rowestimator.h +++ b/dbcon/joblist/rowestimator.h @@ -89,9 +89,10 @@ private: uint32_t daysThroughMonth(uint32_t mth); + template uint32_t estimateDistinctValues(const execplan::CalpontSystemCatalog::ColType& ct, - const uint64_t& min, - const uint64_t& max, + const T& min, + const T& max, const char cpStatus); /** @brief returns a factor between 0 and 1 for the estimate of rows that will qualify the given individual operation. @@ -106,7 +107,8 @@ private: */ template float estimateOpFactor(const T& min, const T& max, const T& value, char op, uint8_t lcf, - uint32_t distinctValues, char cpStatus); + uint32_t distinctValues, char cpStatus, + const execplan::CalpontSystemCatalog::ColType& ct); /** @brief returns a factor between 0 and 1 for the estimate of rows that will qualify * the given operation(s). diff --git a/dbcon/joblist/tuple-bps.cpp b/dbcon/joblist/tuple-bps.cpp index 4c65f2dc3..7df74cc54 100644 --- a/dbcon/joblist/tuple-bps.cpp +++ b/dbcon/joblist/tuple-bps.cpp @@ -1421,7 +1421,8 @@ void TupleBPS::sendJobs(const vector& jobs) } } -bool TupleBPS::compareSingleValue(uint8_t COP, int64_t val1, int64_t val2) const +template +bool TupleBPS::compareSingleValue(uint8_t COP, T val1, T val2) const { switch (COP) { @@ -1536,7 +1537,8 @@ bool TupleBPS::processSingleFilterString_ranged(int8_t BOP, int8_t colWidth, int return ret; } -bool TupleBPS::processSingleFilterString(int8_t BOP, int8_t colWidth, int64_t val, const uint8_t* filterString, +template +bool TupleBPS::processSingleFilterString(int8_t BOP, int8_t colWidth, T val, const uint8_t* filterString, uint32_t filterCount) const { uint j; @@ -1546,6 +1548,7 @@ bool TupleBPS::processSingleFilterString(int8_t BOP, int8_t colWidth, int64_t va { int8_t COP; int64_t val2; + int128_t bigVal2; bool thisPredicate; COP = *filterString++; filterString++; // skip the round var, don't think that applies here @@ -1572,11 +1575,19 @@ bool TupleBPS::processSingleFilterString(int8_t BOP, int8_t colWidth, int64_t va filterString += 8; break; + case 16: + bigVal2 = *((int128_t*) filterString); + filterString += 16; + break; + default: throw logic_error("invalid column width"); } - thisPredicate = compareSingleValue(COP, val, val2); + if (colWidth < 16) + thisPredicate = compareSingleValue(COP, (int64_t) val, val2); + else + thisPredicate = compareSingleValue(COP, (int128_t) val, bigVal2); if (j == 0) ret = thisPredicate; @@ -1590,7 +1601,8 @@ bool TupleBPS::processSingleFilterString(int8_t BOP, int8_t colWidth, int64_t va return ret; } -bool TupleBPS::processOneFilterType(int8_t colWidth, int64_t value, uint32_t type) const +template +bool TupleBPS::processOneFilterType(int8_t colWidth, T value, uint32_t type) const { const vector& filters = fBPP->getFilterSteps(); uint i; @@ -1681,9 +1693,13 @@ bool TupleBPS::processPseudoColFilters(uint32_t extentIndex, boost::shared_ptrsetJoinFERG(rg); } -void TupleBPS::addCPPredicates(uint32_t OID, const vector& vals, bool isRange) +void TupleBPS::addCPPredicates(uint32_t OID, const vector<__int128>& vals, bool isRange, + bool isSmallSideWideDecimal) { if (fTraceFlags & CalpontSelectExecutionPlan::IGNORE_CP || fOid < 3000) @@ -3200,6 +3221,7 @@ void TupleBPS::addCPPredicates(uint32_t OID, const vector& vals, bool i uint32_t i, j, k; int64_t min, max, seq; + __int128 bigMin, bigMax; bool isValid, intersection; vector colCmdVec = fBPP->getFilterSteps(); ColumnCommandJL* cmd; @@ -3223,7 +3245,9 @@ void TupleBPS::addCPPredicates(uint32_t OID, const vector& vals, bool i if (cmd != NULL && cmd->getOID() == OID) { - if (!ll.CasualPartitionDataType(cmd->getColType().colDataType, cmd->getColType().colWidth) + const execplan::CalpontSystemCatalog::ColType& colType = cmd->getColType(); + + if (!ll.CasualPartitionDataType(colType.colDataType, colType.colWidth) || cmd->isDict()) return; @@ -3250,25 +3274,73 @@ void TupleBPS::addCPPredicates(uint32_t OID, const vector& vals, bool i extentsPtr = &mref; } - for (j = 0; j < extents.size(); j++) + if (colType.colWidth <= 8) { - isValid = ll.GetMinMax(&min, &max, &seq, extents[j].range.start, *extentsPtr, - cmd->getColType().colDataType); - - if (isValid) + for (j = 0; j < extents.size(); j++) { - if (isRange) - runtimeCPFlags[j] = ll.checkRangeOverlap(min, max, vals[0], vals[1], - cmd->getColType().colDataType) && runtimeCPFlags[j]; - else + isValid = ll.GetMinMax(&min, &max, &seq, extents[j].range.start, *extentsPtr, + colType.colDataType); + + if (isValid) { - intersection = false; + if (isRange) + { + if (!isSmallSideWideDecimal) + { + runtimeCPFlags[j] = ll.checkRangeOverlap(min, max, (int64_t) vals[0], (int64_t) vals[1], + colType.colDataType) && runtimeCPFlags[j]; + } + else + { + runtimeCPFlags[j] = ll.checkRangeOverlap((__int128) min, (__int128) max, vals[0], vals[1], + colType.colDataType) && runtimeCPFlags[j]; + } + } + else + { + intersection = false; - for (k = 0; k < vals.size(); k++) - intersection = intersection || - ll.checkSingleValue(min, max, vals[k], cmd->getColType().colDataType); + for (k = 0; k < vals.size(); k++) + { + if (!isSmallSideWideDecimal) + { + intersection = intersection || + ll.checkSingleValue(min, max, (int64_t) vals[k], colType.colDataType); + } + else + { + intersection = intersection || + ll.checkSingleValue((__int128) min, (__int128) max, vals[k], colType.colDataType); + } + } - runtimeCPFlags[j] = intersection && runtimeCPFlags[j]; + runtimeCPFlags[j] = intersection && runtimeCPFlags[j]; + } + } + } + } + else + { + for (j = 0; j < extents.size(); j++) + { + isValid = ll.GetMinMax(&bigMin, &bigMax, &seq, extents[j].range.start, *extentsPtr, + colType.colDataType); + + if (isValid) + { + if (isRange) + runtimeCPFlags[j] = ll.checkRangeOverlap(bigMin, bigMax, vals[0], vals[1], + colType.colDataType) && runtimeCPFlags[j]; + else + { + intersection = false; + + for (k = 0; k < vals.size(); k++) + intersection = intersection || + ll.checkSingleValue(bigMin, bigMax, vals[k], colType.colDataType); + + runtimeCPFlags[j] = intersection && runtimeCPFlags[j]; + } } } } @@ -3326,5 +3398,22 @@ void TupleBPS::abort() abort_nolock(); } +template +bool TupleBPS::processOneFilterType(int8_t colWidth, int64_t value, uint32_t type) const; +template +bool TupleBPS::processOneFilterType(int8_t colWidth, int128_t value, uint32_t type) const; + +template +bool TupleBPS::processSingleFilterString(int8_t BOP, int8_t colWidth, int64_t val, const uint8_t* filterString, + uint32_t filterCount) const; +template +bool TupleBPS::processSingleFilterString(int8_t BOP, int8_t colWidth, int128_t val, const uint8_t* filterString, + uint32_t filterCount) const; + +template +bool TupleBPS::compareSingleValue(uint8_t COP, int64_t val1, int64_t val2) const; +template +bool TupleBPS::compareSingleValue(uint8_t COP, int128_t val1, int128_t val2) const; + } //namespace // vim:ts=4 sw=4: diff --git a/dbcon/joblist/tuplehashjoin.cpp b/dbcon/joblist/tuplehashjoin.cpp index e7ddbb235..35639814a 100644 --- a/dbcon/joblist/tuplehashjoin.cpp +++ b/dbcon/joblist/tuplehashjoin.cpp @@ -476,7 +476,9 @@ void TupleHashJoinStep::forwardCPData() for (col = 0; col < joiners[i]->getSmallKeyColumns().size(); col++) { - if (smallRGs[i].isLongString(joiners[i]->getSmallKeyColumns()[col])) + uint32_t idx = joiners[i]->getSmallKeyColumns()[col]; + + if (smallRGs[i].isLongString(idx)) continue; // @bug3683, not to add CP predicates if large side is not simple column @@ -484,8 +486,12 @@ void TupleHashJoinStep::forwardCPData() fFunctionJoinKeys.end()) continue; + bool isSmallSideWideDecimal = + datatypes::Decimal::isWideDecimalType(smallRGs[i].getColType(idx), smallRGs[i].getColumnWidth(idx)); + largeBPS->addCPPredicates(largeRG.getOIDs()[joiners[i]->getLargeKeyColumns()[col]], - joiners[i]->getCPData()[col], !joiners[i]->discreteCPValues()[col]); + joiners[i]->getCPData()[col], !joiners[i]->discreteCPValues()[col], + isSmallSideWideDecimal); } } } diff --git a/dbcon/mysql/ha_mcs_partition.cpp b/dbcon/mysql/ha_mcs_partition.cpp index 7271fba51..8b64ac3c3 100644 --- a/dbcon/mysql/ha_mcs_partition.cpp +++ b/dbcon/mysql/ha_mcs_partition.cpp @@ -48,6 +48,7 @@ using namespace BRM; #include "dataconvert.h" using namespace dataconvert; +#include "widedecimalutils.h" #include "ddlpkg.h" #include "sqlparser.h" using namespace ddlpackage; @@ -250,8 +251,8 @@ struct PartitionInfo max((uint64_t) - 0x8000000000000001LL), status(0) { - DataConvert::int128Min(bigMin); - DataConvert::int128Max(bigMax); + utils::int128Min(bigMin); + utils::int128Max(bigMax); }; }; @@ -311,7 +312,7 @@ const string format(T v, CalpontSystemCatalog::ColType& ct) } else { - char buf[MAX_DECIMAL_STRING_LENGTH]; + char buf[utils::MAXLENGTH16BYTES]; DataConvert::decimalToString((__int128*)&v, (unsigned)ct.scale, buf, sizeof(buf), ct.colDataType); oss << buf; } @@ -339,9 +340,10 @@ const string format(T v, CalpontSystemCatalog::ColType& ct) return oss.str(); } -int64_t IDB_format(char* str, CalpontSystemCatalog::ColType& ct, uint8_t& rf) +template +T IDB_format(char* str, CalpontSystemCatalog::ColType& ct, uint8_t& rf) { - int64_t v = 0; + T v = 0; bool pushWarning = false; rf = 0; boost::any anyVal = DataConvert::convertColumnData(ct, str, pushWarning, current_thd->variables.time_zone->get_name()->ptr(), false, true, false); @@ -433,8 +435,10 @@ int64_t IDB_format(char* str, CalpontSystemCatalog::ColType& ct, uint8_t& rf) #else v = boost::any_cast(anyVal); #endif - else + else if (ct.colWidth == execplan::CalpontSystemCatalog::EIGHT_BYTE) v = boost::any_cast(anyVal); + else + v = boost::any_cast(anyVal); break; @@ -656,6 +660,7 @@ void partitionByValue_common(UDF_ARGS* args, // input string schema, table, column; CalpontSystemCatalog::ColType ct; int64_t startVal, endVal; + int128_t bigStartVal, bigEndVal; uint8_t rfMin = 0, rfMax = 0; if (args->arg_count == 5) @@ -728,68 +733,136 @@ void partitionByValue_common(UDF_ARGS* args, // input { if (!args->args[2]) { - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - startVal = 0; + if (isUnsigned(ct.colDataType)) + { + startVal = 0; + } + else + { + startVal = numeric_limits::min(); + } } else { - startVal = numeric_limits::min(); + if (isUnsigned(ct.colDataType)) + { + bigStartVal = 0; + } + else + { + utils::int128Min(bigStartVal); + } } } else { - startVal = IDB_format((char*) args->args[2], ct, rfMin); + if (!datatypes::Decimal::isWideDecimalType(ct)) + startVal = IDB_format((char*) args->args[2], ct, rfMin); + else + bigStartVal = IDB_format((char*) args->args[2], ct, rfMin); } if (!args->args[3]) { - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - endVal = static_cast(numeric_limits::max()); + if (isUnsigned(ct.colDataType)) + { + endVal = static_cast(numeric_limits::max()); + } + else + { + endVal = numeric_limits::max(); + } } else { - endVal = numeric_limits::max(); + if (isUnsigned(ct.colDataType)) + { + bigEndVal = -1; + } + else + { + utils::int128Max(bigEndVal); + } } } else { - endVal = IDB_format((char*) args->args[3], ct, rfMax); + if (!datatypes::Decimal::isWideDecimalType(ct)) + endVal = IDB_format((char*) args->args[3], ct, rfMax); + else + bigEndVal = IDB_format((char*) args->args[3], ct, rfMax); } } else { if (!args->args[3]) { - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - startVal = 0; + if (isUnsigned(ct.colDataType)) + { + startVal = 0; + } + else + { + startVal = numeric_limits::min(); + } } else { - startVal = numeric_limits::min(); + if (isUnsigned(ct.colDataType)) + { + bigStartVal = 0; + } + else + { + utils::int128Min(bigStartVal); + } } } else { - startVal = IDB_format((char*) args->args[3], ct, rfMin); + if (!datatypes::Decimal::isWideDecimalType(ct)) + startVal = IDB_format((char*) args->args[3], ct, rfMin); + else + bigStartVal = IDB_format((char*) args->args[3], ct, rfMin); } if (!args->args[4]) { - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - endVal = static_cast(numeric_limits::max()); + if (isUnsigned(ct.colDataType)) + { + endVal = static_cast(numeric_limits::max()); + } + else + { + endVal = numeric_limits::max(); + } } else { - endVal = numeric_limits::max(); + if (isUnsigned(ct.colDataType)) + { + bigEndVal = -1; + } + else + { + utils::int128Max(bigEndVal); + } } } else { - endVal = IDB_format((char*) args->args[4], ct, rfMax); + if (!datatypes::Decimal::isWideDecimalType(ct)) + endVal = IDB_format((char*) args->args[4], ct, rfMax); + else + bigEndVal = IDB_format((char*) args->args[4], ct, rfMax); } } @@ -810,7 +883,13 @@ void partitionByValue_common(UDF_ARGS* args, // input partInfo.status |= ET_DISABLED; mapit = partMap.find(logicalPartNum); - int state = em.getExtentMaxMin(iter->range.start, partInfo.max, partInfo.min, seqNum); + + int state; + + if (!datatypes::Decimal::isWideDecimalType(ct)) + state = em.getExtentMaxMin(iter->range.start, partInfo.max, partInfo.min, seqNum); + else + state = em.getExtentMaxMin(iter->range.start, partInfo.bigMax, partInfo.bigMin, seqNum); // char column order swap if ((ct.colDataType == CalpontSystemCatalog::CHAR && ct.colWidth <= 8) || @@ -832,17 +911,35 @@ void partitionByValue_common(UDF_ARGS* args, // input if (mapit->second.status & CPINVALID) continue; - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - mapit->second.min = - (static_cast(partInfo.min) < static_cast(mapit->second.min) ? partInfo.min : mapit->second.min); - mapit->second.max = - (static_cast(partInfo.max) > static_cast(mapit->second.max) ? partInfo.max : mapit->second.max); + if (isUnsigned(ct.colDataType)) + { + mapit->second.min = + (static_cast(partInfo.min) < static_cast(mapit->second.min) ? partInfo.min : mapit->second.min); + mapit->second.max = + (static_cast(partInfo.max) > static_cast(mapit->second.max) ? partInfo.max : mapit->second.max); + } + else + { + mapit->second.min = (partInfo.min < mapit->second.min ? partInfo.min : mapit->second.min); + mapit->second.max = (partInfo.max > mapit->second.max ? partInfo.max : mapit->second.max); + } } else { - mapit->second.min = (partInfo.min < mapit->second.min ? partInfo.min : mapit->second.min); - mapit->second.max = (partInfo.max > mapit->second.max ? partInfo.max : mapit->second.max); + if (isUnsigned(ct.colDataType)) + { + mapit->second.bigMin = + (static_cast(partInfo.bigMin) < static_cast(mapit->second.bigMin) ? partInfo.bigMin : mapit->second.bigMin); + mapit->second.bigMax = + (static_cast(partInfo.bigMax) > static_cast(mapit->second.bigMax) ? partInfo.bigMax : mapit->second.bigMax); + } + else + { + mapit->second.bigMin = (partInfo.bigMin < mapit->second.bigMin ? partInfo.bigMin : mapit->second.bigMin); + mapit->second.bigMax = (partInfo.bigMax > mapit->second.bigMax ? partInfo.bigMax : mapit->second.bigMax); + } } } } @@ -851,35 +948,72 @@ void partitionByValue_common(UDF_ARGS* args, // input for (mapit = partMap.begin(); mapit != partMap.end(); ++mapit) { // @bug 4595. check empty/null case - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - if (!(mapit->second.status & CPINVALID) && - static_cast(mapit->second.min) >= static_cast(startVal) && - static_cast(mapit->second.max) <= static_cast(endVal) && - !(static_cast(mapit->second.min) == numeric_limits::max() && - static_cast(mapit->second.max == 0))) + if (isUnsigned(ct.colDataType)) { - if (rfMin == ROUND_POS && mapit->second.min == startVal) - continue; + if (!(mapit->second.status & CPINVALID) && + static_cast(mapit->second.min) >= static_cast(startVal) && + static_cast(mapit->second.max) <= static_cast(endVal) && + !(static_cast(mapit->second.min) == numeric_limits::max() && + static_cast(mapit->second.max == 0))) + { + if (rfMin == ROUND_POS && mapit->second.min == startVal) + continue; - if (rfMax == ROUND_NEG && mapit->second.max == endVal) - continue; + if (rfMax == ROUND_NEG && mapit->second.max == endVal) + continue; - partSet.insert(mapit->first); + partSet.insert(mapit->first); + } + } + else + { + if (!(mapit->second.status & CPINVALID) && mapit->second.min >= startVal && mapit->second.max <= endVal && + !(mapit->second.min == numeric_limits::max() && mapit->second.max == numeric_limits::min())) + { + if (rfMin == ROUND_POS && mapit->second.min == startVal) + continue; + + if (rfMax == ROUND_NEG && mapit->second.max == endVal) + continue; + + partSet.insert(mapit->first); + } } } else { - if (!(mapit->second.status & CPINVALID) && mapit->second.min >= startVal && mapit->second.max <= endVal && - !(mapit->second.min == numeric_limits::max() && mapit->second.max == numeric_limits::min())) + if (isUnsigned(ct.colDataType)) { - if (rfMin == ROUND_POS && mapit->second.min == startVal) - continue; + if (!(mapit->second.status & CPINVALID) && + static_cast(mapit->second.bigMin) >= static_cast(bigStartVal) && + static_cast(mapit->second.bigMax) <= static_cast(bigEndVal) && + !(static_cast(mapit->second.bigMin) == static_cast(-1) && + static_cast(mapit->second.bigMax == 0))) + { + if (rfMin == ROUND_POS && mapit->second.bigMin == bigStartVal) + continue; - if (rfMax == ROUND_NEG && mapit->second.max == endVal) - continue; + if (rfMax == ROUND_NEG && mapit->second.bigMax == bigEndVal) + continue; - partSet.insert(mapit->first); + partSet.insert(mapit->first); + } + } + else + { + if (!(mapit->second.status & CPINVALID) && mapit->second.bigMin >= bigStartVal && mapit->second.bigMax <= bigEndVal && + !(mapit->second.bigMin == utils::maxInt128 && mapit->second.bigMax == utils::minInt128)) + { + if (rfMin == ROUND_POS && mapit->second.bigMin == bigStartVal) + continue; + + if (rfMax == ROUND_NEG && mapit->second.bigMax == bigEndVal) + continue; + + partSet.insert(mapit->first); + } } } } @@ -1102,9 +1236,9 @@ extern "C" int state = CP_INVALID; - if (ct.colWidth <= 8) + if (!datatypes::Decimal::isWideDecimalType(ct)) state = em.getExtentMaxMin(iter->range.start, partInfo.max, partInfo.min, seqNum); - else if (ct.colWidth == 16) + else state = em.getExtentMaxMin(iter->range.start, partInfo.bigMax, partInfo.bigMin, seqNum); // char column order swap for compare @@ -1127,12 +1261,12 @@ extern "C" if (mapit->second.status & CPINVALID) continue; - if (ct.colWidth <= 8) + if (!datatypes::Decimal::isWideDecimalType(ct)) { mapit->second.min = (partInfo.min < mapit->second.min ? partInfo.min : mapit->second.min); mapit->second.max = (partInfo.max > mapit->second.max ? partInfo.max : mapit->second.max); } - else if (ct.colWidth == 16) + else { mapit->second.bigMin = (partInfo.bigMin < mapit->second.bigMin ? partInfo.bigMin : mapit->second.bigMin); mapit->second.bigMax = (partInfo.bigMax > mapit->second.bigMax ? partInfo.bigMax : mapit->second.bigMax); @@ -1156,7 +1290,7 @@ extern "C" ostringstream output; output.setf(ios::left, ios::adjustfield); - if (ct.colWidth <= 8) + if (!datatypes::Decimal::isWideDecimalType(ct)) { output << setw(10) << "Part#" << setw(30) << "Min" @@ -1165,18 +1299,18 @@ extern "C" else { output << setw(10) << "Part#" - << setw(40) << "Min" - << setw(40) << "Max" << "Status"; + << setw(42) << "Min" + << setw(42) << "Max" << "Status"; } int64_t maxLimit = numeric_limits::max(); int64_t minLimit = numeric_limits::min(); __int128 bigMaxLimit, bigMinLimit; - DataConvert::int128Max(bigMaxLimit); - DataConvert::int128Min(bigMinLimit); + utils::int128Max(bigMaxLimit); + utils::int128Min(bigMinLimit); unsigned __int128 ubigMaxLimit, ubigMinLimit; - DataConvert::uint128Max(ubigMaxLimit); + utils::uint128Max(ubigMaxLimit); ubigMinLimit = 0; // char column order swap for compare in subsequent loop @@ -1197,16 +1331,16 @@ extern "C" if (partIt->second.status & CPINVALID) { - if (ct.colWidth <= 8) + if (!datatypes::Decimal::isWideDecimalType(ct)) output << setw(30) << "N/A" << setw(30) << "N/A"; else - output << setw(40) << "N/A" << setw(40) << "N/A"; + output << setw(42) << "N/A" << setw(42) << "N/A"; } else { if ((isUnsigned(ct.colDataType))) { - if (ct.colWidth <= 8) + if (!datatypes::Decimal::isWideDecimalType(ct)) { if (static_cast(partIt->second.min) == numeric_limits::max() && static_cast(partIt->second.max) == numeric_limits::min()) @@ -1218,14 +1352,14 @@ extern "C" { if (static_cast(partIt->second.bigMin) == ubigMaxLimit && static_cast(partIt->second.bigMax) == ubigMinLimit) - output << setw(40) << "Empty/Null" << setw(40) << "Empty/Null"; + output << setw(42) << "Empty/Null" << setw(42) << "Empty/Null"; else - output << setw(40) << format(partIt->second.bigMin, ct) << setw(40) << format(partIt->second.bigMax, ct); + output << setw(42) << format(partIt->second.bigMin, ct) << setw(42) << format(partIt->second.bigMax, ct); } } else { - if (ct.colWidth <= 8) + if (!datatypes::Decimal::isWideDecimalType(ct)) { if (partIt->second.min == maxLimit && partIt->second.max == minLimit) output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; @@ -1235,9 +1369,9 @@ extern "C" else { if (partIt->second.bigMin == bigMaxLimit && partIt->second.bigMax == bigMinLimit) - output << setw(40) << "Empty/Null" << setw(40) << "Empty/Null"; + output << setw(42) << "Empty/Null" << setw(42) << "Empty/Null"; else - output << setw(40) << format(partIt->second.bigMin, ct) << setw(40) << format(partIt->second.bigMax, ct); + output << setw(42) << format(partIt->second.bigMin, ct) << setw(42) << format(partIt->second.bigMax, ct); } } } @@ -1801,6 +1935,7 @@ extern "C" CalpontSystemCatalog::ColType ct; string errMsg; int64_t startVal, endVal; + int128_t bigStartVal, bigEndVal; uint8_t rfMin = 0, rfMax = 0; try @@ -1859,68 +1994,136 @@ extern "C" { if (!args->args[2]) { - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - startVal = 0; + if (isUnsigned(ct.colDataType)) + { + startVal = 0; + } + else + { + startVal = numeric_limits::min(); + } } else { - startVal = numeric_limits::min(); + if (isUnsigned(ct.colDataType)) + { + bigStartVal = 0; + } + else + { + utils::int128Min(bigStartVal); + } } } else { - startVal = IDB_format((char*) args->args[2], ct, rfMin); + if (!datatypes::Decimal::isWideDecimalType(ct)) + startVal = IDB_format((char*) args->args[2], ct, rfMin); + else + bigStartVal = IDB_format((char*) args->args[2], ct, rfMin); } if (!args->args[3]) { - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - endVal = static_cast(numeric_limits::max()); + if (isUnsigned(ct.colDataType)) + { + endVal = static_cast(numeric_limits::max()); + } + else + { + endVal = numeric_limits::max(); + } } else { - endVal = numeric_limits::max(); + if (isUnsigned(ct.colDataType)) + { + bigEndVal = -1; + } + else + { + utils::int128Max(bigEndVal); + } } } else { - endVal = IDB_format((char*) args->args[3], ct, rfMax); + if (!datatypes::Decimal::isWideDecimalType(ct)) + endVal = IDB_format((char*) args->args[3], ct, rfMax); + else + bigEndVal = IDB_format((char*) args->args[3], ct, rfMax); } } else { if (!args->args[3]) { - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - startVal = 0; + if (isUnsigned(ct.colDataType)) + { + startVal = 0; + } + else + { + startVal = numeric_limits::min(); + } } else { - startVal = numeric_limits::min(); + if (isUnsigned(ct.colDataType)) + { + bigStartVal = 0; + } + else + { + utils::int128Min(bigStartVal); + } } } else { - startVal = IDB_format((char*) args->args[3], ct, rfMin); + if (!datatypes::Decimal::isWideDecimalType(ct)) + startVal = IDB_format((char*) args->args[3], ct, rfMin); + else + bigStartVal = IDB_format((char*) args->args[3], ct, rfMin); } if (!args->args[4]) { - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - endVal = static_cast(numeric_limits::max()); + if (isUnsigned(ct.colDataType)) + { + endVal = static_cast(numeric_limits::max()); + } + else + { + endVal = numeric_limits::max(); + } } else { - endVal = numeric_limits::max(); + if (isUnsigned(ct.colDataType)) + { + bigEndVal = -1; + } + else + { + utils::int128Max(bigEndVal); + } } } else { - endVal = IDB_format((char*) args->args[4], ct, rfMax); + if (!datatypes::Decimal::isWideDecimalType(ct)) + endVal = IDB_format((char*) args->args[4], ct, rfMax); + else + bigEndVal = IDB_format((char*) args->args[4], ct, rfMax); } } @@ -1943,7 +2146,13 @@ extern "C" partInfo.status |= ET_DISABLED; mapit = partMap.find(logicalPartNum); - int state = em.getExtentMaxMin(iter->range.start, partInfo.max, partInfo.min, seqNum); + + int state; + + if (!datatypes::Decimal::isWideDecimalType(ct)) + state = em.getExtentMaxMin(iter->range.start, partInfo.max, partInfo.min, seqNum); + else + state = em.getExtentMaxMin(iter->range.start, partInfo.bigMax, partInfo.bigMin, seqNum); // char column order swap if ((ct.colDataType == CalpontSystemCatalog::CHAR && ct.colWidth <= 8) || @@ -1965,17 +2174,35 @@ extern "C" if (mapit->second.status & CPINVALID) continue; - if (isUnsigned(ct.colDataType)) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - mapit->second.min = - (static_cast(partInfo.min) < static_cast(mapit->second.min) ? partInfo.min : mapit->second.min); - mapit->second.max = - (static_cast(partInfo.max) > static_cast(mapit->second.max) ? partInfo.max : mapit->second.max); + if (isUnsigned(ct.colDataType)) + { + mapit->second.min = + (static_cast(partInfo.min) < static_cast(mapit->second.min) ? partInfo.min : mapit->second.min); + mapit->second.max = + (static_cast(partInfo.max) > static_cast(mapit->second.max) ? partInfo.max : mapit->second.max); + } + else + { + mapit->second.min = (partInfo.min < mapit->second.min ? partInfo.min : mapit->second.min); + mapit->second.max = (partInfo.max > mapit->second.max ? partInfo.max : mapit->second.max); + } } else { - mapit->second.min = (partInfo.min < mapit->second.min ? partInfo.min : mapit->second.min); - mapit->second.max = (partInfo.max > mapit->second.max ? partInfo.max : mapit->second.max); + if (isUnsigned(ct.colDataType)) + { + mapit->second.bigMin = + (static_cast(partInfo.bigMin) < static_cast(mapit->second.bigMin) ? partInfo.bigMin : mapit->second.bigMin); + mapit->second.bigMax = + (static_cast(partInfo.bigMax) > static_cast(mapit->second.bigMax) ? partInfo.bigMax : mapit->second.bigMax); + } + else + { + mapit->second.bigMin = (partInfo.bigMin < mapit->second.bigMin ? partInfo.bigMin : mapit->second.bigMin); + mapit->second.bigMax = (partInfo.bigMax > mapit->second.bigMax ? partInfo.bigMax : mapit->second.bigMax); + } } } } @@ -2010,57 +2237,115 @@ extern "C" for (mapit = partMap.begin(); mapit != partMap.end(); ++mapit) { // @bug 4595. check empty/null case - if (!(mapit->second.status & CPINVALID) && mapit->second.min >= startVal && mapit->second.max <= endVal && - !(mapit->second.min == numeric_limits::max() && mapit->second.max == numeric_limits::min())) + if (!datatypes::Decimal::isWideDecimalType(ct)) { - if (rfMin == ROUND_POS && mapit->second.min == startVal) - continue; - - if (rfMax == ROUND_NEG && mapit->second.max == endVal) - continue; - - // print header - if (noPartFound) + if (!(mapit->second.status & CPINVALID) && mapit->second.min >= startVal && mapit->second.max <= endVal && + !(mapit->second.min == numeric_limits::max() && mapit->second.max == numeric_limits::min())) { - output.setf(ios::left, ios::adjustfield); - output << setw(10) << "Part#" - << setw(30) << "Min" - << setw(30) << "Max" << "Status"; - } + if (rfMin == ROUND_POS && mapit->second.min == startVal) + continue; - noPartFound = false; + if (rfMax == ROUND_NEG && mapit->second.max == endVal) + continue; - // print part info - ostringstream oss; - oss << mapit->first; - output << "\n " << setw(10) << oss.str(); - - if (mapit->second.status & CPINVALID) - { - output << setw(30) << "N/A" << setw(30) << "N/A"; - } - else - { - if ((isUnsigned(ct.colDataType))) + // print header + if (noPartFound) { - if (static_cast(mapit->second.min) > static_cast(mapit->second.max)) - output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; - else - output << setw(30) << format(mapit->second.min, ct) << setw(30) << format(mapit->second.max, ct); + output.setf(ios::left, ios::adjustfield); + output << setw(10) << "Part#" + << setw(30) << "Min" + << setw(30) << "Max" << "Status"; + } + + noPartFound = false; + + // print part info + ostringstream oss; + oss << mapit->first; + output << "\n " << setw(10) << oss.str(); + + if (mapit->second.status & CPINVALID) + { + output << setw(30) << "N/A" << setw(30) << "N/A"; } else { - if (mapit->second.min > mapit->second.max) - output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; + if ((isUnsigned(ct.colDataType))) + { + if (static_cast(mapit->second.min) > static_cast(mapit->second.max)) + output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; + else + output << setw(30) << format(mapit->second.min, ct) << setw(30) << format(mapit->second.max, ct); + } else - output << setw(30) << format(mapit->second.min, ct) << setw(30) << format(mapit->second.max, ct); + { + if (mapit->second.min > mapit->second.max) + output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; + else + output << setw(30) << format(mapit->second.min, ct) << setw(30) << format(mapit->second.max, ct); + } } - } - if (mapit->second.status & ET_DISABLED) - output << "Disabled"; - else - output << "Enabled"; + if (mapit->second.status & ET_DISABLED) + output << "Disabled"; + else + output << "Enabled"; + } + } + else + { + if (!(mapit->second.status & CPINVALID) && mapit->second.bigMin >= bigStartVal && mapit->second.bigMax <= bigEndVal && + !(mapit->second.bigMin == utils::maxInt128 && mapit->second.bigMax == utils::minInt128)) + { + if (rfMin == ROUND_POS && mapit->second.bigMin == bigStartVal) + continue; + + if (rfMax == ROUND_NEG && mapit->second.bigMax == bigEndVal) + continue; + + // print header + if (noPartFound) + { + output.setf(ios::left, ios::adjustfield); + output << setw(10) << "Part#" + << setw(42) << "Min" + << setw(42) << "Max" << "Status"; + } + + noPartFound = false; + + // print part info + ostringstream oss; + oss << mapit->first; + output << "\n " << setw(10) << oss.str(); + + if (mapit->second.status & CPINVALID) + { + output << setw(42) << "N/A" << setw(42) << "N/A"; + } + else + { + if ((isUnsigned(ct.colDataType))) + { + if (static_cast(mapit->second.bigMin) > static_cast(mapit->second.bigMax)) + output << setw(42) << "Empty/Null" << setw(42) << "Empty/Null"; + else + output << setw(42) << format(mapit->second.bigMin, ct) << setw(42) << format(mapit->second.bigMax, ct); + } + else + { + if (mapit->second.bigMin > mapit->second.bigMax) + output << setw(42) << "Empty/Null" << setw(42) << "Empty/Null"; + else + output << setw(42) << format(mapit->second.bigMin, ct) << setw(42) << format(mapit->second.bigMax, ct); + } + } + + if (mapit->second.status & ET_DISABLED) + output << "Disabled"; + else + output << "Enabled"; + } } } diff --git a/dbcon/mysql/is_columnstore_extents.cpp b/dbcon/mysql/is_columnstore_extents.cpp index 188ce31dc..d93152a52 100644 --- a/dbcon/mysql/is_columnstore_extents.cpp +++ b/dbcon/mysql/is_columnstore_extents.cpp @@ -27,6 +27,9 @@ #include "dbrm.h" #include "objectidmanager.h" #include "is_columnstore.h" +#include "mcs_decimal.h" +#include "widedecimalutils.h" +#include "dataconvert.h" // Required declaration as it isn't in a MairaDB include bool schema_table_store_record(THD* thd, TABLE* table); @@ -37,8 +40,10 @@ ST_FIELD_INFO is_columnstore_extents_fields[] = Show::Column("OBJECT_TYPE", Show::Varchar(64), NOT_NULL), // 1 Show::Column("LOGICAL_BLOCK_START", Show::SLonglong(0), NOT_NULL), // 2 Show::Column("LOGICAL_BLOCK_END", Show::SLonglong(0), NOT_NULL), // 3 - Show::Column("MIN_VALUE", Show::SLonglong(0), NULLABLE), // 4 - Show::Column("MAX_VALUE", Show::SLonglong(0), NULLABLE), // 5 + // length=3800 here because sql/sql_i_s.h sets + // decimal_precision() as (length / 100) % 100). Not sure why. + Show::Column("MIN_VALUE", Show::Decimal(3800), NULLABLE), // 4 + Show::Column("MAX_VALUE", Show::Decimal(3800), NULLABLE), // 5 Show::Column("WIDTH", Show::ULong(0), NOT_NULL), // 6 Show::Column("DBROOT", Show::ULong(0), NOT_NULL), // 7 Show::Column("PARTITION_ID", Show::ULong(0), NOT_NULL), // 8 @@ -75,26 +80,61 @@ static int generate_result(BRM::OID_t oid, BRM::DBRM* emp, TABLE* table, THD* th { table->field[1]->store("Column", strlen("Column"), cs); - if (iter->partition.cprange.lo_val == std::numeric_limits::max() || - iter->partition.cprange.lo_val <= (std::numeric_limits::min() + 2)) + if (iter->colWid != datatypes::MAXDECIMALWIDTH) { - table->field[4]->set_null(); - } - else - { - table->field[4]->set_notnull(); - table->field[4]->store(iter->partition.cprange.lo_val); - } + if (iter->partition.cprange.lo_val == std::numeric_limits::max() || + iter->partition.cprange.lo_val <= (std::numeric_limits::min() + 1)) + { + table->field[4]->set_null(); + } + else + { + table->field[4]->set_notnull(); + table->field[4]->store(iter->partition.cprange.lo_val); + } - if (iter->partition.cprange.hi_val == std::numeric_limits::max() || - iter->partition.cprange.hi_val <= (std::numeric_limits::min() + 2)) - { - table->field[5]->set_null(); + if (iter->partition.cprange.hi_val <= (std::numeric_limits::min() + 1)) + { + table->field[5]->set_null(); + } + else + { + table->field[5]->set_notnull(); + table->field[5]->store(iter->partition.cprange.hi_val); + } } else { - table->field[5]->set_notnull(); - table->field[5]->store(iter->partition.cprange.hi_val); + if (iter->partition.cprange.bigLoVal == utils::maxInt128 || + iter->partition.cprange.bigLoVal <= (utils::minInt128 + 1)) + { + table->field[4]->set_null(); + } + else + { + table->field[4]->set_notnull(); + + char buf[utils::MAXLENGTH16BYTES]; + dataconvert::DataConvert::decimalToString( + &iter->partition.cprange.bigLoVal, + 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + table->field[4]->store(buf, strlen(buf), table->field[4]->charset()); + } + + if (iter->partition.cprange.bigHiVal <= (utils::minInt128 + 1)) + { + table->field[5]->set_null(); + } + else + { + table->field[5]->set_notnull(); + + char buf[utils::MAXLENGTH16BYTES]; + dataconvert::DataConvert::decimalToString( + &iter->partition.cprange.bigHiVal, + 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + table->field[5]->store(buf, strlen(buf), table->field[5]->charset()); + } } table->field[6]->store(iter->colWid); diff --git a/primitives/linux-port/column.cpp b/primitives/linux-port/column.cpp index d9724d727..446d81e05 100644 --- a/primitives/linux-port/column.cpp +++ b/primitives/linux-port/column.cpp @@ -1597,8 +1597,8 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, } else { - dataconvert::DataConvert::int128Max(out->Min); - dataconvert::DataConvert::int128Min(out->Max); + utils::int128Max(out->Min); + utils::int128Min(out->Max); } } else diff --git a/primitives/primproc/batchprimitiveprocessor.cpp b/primitives/primproc/batchprimitiveprocessor.cpp index 4a2021daa..999f95518 100644 --- a/primitives/primproc/batchprimitiveprocessor.cpp +++ b/primitives/primproc/batchprimitiveprocessor.cpp @@ -54,6 +54,7 @@ using namespace boost; #include "MonitorProcMem.h" #include "threadnaming.h" #include "vlarray.h" +#include "widedecimalutils.h" #define MAX64 0x7fffffffffffffffLL #define MIN64 0x8000000000000000LL @@ -1098,8 +1099,8 @@ void BatchPrimitiveProcessor::initProcessor() } else { - dataconvert::DataConvert::int128Min(bigMaxVal); - dataconvert::DataConvert::int128Max(bigMinVal); + utils::int128Min(bigMaxVal); + utils::int128Max(bigMinVal); } // @bug 1269, initialize data used by execute() for async loading blocks @@ -2213,8 +2214,8 @@ int BatchPrimitiveProcessor::operator()() } else { - dataconvert::DataConvert::int128Min(bigMaxVal); - dataconvert::DataConvert::int128Max(bigMinVal); + utils::int128Min(bigMaxVal); + utils::int128Max(bigMinVal); } validCPData = false; #ifdef PRIMPROC_STOPWATCH diff --git a/primitives/primproc/pseudocc.cpp b/primitives/primproc/pseudocc.cpp index 7550c1b47..4fb3ba8d8 100644 --- a/primitives/primproc/pseudocc.cpp +++ b/primitives/primproc/pseudocc.cpp @@ -42,6 +42,7 @@ SCommand PseudoCC::duplicate() ret.reset(pseudo); pseudo->function = function; pseudo->valueFromUM = valueFromUM; + pseudo->bigValueFromUM = bigValueFromUM; ColumnCommand::duplicate(pseudo); return ret; } @@ -55,9 +56,21 @@ void PseudoCC::createCommand(messageqcpp::ByteStream& bs) void PseudoCC::resetCommand(messageqcpp::ByteStream& bs) { - if (function == PSEUDO_EXTENTMAX || function == PSEUDO_EXTENTMIN || function == PSEUDO_EXTENTID) + if (function == PSEUDO_EXTENTMAX || function == PSEUDO_EXTENTMIN) + { + if (!datatypes::Decimal::isWideDecimalType(colType)) + bs >> valueFromUM; + else + bs >> bigValueFromUM; + } + else if (function == PSEUDO_EXTENTID) + { bs >> valueFromUM; + if (datatypes::Decimal::isWideDecimalType(colType)) + bigValueFromUM = valueFromUM; + } + ColumnCommand::resetCommand(bs); } @@ -91,8 +104,11 @@ void PseudoCC::loadData() case 8: loadPMNumber(); break; + case 16: - cout << __FILE__<< ":" <<__LINE__ << " Fix for 16 Bytes ?" << endl; + loadPMNumber(); + break; + default: cout << "PC::loadData(): bad column width" << endl; break; @@ -119,6 +135,10 @@ void PseudoCC::loadData() loadRIDs(); break; + case 16: + loadRIDs(); + break; + default: cout << "PC::loadData(): bad column width" << endl; break; @@ -144,8 +164,11 @@ void PseudoCC::loadData() case 8: loadSegmentNum(); break; + case 16: - cout << __FILE__<< ":" <<__LINE__ << " Fix for 16 Bytes ?" << endl; + loadSegmentNum(); + break; + default: cout << "PC::loadData(): bad column width" << endl; break; @@ -173,7 +196,9 @@ void PseudoCC::loadData() break; case 16: - cout << __FILE__<< ":" <<__LINE__ << " Fix for 16 Bytes ?" << endl; + loadPartitionNum(); + break; + default: cout << "PC::loadData(): bad column width" << endl; break; @@ -201,7 +226,9 @@ void PseudoCC::loadData() break; case 16: - cout << __FILE__<< ":" <<__LINE__ << " Fix for 16 Bytes ?" << endl; + loadLBID(); + break; + default: cout << "PC::loadData(): bad column width" << endl; break; @@ -227,8 +254,10 @@ void PseudoCC::loadData() case 8: loadDBRootNum(); break; + case 16: - cout << __FILE__<< ":" <<__LINE__ << " Fix for 16 Bytes ?" << endl; + loadDBRootNum(); + break; default: cout << "PC::loadData(): bad column width" << endl; @@ -258,8 +287,10 @@ void PseudoCC::loadData() case 8: loadSingleValue(valueFromUM); break; + case 16: - cout << __FILE__<< ":" <<__LINE__ << " Fix for 16 Bytes ?" << endl; + loadSingleValue(bigValueFromUM); + break; default: cout << "PC::loadData(): bad column width" << endl; diff --git a/primitives/primproc/pseudocc.h b/primitives/primproc/pseudocc.h index 1a4d84c44..d59cc3360 100644 --- a/primitives/primproc/pseudocc.h +++ b/primitives/primproc/pseudocc.h @@ -49,6 +49,7 @@ private: uint32_t function; uint64_t valueFromUM; + uint128_t bigValueFromUM; }; diff --git a/tools/editem/editem.cpp b/tools/editem/editem.cpp index f2b392dad..c8cc31683 100644 --- a/tools/editem/editem.cpp +++ b/tools/editem/editem.cpp @@ -44,6 +44,9 @@ using namespace config; #include "dataconvert.h" using namespace dataconvert; +#include "widedecimalutils.h" +#include "mcs_decimal.h" + #include "liboamcpp.h" #undef REALLY_DANGEROUS @@ -164,40 +167,97 @@ const string charcolToString(int64_t v) //------------------------------------------------------------------------------ // Formats an integer to it's date, datetime, or char equivalent //------------------------------------------------------------------------------ -const string fmt(int64_t v) +template +const string fmt(T v) { ostringstream oss; if (tflg) { - oss << DataConvert::dateToString(v); + oss << DataConvert::dateToString((int64_t) v); } else if (sflg) { - oss << DataConvert::datetimeToString(v); + oss << DataConvert::datetimeToString((int64_t) v); } else if (aflg) { - oss << charcolToString(v); + oss << charcolToString((int64_t) v); } else if (mflg) { - oss << v; + if (typeid(T) != typeid(int128_t)) + { + oss << (int64_t) v; + } + else + { + char buf[utils::MAXLENGTH16BYTES]; + + int128_t tmp = v; + + dataconvert::DataConvert::decimalToString( + &tmp, 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + + oss << buf; + } } else if (uflg) { - if (static_cast(v) > numeric_limits::max() - 2) - oss << "notset"; + if (typeid(T) != typeid(int128_t)) + { + if (static_cast(v) > numeric_limits::max() - 2) + oss << "notset"; + else + oss << static_cast(v); + } else - oss << static_cast(v); + { + if (v <= utils::minInt128 + 1) + { + oss << "notset"; + } + else + { + char buf[utils::MAXLENGTH16BYTES]; + + int128_t tmp = static_cast(v); + + dataconvert::DataConvert::decimalToString( + &tmp, 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + + oss << buf; + } + } } else { - if (v == numeric_limits::max() || - v <= (numeric_limits::min() + 2)) - oss << "notset"; + if (typeid(T) != typeid(int128_t)) + { + if (v == numeric_limits::max() || + v <= (numeric_limits::min() + 1)) + oss << "notset"; + else + oss << (int64_t) v; + } else - oss << v; + { + if (v == utils::maxInt128 || (v <= utils::minInt128 + 1)) + { + oss << "notset"; + } + else + { + char buf[utils::MAXLENGTH16BYTES]; + + int128_t tmp = v; + + dataconvert::DataConvert::decimalToString( + &tmp, 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + + oss << buf; + } + } } return oss.str(); @@ -234,6 +294,8 @@ int dumpone(OID_t oid, unsigned int sortOrder) std::vector::iterator end; int64_t max; int64_t min; + int128_t bigMax; + int128_t bigMin; int32_t seqNum; bool header; bool needtrailer = false; @@ -262,8 +324,6 @@ int dumpone(OID_t oid, unsigned int sortOrder) while (iter != end) { uint32_t lbidRangeSize = iter->range.size * 1024; - max = iter->partition.cprange.hi_val; - min = iter->partition.cprange.lo_val; seqNum = iter->partition.cprange.sequenceNum; int state = iter->partition.cprange.isValid; @@ -287,10 +347,26 @@ int dumpone(OID_t oid, unsigned int sortOrder) if (vflg) cout << oid << ' '; - cout << iter->range.start << " - " << - (iter->range.start + lbidRangeSize - 1) << - " (" << lbidRangeSize << ") min: " << fmt(min) << - ", max: " << fmt(max) << ", seqNum: " << seqNum << ", state: "; + if (iter->colWid != datatypes::MAXDECIMALWIDTH) + { + max = iter->partition.cprange.hi_val; + min = iter->partition.cprange.lo_val; + + cout << iter->range.start << " - " << + (iter->range.start + lbidRangeSize - 1) << + " (" << lbidRangeSize << ") min: " << fmt(min) << + ", max: " << fmt(max) << ", seqNum: " << seqNum << ", state: "; + } + else + { + bigMax = iter->partition.cprange.bigHiVal; + bigMin = iter->partition.cprange.bigLoVal; + + cout << iter->range.start << " - " << + (iter->range.start + lbidRangeSize - 1) << + " (" << lbidRangeSize << ") min: " << fmt(bigMin) << + ", max: " << fmt(bigMax) << ", seqNum: " << seqNum << ", state: "; + } switch (state) { @@ -415,7 +491,7 @@ int clearAllCPData() if (entries.empty()) continue; - bool isBinaryColumn = entries[0].colWid > 8; + bool isBinaryColumn = (entries[0].colWid == datatypes::MAXDECIMALWIDTH); BRM::CPInfo cpInfo; BRM::CPInfoList_t vCpInfo; @@ -427,8 +503,8 @@ int clearAllCPData() } else { - dataconvert::DataConvert::int128Min(cpInfo.bigMax); - dataconvert::DataConvert::int128Max(cpInfo.bigMin); + utils::int128Min(cpInfo.bigMax); + utils::int128Max(cpInfo.bigMin); } cpInfo.seqNum = -1; @@ -466,7 +542,7 @@ int clearmm(OID_t oid) return 1; } - bool isBinaryColumn = entries[0].colWid > 8; + bool isBinaryColumn = (entries[0].colWid == datatypes::MAXDECIMALWIDTH); // @bug 2280. Changed to use the batch interface to clear the CP info to make the clear option faster. BRM::CPInfo cpInfo; @@ -479,8 +555,8 @@ int clearmm(OID_t oid) } else { - dataconvert::DataConvert::int128Min(cpInfo.bigMax); - dataconvert::DataConvert::int128Max(cpInfo.bigMin); + utils::int128Min(cpInfo.bigMax); + utils::int128Max(cpInfo.bigMin); } cpInfo.seqNum = -1; diff --git a/utils/common/hasher.h b/utils/common/hasher.h index 4978689c4..27d7fbd01 100644 --- a/utils/common/hasher.h +++ b/utils/common/hasher.h @@ -30,6 +30,8 @@ #include #include +using int128_t = __int128; + namespace utils { /** @brief class Hasher @@ -346,6 +348,25 @@ public: } }; +// TODO a copy of these classes also exists in primitiveprocessor.h; consolidate +class Hash128 +{ +public: + inline size_t operator()(const int128_t i) const + { + return *reinterpret_cast(&i); + } +}; + +class Equal128 +{ +public: + inline bool operator()(const int128_t f1, const int128_t f2) const + { + return f1 == f2; + } +}; + //------------------------------------------------------------------------------ /** @brief class TupleHasher * diff --git a/utils/common/widedecimalutils.h b/utils/common/widedecimalutils.h index 2ed5b7309..6efa1b595 100644 --- a/utils/common/widedecimalutils.h +++ b/utils/common/widedecimalutils.h @@ -32,6 +32,9 @@ namespace utils const uint8_t MAXLENGTH16BYTES = 42; const uint8_t MAXLENGTH8BYTES = 23; + const int128_t minInt128 = int128_t(0x8000000000000000LL) << 64; + const int128_t maxInt128 = (int128_t(0x7FFFFFFFFFFFFFFFLL) << 64) + 0xFFFFFFFFFFFFFFFFLL; + inline bool isWideDecimalNullValue(const int128_t& val) { const uint64_t* ptr = reinterpret_cast(&val); diff --git a/utils/dataconvert/dataconvert.h b/utils/dataconvert/dataconvert.h index 7c9f69278..2636919e0 100644 --- a/utils/dataconvert/dataconvert.h +++ b/utils/dataconvert/dataconvert.h @@ -161,21 +161,10 @@ const int32_t MIN_TIMESTAMP_VALUE = 0; namespace dataconvert { -// Decimal has maximum 38 digits with 3 extra chars for dot(.), minus(-), null character(\0) -const int MAX_DECIMAL_STRING_LENGTH = 41; - // WIP MCOL-641 using int128_t = __int128; using uint128_t = unsigned __int128; -struct Int128Pod_struct -{ - uint64_t lo; - uint64_t hi; -}; - -typedef Int128Pod_struct Int128Pod_t; - enum CalpontDateTimeFormat { CALPONTDATE_ENUM = 1, // date format is: "YYYY-MM-DD" @@ -1067,27 +1056,6 @@ public: static size_t writeFractionalPart(int128_t* dec, char* p, const unsigned int buflen, const uint8_t scale); - static inline void int128Max(int128_t& i) - { - Int128Pod_t *pod = reinterpret_cast(&i); - pod->lo = 0xFFFFFFFFFFFFFFFF; - pod->hi = 0x7FFFFFFFFFFFFFFF; - } - - static inline void int128Min(int128_t& i) - { - Int128Pod_t *pod = reinterpret_cast(&i); - pod->lo = 0; - pod->hi = 0x8000000000000000; - } - - static inline void uint128Max(uint128_t& i) - { - Int128Pod_t *pod = reinterpret_cast(&i); - pod->lo = 0xFFFFFFFFFFFFFFFF; - pod->hi = 0xFFFFFFFFFFFFFFFF; - } - static inline std::string constructRegexp(const std::string& str); static inline void trimWhitespace(int64_t& charData); static inline bool isEscapedChar(char c) diff --git a/utils/joiner/tuplejoiner.cpp b/utils/joiner/tuplejoiner.cpp index a8e853553..ee405dd89 100644 --- a/utils/joiner/tuplejoiner.cpp +++ b/utils/joiner/tuplejoiner.cpp @@ -20,16 +20,19 @@ #include #include #include -#ifdef _MSC_VER -#include -#else +#ifndef _MSC_VER #include +#else +#include #endif + #include "hasher.h" #include "lbidlist.h" #include "spinlock.h" #include "vlarray.h" +#include "widedecimalutils.h" + using namespace std; using namespace rowgroup; using namespace utils; @@ -102,18 +105,38 @@ TupleJoiner::TupleJoiner( smallKeyColumns.push_back(smallJoinColumn); largeKeyColumns.push_back(largeJoinColumn); discreteValues.reset(new bool[1]); - cpValues.reset(new vector[1]); + cpValues.reset(new vector[1]); discreteValues[0] = false; if (smallRG.isUnsigned(smallKeyColumns[0])) { - cpValues[0].push_back(numeric_limits::max()); - cpValues[0].push_back(0); + if (datatypes::Decimal::isWideDecimalType( + smallRG.getColType(smallKeyColumns[0]), + smallRG.getColumnWidth(smallKeyColumns[0]))) + { + cpValues[0].push_back((int128_t) -1); + cpValues[0].push_back(0); + } + else + { + cpValues[0].push_back((int128_t) numeric_limits::max()); + cpValues[0].push_back(0); + } } else { - cpValues[0].push_back(numeric_limits::max()); - cpValues[0].push_back(numeric_limits::min()); + if (datatypes::Decimal::isWideDecimalType( + smallRG.getColType(smallKeyColumns[0]), + smallRG.getColumnWidth(smallKeyColumns[0]))) + { + cpValues[0].push_back(utils::maxInt128); + cpValues[0].push_back(utils::minInt128); + } + else + { + cpValues[0].push_back((int128_t) numeric_limits::max()); + cpValues[0].push_back((int128_t) numeric_limits::min()); + } } if (smallRG.isUnsigned(smallJoinColumn) != largeRG.isUnsigned(largeJoinColumn)) @@ -195,20 +218,40 @@ TupleJoiner::TupleJoiner( storedKeyAlloc[i].setAllocSize(keyLength); discreteValues.reset(new bool[smallKeyColumns.size()]); - cpValues.reset(new vector[smallKeyColumns.size()]); + cpValues.reset(new vector[smallKeyColumns.size()]); for (i = 0; i < smallKeyColumns.size(); i++) { discreteValues[i] = false; if (isUnsigned(smallRG.getColTypes()[smallKeyColumns[i]])) { - cpValues[i].push_back(static_cast(numeric_limits::max())); - cpValues[i].push_back(0); + if (datatypes::Decimal::isWideDecimalType( + smallRG.getColType(smallKeyColumns[i]), + smallRG.getColumnWidth(smallKeyColumns[i]))) + { + cpValues[i].push_back((int128_t) -1); + cpValues[i].push_back(0); + } + else + { + cpValues[i].push_back((int128_t) numeric_limits::max()); + cpValues[i].push_back(0); + } } else { - cpValues[i].push_back(numeric_limits::max()); - cpValues[i].push_back(numeric_limits::min()); + if (datatypes::Decimal::isWideDecimalType( + smallRG.getColType(smallKeyColumns[i]), + smallRG.getColumnWidth(smallKeyColumns[i]))) + { + cpValues[i].push_back(utils::maxInt128); + cpValues[i].push_back(utils::minInt128); + } + else + { + cpValues[i].push_back(numeric_limits::max()); + cpValues[i].push_back(numeric_limits::min()); + } } } } @@ -678,8 +721,9 @@ void TupleJoiner::doneInserting() for (col = 0; col < smallKeyColumns.size(); col++) { - tr1::unordered_set uniquer; - tr1::unordered_set::iterator uit; + typedef std::tr1::unordered_set unordered_set_int128; + unordered_set_int128 uniquer; + unordered_set_int128::iterator uit; sthash_t::iterator sthit; hash_t::iterator hit; ldhash_t::iterator ldit; @@ -758,6 +802,12 @@ void TupleJoiner::doneInserting() } } } + else if (datatypes::Decimal::isWideDecimalType( + smallRow.getColType(smallKeyColumns[col]), + smallRow.getColumnWidth(smallKeyColumns[col]))) + { + uniquer.insert(*((int128_t*)smallRow.getBinaryField(smallKeyColumns[col]))); + } else if (smallRow.isUnsigned(smallKeyColumns[col])) { uniquer.insert((int64_t)smallRow.getUintField(smallKeyColumns[col])); @@ -1080,21 +1130,22 @@ void TupleJoiner::updateCPData(const Row& r) { int64_t val = r.getIntField(colIdx); - if (order_swap(val) < order_swap(min) || - min == numeric_limits::max()) + if (order_swap(val) < order_swap((int64_t) min) || + ((int64_t) min) == numeric_limits::max()) { min = val; } - if (order_swap(val) > order_swap(max) || - max == numeric_limits::min()) + if (order_swap(val) > order_swap((int64_t) max) || + ((int64_t) max) == numeric_limits::min()) { max = val; } } else if (r.isUnsigned(colIdx)) { - uint64_t uval; + uint128_t uval; + if (r.getColType(colIdx) == CalpontSystemCatalog::LONGDOUBLE) { double dval = (double)roundl(r.getLongDoubleField(smallKeyColumns[col])); @@ -1114,20 +1165,27 @@ void TupleJoiner::updateCPData(const Row& r) } } } + else if (datatypes::Decimal::isWideDecimalType( + r.getColType(colIdx), + r.getColumnWidth(colIdx))) + { + uval = *((int128_t*)r.getBinaryField(colIdx)); + } else { uval = r.getUintField(colIdx); } - if (uval > static_cast(max)) - max = static_cast(uval); + if (uval > static_cast(max)) + max = static_cast(uval); - if (uval < static_cast(min)) - min = static_cast(uval); + if (uval < static_cast(min)) + min = static_cast(uval); } else { - int64_t val = 0; + int128_t val = 0; + if (r.getColType(colIdx) == CalpontSystemCatalog::LONGDOUBLE) { double dval = (double)roundl(r.getLongDoubleField(colIdx)); @@ -1147,13 +1205,12 @@ void TupleJoiner::updateCPData(const Row& r) } } } - else if (r.getColumnWidth(colIdx) == datatypes::MAXDECIMALWIDTH - && (r.getColType(colIdx) == CalpontSystemCatalog::DECIMAL - || r.getColType(colIdx) == CalpontSystemCatalog::UDECIMAL)) + else if (datatypes::Decimal::isWideDecimalType( + r.getColType(colIdx), + r.getColumnWidth(colIdx))) { - // WIP MCOL-641 + val = *((int128_t*)r.getBinaryField(colIdx)); } - else { val = r.getIntField(colIdx); @@ -1681,20 +1738,40 @@ boost::shared_ptr TupleJoiner::copyForDiskJoin() ret->uniqueLimit = uniqueLimit; ret->discreteValues.reset(new bool[smallKeyColumns.size()]); - ret->cpValues.reset(new vector[smallKeyColumns.size()]); + ret->cpValues.reset(new vector[smallKeyColumns.size()]); for (uint32_t i = 0; i < smallKeyColumns.size(); i++) { ret->discreteValues[i] = false; if (isUnsigned(smallRG.getColTypes()[smallKeyColumns[i]])) { - ret->cpValues[i].push_back(static_cast(numeric_limits::max())); - ret->cpValues[i].push_back(0); + if (datatypes::Decimal::isWideDecimalType( + smallRG.getColType(smallKeyColumns[i]), + smallRG.getColumnWidth(smallKeyColumns[i]))) + { + ret->cpValues[i].push_back((int128_t) -1); + ret->cpValues[i].push_back(0); + } + else + { + ret->cpValues[i].push_back((int128_t) numeric_limits::max()); + ret->cpValues[i].push_back(0); + } } else { - ret->cpValues[i].push_back(numeric_limits::max()); - ret->cpValues[i].push_back(numeric_limits::min()); + if (datatypes::Decimal::isWideDecimalType( + smallRG.getColType(smallKeyColumns[i]), + smallRG.getColumnWidth(smallKeyColumns[i]))) + { + ret->cpValues[i].push_back(utils::maxInt128); + ret->cpValues[i].push_back(utils::minInt128); + } + else + { + ret->cpValues[i].push_back(numeric_limits::max()); + ret->cpValues[i].push_back(numeric_limits::min()); + } } } diff --git a/utils/joiner/tuplejoiner.h b/utils/joiner/tuplejoiner.h index d91297845..c1be13eac 100644 --- a/utils/joiner/tuplejoiner.h +++ b/utils/joiner/tuplejoiner.h @@ -287,7 +287,7 @@ public: { return discreteValues; } - inline const boost::scoped_array >& getCPData() + inline const boost::scoped_array >& getCPData() { return cpValues; } @@ -413,7 +413,7 @@ private: /* Runtime casual partitioning support */ void updateCPData(const rowgroup::Row& r); boost::scoped_array discreteValues; - boost::scoped_array > cpValues; // if !discreteValues, [0] has min, [1] has max + boost::scoped_array > cpValues; // if !discreteValues, [0] has min, [1] has max uint32_t uniqueLimit; bool finished; diff --git a/utils/rowgroup/rowgroup.h b/utils/rowgroup/rowgroup.h index 22d47e16e..c6a1daed8 100644 --- a/utils/rowgroup/rowgroup.h +++ b/utils/rowgroup/rowgroup.h @@ -66,6 +66,7 @@ typedef const struct charset_info_st CHARSET_INFO; // Workaround for my_global.h #define of isnan(X) causing a std::std namespace using int128_t = __int128; +using uint128_t = unsigned __int128; namespace rowgroup { diff --git a/versioning/BRM/blockresolutionmanager.cpp b/versioning/BRM/blockresolutionmanager.cpp index 7127f3f43..6004a3832 100644 --- a/versioning/BRM/blockresolutionmanager.cpp +++ b/versioning/BRM/blockresolutionmanager.cpp @@ -107,10 +107,10 @@ int BlockResolutionManager::saveState(string filename) throw() saveExtentMap(emFilename); // truncate teh file if already exists since no truncate in HDFS. - const char* filename = journalFilename.c_str(); + const char* filename_p = journalFilename.c_str(); IDBDataFile* journal = IDBDataFile::open( - IDBPolicy::getType(filename, IDBPolicy::WRITEENG), filename, "wb", 0); + IDBPolicy::getType(filename_p, IDBPolicy::WRITEENG), filename_p, "wb", 0); delete journal; vbbm.save(vbbmFilename); diff --git a/versioning/BRM/dbrm.cpp b/versioning/BRM/dbrm.cpp index 028efad55..bd27c3aec 100644 --- a/versioning/BRM/dbrm.cpp +++ b/versioning/BRM/dbrm.cpp @@ -31,6 +31,7 @@ #include #include "dataconvert.h" +#include "widedecimalutils.h" #include "oamcache.h" #include "rwlock.h" #include "mastersegmenttable.h" @@ -4560,8 +4561,8 @@ void DBRM::invalidateUncommittedExtentLBIDs(execplan::CalpontSystemCatalog::SCN } else { - dataconvert::DataConvert::int128Min(aInfo.bigMax); - dataconvert::DataConvert::int128Max(aInfo.bigMin); + utils::int128Min(aInfo.bigMax); + utils::int128Max(aInfo.bigMin); } } } diff --git a/versioning/BRM/extentmap.cpp b/versioning/BRM/extentmap.cpp index d549da71f..70d12a383 100644 --- a/versioning/BRM/extentmap.cpp +++ b/versioning/BRM/extentmap.cpp @@ -55,6 +55,7 @@ namespace bi = boost::interprocess; #include "mastersegmenttable.h" #include "blocksize.h" #include "dataconvert.h" +#include "widedecimalutils.h" #include "oamcache.h" #include "IDBDataFile.h" #include "IDBPolicy.h" @@ -118,8 +119,8 @@ EMCasualPartition_struct::EMCasualPartition_struct() { lo_val = numeric_limits::max(); hi_val = numeric_limits::min(); - dataconvert::DataConvert::int128Max(bigLoVal); - dataconvert::DataConvert::int128Min(bigHiVal); + utils::int128Max(bigLoVal); + utils::int128Min(bigHiVal); sequenceNum = 0; isValid = CP_INVALID; } @@ -360,8 +361,8 @@ int ExtentMap::_markInvalid(const LBID_t lbid, const execplan::CalpontSystemCata { fExtentMap[i].partition.cprange.lo_val = numeric_limits::max(); fExtentMap[i].partition.cprange.hi_val = numeric_limits::min(); - dataconvert::DataConvert::int128Max(fExtentMap[i].partition.cprange.bigLoVal); - dataconvert::DataConvert::int128Min(fExtentMap[i].partition.cprange.bigHiVal); + utils::int128Max(fExtentMap[i].partition.cprange.bigLoVal); + utils::int128Min(fExtentMap[i].partition.cprange.bigHiVal); } incSeqNum(fExtentMap[i].partition.cprange.sequenceNum); @@ -1048,7 +1049,7 @@ bool ExtentMap::isValidCPRange(const T& max, const T& min, execplan::CalpontSyst else { unsigned __int128 temp; - dataconvert::DataConvert::uint128Max(temp); + utils::uint128Max(temp); if ( (static_cast(min) >= (temp - 1)) || (static_cast(max) >= (temp - 1)) ) @@ -1070,7 +1071,7 @@ bool ExtentMap::isValidCPRange(const T& max, const T& min, execplan::CalpontSyst else { __int128 temp; - dataconvert::DataConvert::int128Min(temp); + utils::int128Min(temp); if ( (min <= (temp + 1)) || (max <= (temp + 1)) ) @@ -1112,8 +1113,8 @@ int ExtentMap::getMaxMin(const LBID_t lbid, if (typeid(T) == typeid(__int128)) { __int128 tmpMax, tmpMin; - dataconvert::DataConvert::int128Min(tmpMax); - dataconvert::DataConvert::int128Max(tmpMin); + utils::int128Min(tmpMax); + utils::int128Max(tmpMin); max = tmpMax; min = tmpMin; } @@ -2730,8 +2731,8 @@ LBID_t ExtentMap::_createColumnExtent_DBroot(uint32_t size, int OID, } else { - dataconvert::DataConvert::int128Max(e->partition.cprange.bigLoVal); - dataconvert::DataConvert::int128Min(e->partition.cprange.bigHiVal); + utils::int128Max(e->partition.cprange.bigLoVal); + utils::int128Min(e->partition.cprange.bigHiVal); } } @@ -2941,8 +2942,8 @@ LBID_t ExtentMap::_createColumnExtentExactFile(uint32_t size, int OID, } else { - dataconvert::DataConvert::int128Max(e->partition.cprange.bigLoVal); - dataconvert::DataConvert::int128Min(e->partition.cprange.bigHiVal); + utils::int128Max(e->partition.cprange.bigLoVal); + utils::int128Min(e->partition.cprange.bigHiVal); } } @@ -3128,8 +3129,8 @@ LBID_t ExtentMap::_createDictStoreExtent(uint32_t size, int OID, e->status = EXTENTUNAVAILABLE;// @bug 1911 mark extent as in process e->partition.cprange.lo_val = numeric_limits::max(); e->partition.cprange.hi_val = numeric_limits::min(); - dataconvert::DataConvert::int128Max(e->partition.cprange.bigLoVal); - dataconvert::DataConvert::int128Min(e->partition.cprange.bigHiVal); + utils::int128Max(e->partition.cprange.bigLoVal); + utils::int128Min(e->partition.cprange.bigHiVal); e->partition.cprange.sequenceNum = 0; e->partition.cprange.isValid = CP_INVALID; diff --git a/writeengine/bulk/we_brmreporter.cpp b/writeengine/bulk/we_brmreporter.cpp index 0787700be..f86490bec 100644 --- a/writeengine/bulk/we_brmreporter.cpp +++ b/writeengine/bulk/we_brmreporter.cpp @@ -34,6 +34,9 @@ #include "we_log.h" #include "cacheutils.h" #include "IDBPolicy.h" +#include "widedecimalutils.h" +#include "mcs_decimal.h" +#include "dataconvert.h" namespace WriteEngine { @@ -294,11 +297,11 @@ void BRMReporter::sendHWMToFile( ) //------------------------------------------------------------------------------ // Send Casual Partition update information to BRM //------------------------------------------------------------------------------ -// TODO MCOL-641 void BRMReporter::sendCPToFile( ) { if (fCPInfo.size() > 0) { + char buf[utils::MAXLENGTH16BYTES]; std::ostringstream oss; oss << "Writing " << fCPInfo.size() << " CP updates for table " << fTableName << " to report file " << fRptFileName; @@ -306,12 +309,32 @@ void BRMReporter::sendCPToFile( ) for (unsigned int i = 0; i < fCPInfo.size(); i++) { - fRptFile << "CP: " << fCPInfo[i].startLbid << ' ' << - fCPInfo[i].max << ' ' << - fCPInfo[i].min << ' ' << - fCPInfo[i].seqNum << ' ' << - fCPInfo[i].type << ' ' << - fCPInfo[i].newExtent << std::endl; + if (!datatypes::Decimal::isWideDecimalType(fCPInfo[i].type, fCPInfo[i].colWidth)) + { + fRptFile << "CP: " << fCPInfo[i].startLbid << ' ' << + fCPInfo[i].max << ' ' << + fCPInfo[i].min << ' ' << + fCPInfo[i].seqNum << ' ' << + fCPInfo[i].type << ' ' << + fCPInfo[i].newExtent << std::endl; + } + else + { + std::string bigMin, bigMax; + + dataconvert::DataConvert::decimalToString(&fCPInfo[i].bigMin, 0, buf, utils::MAXLENGTH16BYTES, fCPInfo[i].type); + bigMin = buf; + + dataconvert::DataConvert::decimalToString(&fCPInfo[i].bigMax, 0, buf, utils::MAXLENGTH16BYTES, fCPInfo[i].type); + bigMax = buf; + + fRptFile << "CP: " << fCPInfo[i].startLbid << ' ' << + bigMax << ' ' << + bigMin << ' ' << + fCPInfo[i].seqNum << ' ' << + fCPInfo[i].type << ' ' << + fCPInfo[i].newExtent << std::endl; + } } } } diff --git a/writeengine/bulk/we_bulkloadbuffer.cpp b/writeengine/bulk/we_bulkloadbuffer.cpp index 79d6cf275..18e6bae00 100644 --- a/writeengine/bulk/we_bulkloadbuffer.cpp +++ b/writeengine/bulk/we_bulkloadbuffer.cpp @@ -40,6 +40,7 @@ #include "dataconvert.h" #include "exceptclasses.h" #include "mcs_decimal.h" +#include "widedecimalutils.h" #include "joblisttypes.h" @@ -1735,8 +1736,8 @@ int BulkLoadBuffer::parseCol(ColumnInfo& columnInfo) } else { - dataconvert::DataConvert::int128Max(bufStats.bigMinBufferVal); - dataconvert::DataConvert::int128Min(bufStats.bigMaxBufferVal); + utils::int128Max(bufStats.bigMinBufferVal); + utils::int128Min(bufStats.bigMaxBufferVal); } updateCPInfoPendingFlag = false; } diff --git a/writeengine/bulk/we_bulkloadbuffer.h b/writeengine/bulk/we_bulkloadbuffer.h index 3932f39aa..bbdb2378d 100644 --- a/writeengine/bulk/we_bulkloadbuffer.h +++ b/writeengine/bulk/we_bulkloadbuffer.h @@ -31,6 +31,7 @@ #include "we_columninfo.h" #include "calpontsystemcatalog.h" #include "dataconvert.h" +#include "widedecimalutils.h" namespace WriteEngine { @@ -66,8 +67,8 @@ public: { minBufferVal = MAX_BIGINT; maxBufferVal = MIN_BIGINT; - dataconvert::DataConvert::int128Max(bigMinBufferVal); - dataconvert::DataConvert::int128Min(bigMaxBufferVal); + utils::int128Max(bigMinBufferVal); + utils::int128Min(bigMaxBufferVal); } } }; diff --git a/writeengine/bulk/we_colextinf.cpp b/writeengine/bulk/we_colextinf.cpp index a020c7362..f94433689 100644 --- a/writeengine/bulk/we_colextinf.cpp +++ b/writeengine/bulk/we_colextinf.cpp @@ -27,6 +27,7 @@ #include "we_colextinf.h" #include "dataconvert.h" +#include "widedecimalutils.h" #include #include @@ -93,7 +94,7 @@ void ColExtInf::addOrUpdateEntryTemplate( RID lastInputRow, // MAX_INT and maxVal will be MIN_INT (see getCPInfoForBRM()). __int128 bigMinValInit; - dataconvert::DataConvert::int128Max(bigMinValInit); + utils::int128Max(bigMinValInit); if ((iter->second.fMinVal == LLONG_MIN && width <= 8) || (iter->second.fbigMinVal == bigMinValInit && width > 8)) // init the range { diff --git a/writeengine/bulk/we_colextinf.h b/writeengine/bulk/we_colextinf.h index e7215c5c4..e0e516616 100644 --- a/writeengine/bulk/we_colextinf.h +++ b/writeengine/bulk/we_colextinf.h @@ -41,6 +41,7 @@ #include "brmtypes.h" #include "we_type.h" #include "dataconvert.h" +#include "widedecimalutils.h" namespace WriteEngine { @@ -65,8 +66,8 @@ public: fMaxVal(LLONG_MIN), fNewExtent(true) { - dataconvert::DataConvert::int128Min(fbigMaxVal); - dataconvert::DataConvert::int128Max(fbigMinVal); + utils::int128Min(fbigMaxVal); + utils::int128Max(fbigMinVal); } // Used to create entry for an existing extent we are going to add data to. @@ -76,8 +77,8 @@ public: fMaxVal(LLONG_MIN), fNewExtent(bIsNewExtent) { - dataconvert::DataConvert::int128Min(fbigMaxVal); - dataconvert::DataConvert::int128Max(fbigMinVal); + utils::int128Min(fbigMaxVal); + utils::int128Max(fbigMinVal); } // Used to create entry for a new extent, with LBID not yet allocated diff --git a/writeengine/wrapper/we_colop.cpp b/writeengine/wrapper/we_colop.cpp index a997f0999..7eda7fc7c 100644 --- a/writeengine/wrapper/we_colop.cpp +++ b/writeengine/wrapper/we_colop.cpp @@ -40,6 +40,7 @@ using namespace std; using namespace execplan; #include "dataconvert.h" +#include "widedecimalutils.h" #include "IDBDataFile.h" #include "IDBPolicy.h" @@ -1140,8 +1141,8 @@ int ColumnOp::fillColumn(const TxnID& txnid, Column& column, Column& refCol, voi } else { - dataconvert::DataConvert::int128Min(cpInfo.bigMax); - dataconvert::DataConvert::int128Max(cpInfo.bigMin); + utils::int128Min(cpInfo.bigMax); + utils::int128Max(cpInfo.bigMin); } } @@ -1193,8 +1194,8 @@ int ColumnOp::fillColumn(const TxnID& txnid, Column& column, Column& refCol, voi } else { - dataconvert::DataConvert::int128Min(cpInfo1.bigMax); - dataconvert::DataConvert::int128Max(cpInfo1.bigMin); + utils::int128Min(cpInfo1.bigMax); + utils::int128Max(cpInfo1.bigMin); } } diff --git a/writeengine/wrapper/writeengine.cpp b/writeengine/wrapper/writeengine.cpp index bb7489a48..24407d513 100644 --- a/writeengine/wrapper/writeengine.cpp +++ b/writeengine/wrapper/writeengine.cpp @@ -1170,8 +1170,8 @@ int WriteEngineWrapper::insertColumnRecs(const TxnID& txnid, } else { - dataconvert::DataConvert::int128Min(cpInfo.bigMax); - dataconvert::DataConvert::int128Max(cpInfo.bigMin); + utils::int128Min(cpInfo.bigMax); + utils::int128Max(cpInfo.bigMin); } } @@ -1916,8 +1916,8 @@ int WriteEngineWrapper::insertColumnRecsBinary(const TxnID& txnid, } else { - dataconvert::DataConvert::int128Min(cpInfo.bigMax); - dataconvert::DataConvert::int128Max(cpInfo.bigMin); + utils::int128Min(cpInfo.bigMax); + utils::int128Max(cpInfo.bigMin); } }