diff --git a/dbcon/joblist/jlf_execplantojoblist.cpp b/dbcon/joblist/jlf_execplantojoblist.cpp index 8c86908af..7027e3213 100644 --- a/dbcon/joblist/jlf_execplantojoblist.cpp +++ b/dbcon/joblist/jlf_execplantojoblist.cpp @@ -1602,6 +1602,16 @@ bool optimizeIdbPatitionSimpleFilter(SimpleFilter* sf, JobStepVector& jsv, JobIn } +// WIP MCOL-641 put this in dataconvert +void atoi_(const string &arg, unsigned __int128 &res) +{ + res = 0; + for (size_t j = 0; j < arg.size(); j++) + { + res = res*10 + arg[j] - '0'; + } +} + const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) { JobStepVector jsv; @@ -1842,6 +1852,7 @@ const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) // @bug 1151 string longer than colwidth of char/varchar. int64_t value = 0; uint8_t rf = 0; + unsigned __int128 val128 = 0; #ifdef FAILED_ATOI_IS_ZERO //if cvn throws (because there's non-digit data in the string, treat that as zero rather than @@ -1887,8 +1898,17 @@ const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) } #else - bool isNull = ConstantColumn::NULLDATA == cc->type(); - value = convertValueNum(constval, ct, isNull, rf, jobInfo.timeZone); + // WIP MCOL-641 + if (ct.colDataType == CalpontSystemCatalog::DECIMAL && + ct.colWidth == 16) + { + atoi_(constval, val128); + } + else + { + bool isNull = ConstantColumn::NULLDATA == cc->type(); + value = convertValueNum(constval, ct, isNull, rf, jobInfo.timeZone); + } if (ct.colDataType == CalpontSystemCatalog::FLOAT && !isNull) { @@ -1921,7 +1941,14 @@ const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) pcs = new PseudoColStep(sc->oid(), tbl_oid, pc->pseudoType(), ct, jobInfo); if (sc->isColumnStore()) - pcs->addFilter(cop, value, rf); + { + // WIP MCOL-641 + if (ct.colDataType == CalpontSystemCatalog::DECIMAL && + ct.colWidth == 16) + pcs->addFilter(cop, val128, rf); + else + pcs->addFilter(cop, value, rf); + } pcs->alias(alias); pcs->view(view); diff --git a/dbcon/joblist/pcolstep.cpp b/dbcon/joblist/pcolstep.cpp index c4f09ce4b..296452819 100644 --- a/dbcon/joblist/pcolstep.cpp +++ b/dbcon/joblist/pcolstep.cpp @@ -633,6 +633,18 @@ void pColStep::addFilter(int8_t COP, int64_t value, uint8_t roundFlag) fFilterCount++; } +// WIP MCOL-641 +void pColStep::addFilter(int8_t COP, unsigned __int128 value, uint8_t roundFlag) +{ + fFilterString << (uint8_t) COP; + fFilterString << roundFlag; + + // bitwise copies into the filter ByteStream + fFilterString << value; + + fFilterCount++; +} + void pColStep::setRidList(DataList* dl) { ridList = dl; diff --git a/dbcon/joblist/primitivestep.h b/dbcon/joblist/primitivestep.h index 35ecf86de..d22ac2821 100644 --- a/dbcon/joblist/primitivestep.h +++ b/dbcon/joblist/primitivestep.h @@ -195,6 +195,8 @@ public: */ void addFilter(int8_t COP, int64_t value, uint8_t roundFlag = 0); void addFilter(int8_t COP, float value); + // WIP MCOL-641 + void addFilter(int8_t COP, unsigned __int128 value, uint8_t roundFlag = 0); /** @brief Sets the DataList to get RID values from. * diff --git a/primitives/linux-port/column.cpp b/primitives/linux-port/column.cpp index 5d5885cf4..4f3cea781 100644 --- a/primitives/linux-port/column.cpp +++ b/primitives/linux-port/column.cpp @@ -1535,6 +1535,16 @@ inline void p_Col_ridArray(NewColRequestHeader* in, #endif } + +// WIP MCOL-641 +using uint128_t = unsigned __int128; +using int128_t = __int128; + +struct uint128_pod { + uint64_t lo; + uint64_t hi; +}; + // for BINARY template inline void p_Col_bin_ridArray(NewColRequestHeader* in, @@ -1630,9 +1640,18 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, regex[argIndex].used = false; } } - + // WIP MCOL-641 + // we have a pre-parsed filter, and it's in the form of op and value arrays + else if (parsedColumnFilter->columnFilterMode == TWO_ARRAYS) + { + argVals = (binWtype*) parsedColumnFilter->prestored_argVals.get(); + cops = parsedColumnFilter->prestored_cops.get(); + rfs = parsedColumnFilter->prestored_rfs.get(); + regex = parsedColumnFilter->prestored_regex.get(); + } // else we have a pre-parsed filter, and it's an unordered set for quick == comparisons + bval = (binWtype*)nextBinColValue(in->DataType, ridArray, in->NVALS, &nextRidIndex, &done, &isNull, &isEmpty, &rid, in->OutputType, reinterpret_cast(block), itemsPerBlk); @@ -1681,29 +1700,39 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, // if((*((uint64_t *) (uval))) != 0) cout << "comparing " << dec << (*((uint64_t *) (uval))) << " to " << (*((uint64_t *) (argVals[argIndex]))) << endl; - int val1 = memcmp(*bval, &argVals[argIndex], W); + // WIP MCOL-641 + uint128_t val, filterVal; + uint128_pod *valPod, *filterValPod; + valPod = reinterpret_cast(&val); + filterValPod = reinterpret_cast(&filterVal); + + valPod->lo = *reinterpret_cast(*bval); + valPod->hi = *(reinterpret_cast(*bval) + 1); + + filterValPod->lo = *reinterpret_cast(argVals[argIndex]); + filterValPod->hi = *(reinterpret_cast(argVals[argIndex]) + 1); switch (cops[argIndex]) { case COMPARE_NIL: cmp = false; break; case COMPARE_LT: - cmp = val1 < 0; + cmp = val < filterVal; break; case COMPARE_EQ: - cmp = val1 == 0; + cmp = val == filterVal; break; case COMPARE_LE: - cmp = val1 <= 0; + cmp = val <= filterVal; break; case COMPARE_GT: - cmp = val1 > 0; + cmp = val > filterVal; break; case COMPARE_NE: - cmp = val1 != 0; + cmp = val != filterVal; break; case COMPARE_GE: - cmp = val1 >= 0; + cmp = val >= filterVal; break; default: logIt(34, cops[argIndex], "colCompare"); @@ -1854,7 +1883,11 @@ boost::shared_ptr parseColumnFilter ret.reset(new ParsedColumnFilter()); ret->columnFilterMode = TWO_ARRAYS; - ret->prestored_argVals.reset(new int64_t[filterCount]); + // WIP MCOL-641 + if (colWidth == 16) + ret->prestored_argVals.reset(new int64_t[filterCount * 2]); + else + ret->prestored_argVals.reset(new int64_t[filterCount]); ret->prestored_cops.reset(new uint8_t[filterCount]); ret->prestored_rfs.reset(new uint8_t[filterCount]); ret->prestored_regex.reset(new idb_regex_t[filterCount]); @@ -1949,8 +1982,10 @@ boost::shared_ptr parseColumnFilter case 8: ret->prestored_argVals[argIndex] = *reinterpret_cast(args->val); break; + + // WIP MCOL-641 case 16: - cout << __FILE__<< ":" <<__LINE__ << " Fix for 16 Bytes ?" << endl; + memcpy(ret->prestored_argVals.get() + (argIndex * 2), args->val, 16); } } diff --git a/utils/messageqcpp/bytestream.cpp b/utils/messageqcpp/bytestream.cpp index 6ecbf625d..4cc4a103a 100644 --- a/utils/messageqcpp/bytestream.cpp +++ b/utils/messageqcpp/bytestream.cpp @@ -235,6 +235,18 @@ ByteStream& ByteStream::operator<<(const uint64_t o) return *this; } +// WIP MCOL-641 +ByteStream& ByteStream::operator<<(const unsigned __int128 o) +{ + if (fBuf == 0 || (fCurInPtr - fBuf + 16U > fMaxLen + ISSOverhead)) + growBuf(fMaxLen + BlockSize); + + *((unsigned __int128*) fCurInPtr) = o; + fCurInPtr += 16; + + return *this; +} + ByteStream& ByteStream::operator<<(const string& s) { int32_t len = s.size(); @@ -319,6 +331,14 @@ ByteStream& ByteStream::operator>>(uint64_t& o) return *this; } +// WIP MCOL-641 +ByteStream& ByteStream::operator>>(unsigned __int128& o) +{ + peek(o); + fCurOutPtr += 16; + return *this; +} + ByteStream& ByteStream::operator>>(string& s) { peek(s); @@ -399,6 +419,16 @@ void ByteStream::peek(uint64_t& o) const o = *((uint64_t*) fCurOutPtr); } +// WIP MCOL-641 +void ByteStream::peek(unsigned __int128& o) const +{ + + if (length() < 16) + throw underflow_error("ByteStream>unsigned __int128: not enough data in stream to fill datatype"); + + o = *((unsigned __int128*) fCurOutPtr); +} + void ByteStream::peek(string& s) const { int32_t len; diff --git a/utils/messageqcpp/bytestream.h b/utils/messageqcpp/bytestream.h index 316d9b0a1..16d547fba 100644 --- a/utils/messageqcpp/bytestream.h +++ b/utils/messageqcpp/bytestream.h @@ -143,6 +143,11 @@ public: * push an uint64_t onto the end of the stream. The byte order is whatever the native byte order is. */ EXPORT ByteStream& operator<<(const uint64_t o); + // WIP MCOL-641 + /** + * push an unsigned __int128 onto the end of the stream. The byte order is whatever the native byte order is. + */ + EXPORT ByteStream& operator<<(const unsigned __int128 o); /** * push a float onto the end of the stream. The byte order is * whatever the native byte order is. @@ -207,6 +212,11 @@ public: * extract an uint64_t from the front of the stream. The byte order is whatever the native byte order is. */ EXPORT ByteStream& operator>>(uint64_t& o); + // WIP MCOL-641 + /** + * extract an unsigned __int128 from the front of the stream. The byte order is whatever the native byte order is. + */ + EXPORT ByteStream& operator>>(unsigned __int128& o); /** * extract a float from the front of the stream. The byte * order is whatever the native byte order is. @@ -277,6 +287,11 @@ public: * Peek at an uint64_t from the front of the stream. The byte order is whatever the native byte order is. */ EXPORT void peek(uint64_t& o) const; + // WIP MCOL-641 + /** + * Peek at an unsigned __int128 from the front of the stream. The byte order is whatever the native byte order is. + */ + EXPORT void peek(unsigned __int128& o) const; /** * Peek at a float from the front of the stream. The byte order * is whatever the native byte order is.