1
0
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:
Roman Nozdrin
2020-03-02 14:38:40 +00:00
parent 61647c1f5b
commit 97ee1609b2
16 changed files with 200 additions and 193 deletions

View File

@ -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_");

View File

@ -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());

View File

@ -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<>

View File

@ -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)

View File

@ -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;

View File

@ -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:

View File

@ -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;
const uint64_t BINARYNULLVALUELOW = 0ULL;
const uint64_t BINARYNULLVALUEHIGH = 0x8000000000000000ULL;
const uint64_t BINARYEMPTYVALUELOW = 1ULL;
const uint64_t BINARYEMPTYVALUEHIGH = 0x8000000000000000ULL;
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

View File

@ -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,

View File

@ -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)
{

View File

@ -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()));
}

View File

@ -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;
}

View File

@ -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]);

View File

@ -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:

View File

@ -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;

View File

@ -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;
}

View File

@ -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))