You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
MCOL-641 Replaced NULL binary constants.
DataConvert::decimalToString, toString, writeIntPart, writeFractionalPart are not templates anymore.
This commit is contained in:
@ -83,8 +83,11 @@ const uint16_t NULL_UINT16 = USMALLINTNULL;
|
||||
const uint32_t NULL_UINT32 = UINTNULL;
|
||||
const uint64_t NULL_UINT64 = UBIGINTNULL;
|
||||
|
||||
const uint64_t BINARYEMPTYROW = UBIGINTEMPTYROW;
|
||||
const uint64_t BINARYNULL = UBIGINTNULL;
|
||||
const uint64_t BINARYNULLVALUELOW = 0ULL;
|
||||
const uint64_t BINARYNULLVALUEHIGH = 0x8000000000000000ULL;
|
||||
const uint64_t BINARYEMPTYVALUELOW = 1ULL;
|
||||
const uint64_t BINARYEMPTYVALUEHIGH = 0x8000000000000000ULL;
|
||||
const uint64_t BINARYEMPTYROW = 0ULL;
|
||||
|
||||
const std::string CPNULLSTRMARK("_CpNuLl_");
|
||||
const std::string CPSTRNOTFOUND("_CpNoTf_");
|
||||
|
@ -805,36 +805,21 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h
|
||||
case CalpontSystemCatalog::DECIMAL:
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
// WIP MCOL-641
|
||||
if (row.getPrecision(s) > 18)
|
||||
if (colType.colWidth == 16)
|
||||
{
|
||||
// unset null bit first
|
||||
// Might be redundant
|
||||
if ((*f)->null_ptr)
|
||||
*(*f)->null_ptr &= ~(*f)->null_bit;
|
||||
|
||||
uint128_t* udec;
|
||||
int128_t* dec;
|
||||
// We won't have more than 38 digits + sign + dp
|
||||
// Make this precision based
|
||||
char buf[41];
|
||||
// We won't have more than [+-][0][.] + up to 38 digits
|
||||
char buf[utils::MAXLENGTH16BYTES];
|
||||
|
||||
// This C-style cast doesn't look appropriate.
|
||||
// Is there a way to use decltype instead of if?
|
||||
if (colType.colDataType == CalpontSystemCatalog::DECIMAL)
|
||||
{
|
||||
dec = row.getBinaryField<int128_t>(s);
|
||||
dataconvert::DataConvert::decimalToString(dec,
|
||||
(unsigned)colType.scale, buf,
|
||||
sizeof(buf), colType.colDataType);
|
||||
}
|
||||
else
|
||||
{
|
||||
udec = row.getBinaryField<uint128_t>(s);
|
||||
dataconvert::DataConvert::decimalToString(udec,
|
||||
(unsigned)colType.scale, buf,
|
||||
sizeof(buf), colType.colDataType);
|
||||
}
|
||||
|
||||
Field_new_decimal* f2 = (Field_new_decimal*)*f;
|
||||
f2->store(buf, strlen(buf), f2->charset());
|
||||
|
@ -40,6 +40,7 @@ using namespace boost;
|
||||
#include "stats.h"
|
||||
#include "primproc.h"
|
||||
#include "dataconvert.h"
|
||||
#include "widedecimalutils.h"
|
||||
using namespace logging;
|
||||
using namespace dbbc;
|
||||
using namespace primitives;
|
||||
@ -277,16 +278,17 @@ template<>
|
||||
inline bool isEmptyVal<32>(uint8_t type, const uint8_t* ival) // For BINARY
|
||||
{
|
||||
const uint64_t* val = reinterpret_cast<const uint64_t*>(ival);
|
||||
return ((val[0] == joblist::BINARYEMPTYROW) && (val[1] == joblist::BINARYEMPTYROW)
|
||||
&& (val[2] == joblist::BINARYEMPTYROW) && (val[3] == joblist::BINARYEMPTYROW));
|
||||
return ((val[0] == joblist::BINARYEMPTYVALUELOW)
|
||||
&& (val[1] == joblist::BINARYNULLVALUELOW)
|
||||
&& (val[2] == joblist::BINARYNULLVALUELOW)
|
||||
&& (val[3] == joblist::BINARYEMPTYVALUEHIGH));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool isEmptyVal<16>(uint8_t type, const uint8_t* ival) // For BINARY
|
||||
{
|
||||
const uint64_t* val = reinterpret_cast<const uint64_t*>(ival);
|
||||
return ((val[0] == joblist::BINARYEMPTYROW) && (val[1] == joblist::BINARYEMPTYROW));
|
||||
|
||||
const int128_t* val = reinterpret_cast<const int128_t*>(ival);
|
||||
return utils::isWideDecimalEmptyValue (*val);
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -410,19 +412,22 @@ inline bool isEmptyVal<1>(uint8_t type, const uint8_t* ival)
|
||||
template<int>
|
||||
inline bool isNullVal(uint8_t type, const uint8_t* val8);
|
||||
|
||||
// WIP This method only works for wide DECIMAL so far.
|
||||
template<>
|
||||
inline bool isNullVal<16>(uint8_t type, const uint8_t* ival) // For BINARY
|
||||
{
|
||||
const uint64_t* val = reinterpret_cast<const uint64_t*>(ival);
|
||||
return ((val[0] == joblist::BINARYNULL) && (val[1] == joblist::BINARYEMPTYROW));
|
||||
const int128_t* val = reinterpret_cast<const int128_t*>(ival);
|
||||
return utils::isWideDecimalNullValue (*val);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool isNullVal<32>(uint8_t type, const uint8_t* ival) // For BINARY
|
||||
{
|
||||
const uint64_t* val = reinterpret_cast<const uint64_t*>(ival);
|
||||
return ((val[0] == joblist::BINARYNULL) && (val[1] == joblist::BINARYEMPTYROW)
|
||||
&& (val[2] == joblist::BINARYEMPTYROW) && (val[3] == joblist::BINARYEMPTYROW));
|
||||
return ((val[0] == joblist::BINARYNULLVALUELOW)
|
||||
&& (val[1] == joblist::BINARYNULLVALUELOW)
|
||||
&& (val[2] == joblist::BINARYNULLVALUELOW)
|
||||
&& (val[3] == joblist::BINARYNULLVALUEHIGH));
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -40,6 +40,7 @@ using namespace std;
|
||||
#include "primitiveserver.h"
|
||||
#include "primproc.h"
|
||||
#include "stats.h"
|
||||
#include "widedecimalutils.h"
|
||||
|
||||
using namespace messageqcpp;
|
||||
using namespace rowgroup;
|
||||
@ -1062,9 +1063,8 @@ const uint64_t ColumnCommand::getEmptyRowValue( const CSCDataType dataType, cons
|
||||
void ColumnCommand::getEmptyRowValue(const CSCDataType dataType,
|
||||
const int width, messageqcpp::ByteStream::hexbyte* space) const
|
||||
{
|
||||
uint64_t *ptr = reinterpret_cast<uint64_t*>(space);
|
||||
ptr[0] = joblist::BINARYEMPTYROW;
|
||||
ptr[1] = joblist::BINARYEMPTYROW;
|
||||
int128_t *val = reinterpret_cast<int128_t*>(space);
|
||||
utils::setWideDecimalEMptyValue(*val);
|
||||
}
|
||||
|
||||
void ColumnCommand::getLBIDList(uint32_t loopCount, vector<int64_t>* lbids)
|
||||
|
@ -18,11 +18,12 @@
|
||||
#ifndef UTILS_COLWIDTH_H
|
||||
#define UTILS_COLWIDTH_H
|
||||
|
||||
#define MAXLEGACYWIDTH 8
|
||||
#define MAXCOLUMNWIDTH 16
|
||||
|
||||
namespace utils
|
||||
{
|
||||
const uint8_t MAXLEGACYWIDTH = 8ULL;
|
||||
const uint8_t MAXCOLUMNWIDTH = 16ULL;
|
||||
|
||||
inline bool isWide(uint8_t width)
|
||||
{
|
||||
return width > MAXLEGACYWIDTH;
|
||||
|
@ -127,7 +127,7 @@ uint64_t getNullValue(CalpontSystemCatalog::ColDataType t, uint32_t colWidth)
|
||||
return joblist::UBIGINTNULL;
|
||||
|
||||
case CalpontSystemCatalog::BINARY:
|
||||
return joblist::BINARYNULL;
|
||||
return joblist::BINARYNULLVALUELOW;
|
||||
|
||||
case CalpontSystemCatalog::VARBINARY:
|
||||
default:
|
||||
@ -201,7 +201,6 @@ int64_t getSignedNullValue(CalpontSystemCatalog::ColDataType t, uint32_t colWidt
|
||||
default:
|
||||
throw logic_error("getSignedNullValue() Can't return the NULL string");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -219,8 +218,14 @@ int64_t getSignedNullValue(CalpontSystemCatalog::ColDataType t, uint32_t colWidt
|
||||
case 4 :
|
||||
return (int64_t) ((int32_t) joblist::INTNULL);
|
||||
|
||||
default:
|
||||
case 8:
|
||||
return joblist::BIGINTNULL;
|
||||
|
||||
default:
|
||||
ostringstream os;
|
||||
os << "getSignedNullValue(): got bad column width (" << t <<
|
||||
"). Width=" << colWidth << endl;
|
||||
throw logic_error(os.str());
|
||||
}
|
||||
|
||||
break;
|
||||
@ -243,7 +248,7 @@ int64_t getSignedNullValue(CalpontSystemCatalog::ColDataType t, uint32_t colWidt
|
||||
return (int64_t)joblist::LONGDOUBLENULL;
|
||||
|
||||
case CalpontSystemCatalog::BINARY:
|
||||
return (int64_t)joblist::BINARYNULL;
|
||||
return (int64_t)joblist::BINARYNULLVALUELOW;
|
||||
|
||||
case CalpontSystemCatalog::VARBINARY:
|
||||
default:
|
||||
|
@ -18,29 +18,57 @@
|
||||
#ifndef WIDE_DECIMAL_UTILS_H
|
||||
#define WIDE_DECIMAL_UTILS_H
|
||||
|
||||
namespace utils
|
||||
{
|
||||
|
||||
using int128_t = __int128;
|
||||
using uint128_t = unsigned __int128;
|
||||
|
||||
namespace utils
|
||||
{
|
||||
const uint64_t BINARYNULLVALUELOW = 0ULL;
|
||||
const uint64_t BINARYNULLVALUEHIGH = 0x8000000000000000ULL;
|
||||
const uint64_t BINARYEMPTYVALUELOW = 1ULL;
|
||||
const uint64_t BINARYEMPTYVALUEHIGH = 0x8000000000000000ULL;
|
||||
const uint8_t MAXLENGTH16BYTES = 42;
|
||||
|
||||
inline bool isWideDecimalNullValue(const int128_t val)
|
||||
inline bool isWideDecimalNullValue(const int128_t& val)
|
||||
{
|
||||
const uint64_t* ptr = reinterpret_cast<const uint64_t*>(&val);
|
||||
return (ptr[0] == BINARYNULLVALUELOW && ptr[1] == BINARYNULLVALUEHIGH);
|
||||
}
|
||||
|
||||
inline bool isWideDecimalEmptyValue(const int128_t val)
|
||||
inline bool isWideDecimalEmptyValue(const int128_t& val)
|
||||
{
|
||||
const uint64_t* ptr = reinterpret_cast<const uint64_t*>(&val);
|
||||
return (ptr[0] == BINARYEMPTYVALUELOW && ptr[1] == BINARYEMPTYVALUEHIGH);
|
||||
}
|
||||
|
||||
inline void setWideDecimalNullValue(int128_t& val)
|
||||
{
|
||||
uint64_t* ptr = reinterpret_cast<uint64_t*>(&val);
|
||||
ptr[0] = BINARYNULLVALUELOW;
|
||||
ptr[1] = BINARYNULLVALUEHIGH;
|
||||
}
|
||||
|
||||
inline void setWideDecimalEMptyValue(int128_t& val)
|
||||
{
|
||||
uint64_t* ptr = reinterpret_cast<uint64_t*>(&val);
|
||||
ptr[0] = BINARYEMPTYVALUELOW;
|
||||
ptr[1] = BINARYEMPTYVALUEHIGH;
|
||||
}
|
||||
|
||||
inline void setWideDecimalNullValue(int128_t* val)
|
||||
{
|
||||
uint64_t* ptr = reinterpret_cast<uint64_t*>(val);
|
||||
ptr[0] = BINARYNULLVALUELOW;
|
||||
ptr[1] = BINARYNULLVALUEHIGH;
|
||||
}
|
||||
|
||||
inline void setWideDecimalEMptyValue(int128_t* val)
|
||||
{
|
||||
uint64_t* ptr = reinterpret_cast<uint64_t*>(val);
|
||||
ptr[0] = BINARYEMPTYVALUELOW;
|
||||
ptr[1] = BINARYEMPTYVALUEHIGH;
|
||||
}
|
||||
|
||||
inline void int128Max(int128_t& val)
|
||||
{
|
||||
uint64_t* ptr = reinterpret_cast<uint64_t*>(&val);
|
||||
@ -61,7 +89,6 @@ const uint64_t BINARYEMPTYVALUEHIGH = 0x8000000000000000ULL;
|
||||
ptr[0] = 0xFFFFFFFFFFFFFFFF;
|
||||
ptr[1] = 0xFFFFFFFFFFFFFFFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // WIDE_DECIMAL_UTILS_H
|
||||
|
@ -102,6 +102,29 @@ const string columnstore_big_precision[20] =
|
||||
"99999999999999999999999999999999999999"
|
||||
};
|
||||
|
||||
const uint64_t columnstore_pow_10[20] =
|
||||
{
|
||||
1ULL,
|
||||
10ULL,
|
||||
100ULL,
|
||||
1000ULL,
|
||||
10000ULL,
|
||||
100000ULL,
|
||||
1000000ULL,
|
||||
10000000ULL,
|
||||
100000000ULL,
|
||||
1000000000ULL,
|
||||
10000000000ULL,
|
||||
100000000000ULL,
|
||||
1000000000000ULL,
|
||||
10000000000000ULL,
|
||||
100000000000000ULL,
|
||||
1000000000000000ULL,
|
||||
10000000000000000ULL,
|
||||
100000000000000000ULL,
|
||||
1000000000000000000ULL,
|
||||
10000000000000000000ULL
|
||||
};
|
||||
template <class T>
|
||||
bool from_string(T& t, const std::string& s, std::ios_base & (*f)(std::ios_base&))
|
||||
{
|
||||
@ -1226,32 +1249,37 @@ bool stringToTimestampStruct(const string& data, TimeStamp& timeStamp, const str
|
||||
|
||||
}
|
||||
|
||||
// WIP MCOL-641
|
||||
template <typename T>
|
||||
size_t DataConvert::writeIntPart(T* dec, char* p,
|
||||
size_t DataConvert::writeIntPart(int128_t* dec, char* p,
|
||||
const uint16_t buflen,
|
||||
const uint8_t scale) //don't need this
|
||||
const uint8_t scale)
|
||||
{
|
||||
T intPart = *dec;
|
||||
int128_t intPart = *dec;
|
||||
if (scale)
|
||||
{
|
||||
//TODO Use dictionary to produce divisor
|
||||
// instead of a loop
|
||||
for (size_t i = 0; i < scale; i++)
|
||||
intPart /= 10;
|
||||
uint8_t maxPowOf10 = sizeof(columnstore_pow_10)/sizeof(columnstore_pow_10[0])-1;
|
||||
switch (scale/maxPowOf10)
|
||||
{
|
||||
case(2):
|
||||
intPart /= columnstore_pow_10[maxPowOf10];
|
||||
intPart /= columnstore_pow_10[maxPowOf10];
|
||||
break;
|
||||
case(1):
|
||||
intPart /= columnstore_pow_10[maxPowOf10];
|
||||
case(0):
|
||||
intPart /= columnstore_pow_10[scale%maxPowOf10];
|
||||
}
|
||||
}
|
||||
|
||||
// optimize for less then uint64_t values
|
||||
uint64_t div = 10000000000000000000ULL;
|
||||
T high = intPart;
|
||||
T low;
|
||||
int128_t high = intPart;
|
||||
int128_t low;
|
||||
low = high % div;
|
||||
high /= div;
|
||||
T mid;
|
||||
int128_t mid;
|
||||
mid = high % div;
|
||||
high /= div;
|
||||
|
||||
// pod[0] is high 8 byte, pod[1] is low
|
||||
// pod[0] is low 8 byte, pod[1] is high
|
||||
uint64_t* high_pod = reinterpret_cast<uint64_t*>(&high);
|
||||
uint64_t* mid_pod = reinterpret_cast<uint64_t*>(&mid);
|
||||
uint64_t* low_pod = reinterpret_cast<uint64_t*>(&low);
|
||||
@ -1287,17 +1315,29 @@ size_t DataConvert::writeIntPart(T* dec, char* p,
|
||||
return p-original_p;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
size_t DataConvert::writeFractionalPart(T* dec, char* p,
|
||||
size_t DataConvert::writeFractionalPart(int128_t* dec, char* p,
|
||||
const uint16_t buflen,
|
||||
const uint8_t scale)
|
||||
{
|
||||
//TODO Use dictionary instead of multiplication.
|
||||
T scaleDivisor = 10;
|
||||
for (size_t i = 1; i < scale; i++)
|
||||
scaleDivisor *= 10;
|
||||
int128_t scaleDivisor = 1;
|
||||
|
||||
T fractionalPart = *dec % scaleDivisor;
|
||||
uint8_t maxPowOf10 = sizeof(columnstore_pow_10)/sizeof(columnstore_pow_10[0])-1;
|
||||
switch (scale/maxPowOf10)
|
||||
{
|
||||
case(2):
|
||||
scaleDivisor *= columnstore_pow_10[maxPowOf10];
|
||||
scaleDivisor *= columnstore_pow_10[maxPowOf10];
|
||||
break;
|
||||
case(1):
|
||||
scaleDivisor *= columnstore_pow_10[maxPowOf10];
|
||||
case(0):
|
||||
scaleDivisor *= columnstore_pow_10[scale%maxPowOf10];
|
||||
}
|
||||
|
||||
//for (size_t i = 1; i < scale; i++)
|
||||
// scaleDivisor *= 10;
|
||||
|
||||
int128_t fractionalPart = *dec % scaleDivisor;
|
||||
// divide by the base untill we have non-zero quotinent
|
||||
size_t written = 0;
|
||||
scaleDivisor /= 10;
|
||||
@ -1319,38 +1359,24 @@ size_t DataConvert::writeFractionalPart(T* dec, char* p,
|
||||
return scale;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void DataConvert::toString(T* dec, uint8_t scale,
|
||||
void DataConvert::toString(int128_t* dec, uint8_t scale,
|
||||
char *p, unsigned int buflen)
|
||||
{
|
||||
char* original_p = p;
|
||||
size_t written = 0;
|
||||
// Early return for NULL value
|
||||
int128_t sign = 0;
|
||||
// WIP use constants here
|
||||
// WIP Treat both magics here
|
||||
uint64_t* signPod = reinterpret_cast<uint64_t*>(&sign);
|
||||
signPod[1] = utils::BINARYNULLVALUEHIGH;
|
||||
|
||||
if (*dec == sign)
|
||||
// Raise exception on NULL and EMPTY value
|
||||
if (utils::isWideDecimalNullValue(*dec) || utils::isWideDecimalEmptyValue(*dec))
|
||||
{
|
||||
*p++ = '0';
|
||||
if (scale)
|
||||
{
|
||||
*p++ = '.';
|
||||
while (scale-- > 0)
|
||||
*p++ = '0';
|
||||
}
|
||||
return;
|
||||
throw QueryDataExcept("toString() char buffer overflow.", formatErr);
|
||||
}
|
||||
|
||||
if (*dec < static_cast<T>(0))
|
||||
if (*dec < static_cast<int128_t>(0))
|
||||
{
|
||||
*p++ = '-';
|
||||
*dec *= -1;
|
||||
}
|
||||
|
||||
written = writeIntPart<T>(dec, p, buflen, scale);
|
||||
written = writeIntPart(dec, p, buflen, scale);
|
||||
p += written;
|
||||
|
||||
if (scale)
|
||||
@ -1365,10 +1391,6 @@ void DataConvert::toString(T* dec, uint8_t scale,
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
void DataConvert::toString<int128_t>(int128_t* dec, uint8_t scale,
|
||||
char *p, unsigned int buflen);
|
||||
|
||||
// WIP MCOL-641
|
||||
void atoi128(const std::string& arg, int128_t& res)
|
||||
{
|
||||
@ -1397,25 +1419,14 @@ void atoi128(const std::string& arg, uint128_t& res)
|
||||
}
|
||||
}
|
||||
|
||||
// WIP MCOL-641
|
||||
// Doesn't work for -0.042
|
||||
template <typename T>
|
||||
void DataConvert::decimalToString(T* valuePtr,
|
||||
void DataConvert::decimalToString(int128_t* valuePtr,
|
||||
uint8_t scale,
|
||||
char* buf,
|
||||
unsigned int buflen,
|
||||
cscDataType colDataType) // We don't need the last one
|
||||
{
|
||||
|
||||
toString<T>(valuePtr, scale, buf, buflen);
|
||||
toString(valuePtr, scale, buf, buflen);
|
||||
}
|
||||
// Explicit instantiation
|
||||
template
|
||||
void DataConvert::decimalToString<int128_t>(int128_t* value, uint8_t scale,
|
||||
char* buf, unsigned int buflen, cscDataType colDataType);
|
||||
template
|
||||
void DataConvert::decimalToString<uint128_t>(uint128_t* value, uint8_t scale,
|
||||
char* buf, unsigned int buflen, cscDataType colDataType);
|
||||
|
||||
boost::any
|
||||
DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType,
|
||||
|
@ -1041,17 +1041,13 @@ public:
|
||||
EXPORT static bool isNullData(execplan::ColumnResult* cr, int rownum, execplan::CalpontSystemCatalog::ColType colType);
|
||||
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 <typename T>
|
||||
EXPORT static void decimalToString(T* value, uint8_t scale, char* buf, unsigned int buflen, cscDataType colDataType);
|
||||
static void decimalToString(int128_t* value, uint8_t scale, char* buf, unsigned int buflen, cscDataType colDataType);
|
||||
|
||||
template <typename T>
|
||||
static void toString(T* dec, uint8_t scale, char* p, unsigned int buflen);
|
||||
template <typename T>
|
||||
static size_t writeIntPart(T* dec, char* p, const uint16_t buflen,
|
||||
static void toString(int128_t* dec, uint8_t scale, char* p, unsigned int buflen);
|
||||
static size_t writeIntPart(int128_t* dec, char* p, const uint16_t buflen,
|
||||
const uint8_t scale);
|
||||
static size_t writeFractionalPart(int128_t* dec, char* p, const uint16_t buflen,
|
||||
const uint8_t scale);
|
||||
template <typename T>
|
||||
static size_t writeFractionalPart(T* dec, char* p,
|
||||
const uint16_t buflen, const uint8_t scale);
|
||||
|
||||
static inline void int128Max(int128_t& i)
|
||||
{
|
||||
|
@ -477,11 +477,11 @@ void FuncExp::evaluate(rowgroup::Row& row, std::vector<execplan::SRCP>& expressi
|
||||
{
|
||||
// WIP make this a separate function w and w/o overflow check
|
||||
if (expression[i]->resultType().colDataType == execplan::CalpontSystemCatalog::DECIMAL)
|
||||
row.setBinaryField_offset(reinterpret_cast<uint8_t*>(&val.__v.__s128),
|
||||
row.setBinaryField_offset(&val.__v.__s128,
|
||||
expression[i]->resultType().colWidth,
|
||||
row.getOffset(expression[i]->outputIndex()));
|
||||
else
|
||||
row.setBinaryField_offset(reinterpret_cast<uint8_t*>(&val.__v.__u128),
|
||||
row.setBinaryField_offset(&val.__v.__u128,
|
||||
expression[i]->resultType().colWidth,
|
||||
row.getOffset(expression[i]->outputIndex()));
|
||||
}
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "vlarray.h"
|
||||
|
||||
#include "collation.h"
|
||||
#include "widedecimalutils.h"
|
||||
|
||||
//..comment out NDEBUG to enable assertions, uncomment NDEBUG to disable
|
||||
//#define NDEBUG
|
||||
@ -222,19 +223,8 @@ inline string getStringNullValue()
|
||||
return joblist::CPNULLSTRMARK;
|
||||
}
|
||||
|
||||
inline uint64_t getBinaryNullValue()
|
||||
{
|
||||
return joblist::BINARYNULL;
|
||||
}
|
||||
|
||||
inline uint64_t getBinaryEmptyValue()
|
||||
{
|
||||
return joblist::BINARYEMPTYROW;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace rowgroup
|
||||
{
|
||||
const std::string typeStr("");
|
||||
@ -1176,14 +1166,11 @@ void RowAggregation::makeAggFieldsNull(Row& row)
|
||||
}
|
||||
else
|
||||
{
|
||||
// WIP This is only 1st part of the value
|
||||
uint64_t nullValue = getBinaryNullValue();
|
||||
uint64_t emptyValue = getBinaryEmptyValue();
|
||||
int128_t nullValue = 0;
|
||||
utils::setWideDecimalNullValue(nullValue);
|
||||
uint32_t offset = row.getOffset(colOut);
|
||||
row.setBinaryField_offset(&nullValue, sizeof(nullValue),
|
||||
offset);
|
||||
row.setBinaryField_offset(&emptyValue, sizeof(nullValue),
|
||||
offset+sizeof(nullValue));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -91,15 +91,9 @@ class RowDecimalTest : public ::testing::Test {
|
||||
int128_t nullValue = 0;
|
||||
int128_t bigValue = 0;
|
||||
uint64_t* uint128_pod = reinterpret_cast<uint64_t*>(&nullValue);
|
||||
uint128_pod[0] = joblist::BINARYNULL;
|
||||
uint128_pod[1] = joblist::BINARYEMPTYROW;
|
||||
uint128_pod[0] = joblist::UBIGINTNULL;
|
||||
uint128_pod[1] = joblist::UBIGINTEMPTYROW;
|
||||
bigValue = -static_cast<int128_t>(0xFFFFFFFF)*0xFFFFFFFFFFFFFFFF;
|
||||
//char buf[utils::precisionByWidth(16)+3];
|
||||
//memset(&buf[0], 0, sizeof(buf));
|
||||
//int scale1 = 3;
|
||||
//dataconvert::DataConvert::decimalToString(&bigValue, scale1, buf,
|
||||
// utils::precisionByWidth(sizeof(bigValue))+3,types[0]);
|
||||
//std::cout << buf << std::endl;
|
||||
sValueVector.push_back(nullValue);
|
||||
sValueVector.push_back(-42);
|
||||
sValueVector.push_back(bigValue);
|
||||
@ -136,8 +130,6 @@ class RowDecimalTest : public ::testing::Test {
|
||||
s64ValueVector.push_back(0x81);
|
||||
s64ValueVector.push_back(joblist::BIGINTNULL-1);
|
||||
|
||||
//r.initToNull();
|
||||
//r.nextRow(rowSize);
|
||||
for(size_t i = 0; i < sValueVector.size(); i++) {
|
||||
r.setBinaryField_offset(&sValueVector[i],
|
||||
sizeof(sValueVector[0]), offsets[0]);
|
||||
|
@ -44,6 +44,7 @@ using namespace execplan;
|
||||
#include "rowgroup.h"
|
||||
#include "dataconvert.h"
|
||||
#include "columnwidth.h"
|
||||
#include "widedecimalutils.h"
|
||||
|
||||
#include "collation.h"
|
||||
|
||||
@ -850,9 +851,7 @@ void Row::initToNull()
|
||||
|
||||
case 16 :
|
||||
{
|
||||
uint64_t *dec = reinterpret_cast<uint64_t*>(&data[offsets[i]]);
|
||||
dec[0] = joblist::BINARYNULL;
|
||||
dec[1] = joblist::BINARYEMPTYROW;
|
||||
utils::setWideDecimalNullValue(reinterpret_cast<int128_t&>(data[offsets[i]]));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -881,9 +880,7 @@ void Row::initToNull()
|
||||
break;
|
||||
case CalpontSystemCatalog::BINARY:
|
||||
{
|
||||
uint64_t *dec = reinterpret_cast<uint64_t*>(&data[offsets[i]]);
|
||||
dec[0] = joblist::BINARYNULL;
|
||||
dec[1] = joblist::BINARYEMPTYROW;
|
||||
utils::setWideDecimalNullValue(reinterpret_cast<int128_t&>(data[offsets[i]]));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -915,11 +912,11 @@ inline bool
|
||||
Row::isNullValue_offset<execplan::CalpontSystemCatalog::BINARY,32>(
|
||||
uint32_t offset) const
|
||||
{
|
||||
const int64_t *intPtr = reinterpret_cast<const int64_t*>(&data[offset]);
|
||||
return ((intPtr[0] == static_cast<int64_t>(joblist::BINARYNULL)) &&
|
||||
(intPtr[1] == static_cast<int64_t>(joblist::BINARYEMPTYROW)) &&
|
||||
(intPtr[2] == static_cast<int64_t>(joblist::BINARYEMPTYROW)) &&
|
||||
(intPtr[3] == static_cast<int64_t>(joblist::BINARYEMPTYROW)));
|
||||
const uint64_t *intPtr = reinterpret_cast<const uint64_t*>(&data[offset]);
|
||||
return ((intPtr[0] == static_cast<uint64_t>(utils::BINARYNULLVALUELOW)) &&
|
||||
(intPtr[1] == static_cast<uint64_t>(utils::BINARYNULLVALUELOW)) &&
|
||||
(intPtr[2] == static_cast<uint64_t>(utils::BINARYNULLVALUELOW)) &&
|
||||
(intPtr[3] == static_cast<uint64_t>(utils::BINARYEMPTYVALUEHIGH)));
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -927,9 +924,8 @@ inline bool
|
||||
Row::isNullValue_offset<execplan::CalpontSystemCatalog::BINARY,16>(
|
||||
uint32_t offset) const
|
||||
{
|
||||
const int64_t *intPtr = reinterpret_cast<const int64_t*>(&data[offset]);
|
||||
return ((intPtr[0] == static_cast<int64_t>(joblist::BINARYNULL))
|
||||
&& (intPtr[1] == static_cast<int64_t>(joblist::BINARYEMPTYROW)));
|
||||
const int128_t *intPtr = reinterpret_cast<const int128_t*>(&data[offset]);
|
||||
return utils::isWideDecimalNullValue (*intPtr);
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -937,9 +933,8 @@ inline bool
|
||||
Row::isNullValue_offset<execplan::CalpontSystemCatalog::DECIMAL,16>(
|
||||
uint32_t offset) const
|
||||
{
|
||||
const int64_t *intPtr = reinterpret_cast<const int64_t*>(&data[offset]);
|
||||
return ((intPtr[0] == static_cast<int64_t>(joblist::BINARYNULL))
|
||||
&& (intPtr[1] == static_cast<int64_t>(joblist::BINARYEMPTYROW)));
|
||||
const int128_t *intPtr = reinterpret_cast<const int128_t*>(&data[offset]);
|
||||
return utils::isWideDecimalNullValue (*intPtr);
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -1059,8 +1054,7 @@ bool Row::isNullValue(uint32_t colIndex) const
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
// WIP MCOL-641 Allmighty hack.
|
||||
int32_t width = getColumnWidth(colIndex);
|
||||
switch (width)
|
||||
switch (getColumnWidth(colIndex))
|
||||
{
|
||||
// MCOL-641
|
||||
case 16:
|
||||
|
@ -814,22 +814,27 @@ inline uint32_t Row::getStringLength(uint32_t colIndex) const
|
||||
memcpy(&data[offset], strdata, length);
|
||||
}*/
|
||||
|
||||
// WIP MCOL-641. This method can be applied to uint8_t* buffers.
|
||||
// MCOL-641. This method can be applied to uint8_t* buffers.
|
||||
template<typename T>
|
||||
inline void Row::setBinaryField(T* value, uint32_t width, uint32_t colIndex)
|
||||
{
|
||||
memcpy(&data[offsets[colIndex]], value, width);
|
||||
}
|
||||
|
||||
// WIP MCOL-641. This method !cannot! be applied to uint8_t* buffers.
|
||||
// MCOL-641. This method !cannot! be applied to uint8_t* buffers.
|
||||
template<typename T>
|
||||
inline void Row::setBinaryField_offset(T* value, uint32_t width, uint32_t offset)
|
||||
{
|
||||
// WIP Compare performance.
|
||||
//memcpy(&data[offset], value, width);
|
||||
*reinterpret_cast<T*>(&data[offset]) = *value;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void Row::setBinaryField_offset<uint8_t>(uint8_t* value, uint32_t width, uint32_t offset)
|
||||
{
|
||||
memcpy(&data[offset], value, width);
|
||||
}
|
||||
|
||||
inline void Row::setStringField(const uint8_t* strdata, uint32_t length, uint32_t colIndex)
|
||||
{
|
||||
uint64_t offset;
|
||||
|
@ -51,8 +51,8 @@ using namespace BRM;
|
||||
#include "cacheutils.h"
|
||||
#include "IDBDataFile.h"
|
||||
#include "IDBPolicy.h"
|
||||
|
||||
#include "checks.h"
|
||||
#include "columnwidth.h"
|
||||
|
||||
namespace WriteEngine
|
||||
{
|
||||
@ -3000,21 +3000,16 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs,
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
// WIP MCOL-641
|
||||
// decimal width > 8 cannot be stored in an integer
|
||||
if (fetchColColwidths[fetchColPos] > 8)
|
||||
if (fetchColColwidths[fetchColPos] == 16)
|
||||
{
|
||||
int128_t* dec;
|
||||
char buf[41];
|
||||
char buf[utils::MAXLENGTH16BYTES];
|
||||
dec = row.getBinaryField<int128_t>(fetchColPos);
|
||||
dataconvert::DataConvert::decimalToString<int128_t>(dec,
|
||||
dataconvert::DataConvert::decimalToString(dec,
|
||||
(unsigned)fetchColScales[fetchColPos], buf,
|
||||
sizeof(buf), fetchColTypes[fetchColPos]);
|
||||
|
||||
value = buf;
|
||||
|
||||
//value = row.getStringField(fetchColPos);
|
||||
//unsigned i = strlen(value.c_str());
|
||||
//value = value.substr(0, i);
|
||||
value.assign(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3368,22 +3363,17 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs,
|
||||
case CalpontSystemCatalog::DECIMAL:
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
// WIP MCOL-641
|
||||
// decimal width > 8 cannot be stored in an integer
|
||||
if (fetchColColwidths[fetchColPos] > 8)
|
||||
if (fetchColColwidths[fetchColPos] == 16)
|
||||
{
|
||||
// WIP MCOL-641
|
||||
int128_t* dec;
|
||||
char buf[41];
|
||||
char buf[utils::MAXLENGTH16BYTES];
|
||||
dec = row.getBinaryField<int128_t>(fetchColPos);
|
||||
dataconvert::DataConvert::decimalToString<int128_t>(dec,
|
||||
dataconvert::DataConvert::decimalToString(dec,
|
||||
(unsigned)fetchColScales[fetchColPos], buf,
|
||||
sizeof(buf), fetchColTypes[fetchColPos]);
|
||||
|
||||
value = buf;
|
||||
|
||||
//value = row.getStringField(fetchColPos);
|
||||
//unsigned i = strlen(value.c_str());
|
||||
//value = value.substr(0, i);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ using namespace execplan;
|
||||
#include "MonitorProcMem.h"
|
||||
using namespace idbdatafile;
|
||||
#include "dataconvert.h"
|
||||
#include "widedecimalutils.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define isnan _isnan
|
||||
@ -3973,11 +3974,16 @@ void WriteEngineWrapper::printInputValue(const ColStructList& colStructList,
|
||||
curStr = boost::lexical_cast<string>(boost::any_cast<float>(curTuple.data));
|
||||
else if (curTuple.data.type() == typeid(long long))
|
||||
curStr = boost::lexical_cast<string>(boost::any_cast<long long>(curTuple.data));
|
||||
else if (curTuple.data.type() == typeid(int128_t))
|
||||
{
|
||||
// WIP replace with a single call
|
||||
char buf[utils::MAXLENGTH16BYTES];
|
||||
int128_t val = boost::any_cast<int128_t>(curTuple.data);
|
||||
dataconvert::DataConvert::toString(&val, 0, buf, utils::MAXLENGTH16BYTES);
|
||||
curStr.assign(buf);
|
||||
}
|
||||
else if (curTuple.data.type() == typeid(double))
|
||||
curStr = boost::lexical_cast<string>(boost::any_cast<double>(curTuple.data));
|
||||
// else
|
||||
// if (curTuple.data.type() == typeid(bool))
|
||||
// curStr = boost::lexical_cast<string>(boost::any_cast<bool>(curTuple.data));
|
||||
else if (curTuple.data.type() == typeid(short))
|
||||
curStr = boost::lexical_cast<string>(boost::any_cast<short>(curTuple.data));
|
||||
else if (curTuple.data.type() == typeid(char))
|
||||
|
Reference in New Issue
Block a user