From 84f9821720e9e08a81db20c97f7044ef9651c2cf Mon Sep 17 00:00:00 2001 From: drrtuy Date: Tue, 4 Feb 2020 23:02:39 +0300 Subject: [PATCH] MCOL-641 Switched to DataConvert static methods in joblist code. Replaced BINARYEMPTYROW and BINARYNULL values. We need to have separate magic values for numeric and non-numeric binary types b/c numeric cant tolerate losing 0 used for magics previously. atoi128() now parses minus sign and produces negative values. RowAggregation::isNull() now uses Row::isNull() for DECIMAL. --- dbcon/joblist/jlf_execplantojoblist.cpp | 18 +++------- dbcon/joblist/joblisttypes.h | 4 +-- utils/dataconvert/dataconvert.cpp | 46 ++++++++++++++++--------- utils/dataconvert/dataconvert.h | 21 +++++++---- utils/rowgroup/rowaggregation.cpp | 2 +- utils/rowgroup/rowgroup.cpp | 16 ++++----- 6 files changed, 59 insertions(+), 48 deletions(-) diff --git a/dbcon/joblist/jlf_execplantojoblist.cpp b/dbcon/joblist/jlf_execplantojoblist.cpp index 0a226c38d..3460b0491 100644 --- a/dbcon/joblist/jlf_execplantojoblist.cpp +++ b/dbcon/joblist/jlf_execplantojoblist.cpp @@ -1601,18 +1601,6 @@ bool optimizeIdbPatitionSimpleFilter(SimpleFilter* sf, JobStepVector& jsv, JobIn return true; } - -// WIP MCOL-641 put this in dataconvert -void atoi128(const string& arg, unsigned __int128& res) -{ - res = 0; - for (size_t j = 0; j < arg.size(); j++) - { - if (LIKELY(arg[j]-'0' >= 0)) - res = res*10 + arg[j] - '0'; - } -} - const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) { JobStepVector jsv; @@ -1899,11 +1887,13 @@ const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) } #else - // WIP MCOL-641 + // WIP MCOL-641 width check must be a f() not a literal + // make a template from convertValueNum to avoid extra if + // this condition doesn't support UDECIMAL if (ct.colDataType == CalpontSystemCatalog::DECIMAL && ct.colWidth == 16) { - atoi128(constval, val128); + dataconvert::atoi128(constval, val128); } else { diff --git a/dbcon/joblist/joblisttypes.h b/dbcon/joblist/joblisttypes.h index 9ad0e071c..cfd3a72e8 100644 --- a/dbcon/joblist/joblisttypes.h +++ b/dbcon/joblist/joblisttypes.h @@ -83,8 +83,8 @@ const uint16_t NULL_UINT16 = USMALLINTNULL; const uint32_t NULL_UINT32 = UINTNULL; const uint64_t NULL_UINT64 = UBIGINTNULL; -const uint64_t BINARYEMPTYROW = 0; -const uint64_t BINARYNULL = 0; +const uint64_t BINARYEMPTYROW = UBIGINTEMPTYROW; +const uint64_t BINARYNULL = UBIGINTNULL; const std::string CPNULLSTRMARK("_CpNuLl_"); const std::string CPSTRNOTFOUND("_CpNoTf_"); diff --git a/utils/dataconvert/dataconvert.cpp b/utils/dataconvert/dataconvert.cpp index 96146a71a..501a2e59a 100644 --- a/utils/dataconvert/dataconvert.cpp +++ b/utils/dataconvert/dataconvert.cpp @@ -51,6 +51,7 @@ typedef uint32_t ulong; using namespace logging; + namespace { @@ -1162,10 +1163,8 @@ bool stringToTimestampStruct(const string& data, TimeStamp& timeStamp, const str } -// WIP +// WIP MCOL-641 #include -using int128_t = __int128; -using uint128_t = unsigned __int128; struct uint128_pod { @@ -1192,6 +1191,7 @@ void DataConvert::toString(T* dec, char *p, size_t buflen) // WIP How to treat PODs here ? // use typeof // Or a templated structure + // Use uint64* to access parts of uint128 and remove pods uint128_pod *high_pod = reinterpret_cast(&high); uint128_pod *mid_pod = reinterpret_cast(&mid); uint128_pod *low_pod = reinterpret_cast(&low); @@ -1201,7 +1201,7 @@ void DataConvert::toString(T* dec, char *p, size_t buflen) // WIP replace snprintf with streams if (high_pod->lo != 0) { printed_chars = snprintf(p, div_log+1, "%lu", high_pod->lo); - p += printed_chars; + p += printed_chars; printed_chars = snprintf(p, div_log+1, "%019lu", mid_pod->lo); p += printed_chars; } else if (mid_pod->lo != 0) { @@ -1215,32 +1215,42 @@ void DataConvert::toString(T* dec, char *p, size_t buflen) // WIP MCOL-641 // Template this // result must be calloc-ed -//template -//void atoi_(const string &arg, T &res) -void atoi128(const string& arg, int128_t& res) +void atoi128(const std::string& arg, int128_t& res) { - // WIP - //char buf[41]; - //int128_t *res_ptr = reinterpret_cast(result); res = 0; - for (size_t j = 0; j < arg.size(); j++) + size_t idx = (arg[0] == '-') ? 1 : 0; + for (size_t j = idx; j < arg.size(); j++) { // WIP Optimize this if (LIKELY(arg[j]-'0' >= 0)) res = res*10 + arg[j] - '0'; } + // Use bit shift if possible + if (idx) + res *= -1; //toString(res, buf); //std::cerr << "atoi_ " << buf <= 0)) + res = res*10 + arg[j] - '0'; + } +} + // WIP MCOL-641 template void DataConvert::decimalToString(T* valuePtr, uint8_t scale, char* buf, unsigned int buflen, - execplan::CalpontSystemCatalog::ColDataType colDataType) + cscDataType colDataType) { toString(valuePtr, buf, buflen); @@ -1302,19 +1312,23 @@ void DataConvert::decimalToString(T* valuePtr, } // Explicit instantiation template -void DataConvert::decimalToString(int128_t* value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType); +void DataConvert::decimalToString(int128_t* value, uint8_t scale, + char* buf, unsigned int buflen, cscDataType colDataType); template -void DataConvert::decimalToString(uint128_t* value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType); +void DataConvert::decimalToString(uint128_t* value, uint8_t scale, + char* buf, unsigned int buflen, cscDataType colDataType); boost::any DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, - const std::string& dataOrig, bool& pushWarning, const std::string& timeZone, bool nulFlag, bool noRoundup, bool isUpdate) + const std::string& dataOrig, bool& pushWarning, + const std::string& timeZone, bool nulFlag, + bool noRoundup, bool isUpdate) { boost::any value; // WIP std::string data( dataOrig ); pushWarning = false; - CalpontSystemCatalog::ColDataType type = colType.colDataType; + cscDataType type = colType.colDataType; //if ( !data.empty() ) if (!nulFlag) diff --git a/utils/dataconvert/dataconvert.h b/utils/dataconvert/dataconvert.h index 05cc27777..6ec934610 100644 --- a/utils/dataconvert/dataconvert.h +++ b/utils/dataconvert/dataconvert.h @@ -84,6 +84,7 @@ inline uint64_t uint64ToStr(uint64_t n) return htonll(n); } +using cscDataType = execplan::CalpontSystemCatalog::ColDataType; #if defined(_MSC_VER) && defined(xxxDATACONVERT_DLLEXPORT) #define EXPORT __declspec(dllexport) @@ -114,7 +115,6 @@ const int64_t IDB_pow[19] = 1000000000000000000LL }; - const int32_t SECS_PER_MIN = 60; const int32_t MINS_PER_HOUR = 60; const int32_t HOURS_PER_DAY = 24; @@ -134,6 +134,9 @@ const int32_t MIN_TIMESTAMP_VALUE = 0; namespace dataconvert { +using int128_t = __int128; +using uint128_t = unsigned __int128; + enum CalpontDateTimeFormat { CALPONTDATE_ENUM = 1, // date format is: "YYYY-MM-DD" @@ -157,6 +160,9 @@ struct MySQLTime } }; +void atoi128(const std::string& arg, int128_t& res); +void atoi128(const std::string& arg, uint128_t& res); + /** * This function converts the timezone represented as a string * in the format "+HH:MM" or "-HH:MM" to a signed offset in seconds @@ -1009,10 +1015,10 @@ public: EXPORT static bool isColumnTimeStampValid( int64_t timeStamp ); EXPORT static bool isNullData(execplan::ColumnResult* cr, int rownum, execplan::CalpontSystemCatalog::ColType colType); - static inline std::string decimalToString(int64_t value, uint8_t scale, execplan::CalpontSystemCatalog::ColDataType colDataType); - static inline void decimalToString(int64_t value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType); + static inline std::string decimalToString(int64_t value, uint8_t scale, cscDataType colDataType); + static inline void decimalToString(int64_t value, uint8_t scale, char* buf, unsigned int buflen, cscDataType colDataType); template - EXPORT static void decimalToString(T* value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType); + EXPORT static void decimalToString(T* value, uint8_t scale, char* buf, unsigned int buflen, cscDataType colDataType); template EXPORT static void toString(T* dec, char *p, size_t buflen); @@ -1226,15 +1232,16 @@ inline void DataConvert::timeToString1( long long timevalue, char* buf, unsigned #endif } -inline std::string DataConvert::decimalToString(int64_t value, uint8_t scale, execplan::CalpontSystemCatalog::ColDataType colDataType) +inline std::string DataConvert::decimalToString(int64_t value, uint8_t scale, cscDataType colDataType) { + // This is too much char buf[80]; DataConvert::decimalToString(value, scale, buf, 80, colDataType); return std::string(buf); } -inline void DataConvert::decimalToString(int64_t int_val, uint8_t scale, char* buf, unsigned int buflen, - execplan::CalpontSystemCatalog::ColDataType colDataType) +inline void DataConvert::decimalToString(int64_t int_val, uint8_t scale, + char* buf, unsigned int buflen, cscDataType colDataType) { // Need to convert a string with a binary unsigned number in it to a 64-bit signed int diff --git a/utils/rowgroup/rowaggregation.cpp b/utils/rowgroup/rowaggregation.cpp index 7d62c4a78..0176e87b5 100755 --- a/utils/rowgroup/rowaggregation.cpp +++ b/utils/rowgroup/rowaggregation.cpp @@ -542,7 +542,7 @@ inline bool RowAggregation::isNull(const RowGroup* pRowGroup, const Row& row, in case execplan::CalpontSystemCatalog::DECIMAL: case execplan::CalpontSystemCatalog::UDECIMAL: { - row.isNullValue(col); + ret = row.isNullValue(col); break; } diff --git a/utils/rowgroup/rowgroup.cpp b/utils/rowgroup/rowgroup.cpp index ec229d8b5..e3be508ab 100644 --- a/utils/rowgroup/rowgroup.cpp +++ b/utils/rowgroup/rowgroup.cpp @@ -846,12 +846,12 @@ void Row::initToNull() break; case 16 : - // WIP MCOL-641 + { uint64_t *dec = reinterpret_cast(&data[offsets[i]]); -+ dec[0] = joblist::BINARYNULL; -+ dec[1] = joblist::BINARYNULL; + dec[0] = joblist::BINARYNULL; + dec[1] = joblist::BINARYNULL; break; - + } default: *((int64_t*) &data[offsets[i]]) = static_cast(joblist::BIGINTNULL); break; @@ -1045,15 +1045,15 @@ bool Row::isNullValue(uint32_t colIndex) const case CalpontSystemCatalog::UDECIMAL: { uint32_t len = getColumnWidth(colIndex); - const uint64_t *dec; + const int64_t *dec; switch (len) { // MCOL-641 case 16: - dec = reinterpret_cast(&data[offsets[colIndex]]); - return ((dec[0] == joblist::BINARYNULL) - && (dec[1] == joblist::BINARYNULL)); + dec = reinterpret_cast(&data[offsets[colIndex]]); + return ((dec[0] == static_cast(joblist::BINARYNULL)) + && (dec[1] == static_cast(joblist::BINARYNULL))); case 1 : return (data[offsets[colIndex]] == joblist::TINYINTNULL);