You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-06-13 16:01:32 +03:00
MCOL-4387 Convert dataconvert::decimalToString() into VDecimal and TSInt128 methods
This commit is contained in:
@ -632,16 +632,20 @@ int TypeHandlerSLongDouble::storeValueToField(rowgroup::Row &row, int pos,
|
|||||||
int TypeHandlerXDecimal::storeValueToField64(rowgroup::Row &row, int pos,
|
int TypeHandlerXDecimal::storeValueToField64(rowgroup::Row &row, int pos,
|
||||||
StoreField *f) const
|
StoreField *f) const
|
||||||
{
|
{
|
||||||
int64_t val = row.getIntField(pos);
|
return f->store_decimal64(datatypes::VDecimal(row.getIntField(pos),
|
||||||
return f->store_decimal64(val);
|
f->scale(),
|
||||||
|
f->precision()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int TypeHandlerXDecimal::storeValueToField128(rowgroup::Row &row, int pos,
|
int TypeHandlerXDecimal::storeValueToField128(rowgroup::Row &row, int pos,
|
||||||
StoreField *f) const
|
StoreField *f) const
|
||||||
{
|
{
|
||||||
int128_t* dec= row.getBinaryField<int128_t>(pos);
|
int128_t* decPtr = row.getBinaryField<int128_t>(pos);
|
||||||
return f->store_decimal128(*dec);
|
return f->store_decimal128(datatypes::VDecimal(0,
|
||||||
|
f->scale(),
|
||||||
|
f->precision(),
|
||||||
|
decPtr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -780,12 +784,8 @@ TypeHandlerXDecimal::format128(const SimpleValue &v,
|
|||||||
const
|
const
|
||||||
{
|
{
|
||||||
idbassert(isValidXDecimal128(attr));
|
idbassert(isValidXDecimal128(attr));
|
||||||
ostringstream oss;
|
datatypes::VDecimal dec(0, attr.scale, attr.precision, v.toSInt128());
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
return dec.toString(true);
|
||||||
int128_t tmp= v.toSInt128();
|
|
||||||
DataConvert::decimalToString(&tmp, (unsigned) attr.scale, buf, (uint8_t) sizeof(buf), code());
|
|
||||||
oss << buf;
|
|
||||||
return oss.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -720,6 +720,7 @@ public:
|
|||||||
virtual ~StoreField() {}
|
virtual ~StoreField() {}
|
||||||
virtual int32_t colWidth() const = 0;
|
virtual int32_t colWidth() const = 0;
|
||||||
virtual int32_t precision() const = 0;
|
virtual int32_t precision() const = 0;
|
||||||
|
virtual int32_t scale() const = 0;
|
||||||
virtual int store_date(int64_t val) = 0;
|
virtual int store_date(int64_t val) = 0;
|
||||||
virtual int store_datetime(int64_t val) = 0;
|
virtual int store_datetime(int64_t val) = 0;
|
||||||
virtual int store_time(int64_t val) = 0;
|
virtual int store_time(int64_t val) = 0;
|
||||||
@ -730,8 +731,8 @@ public:
|
|||||||
virtual int store_float(float val) = 0;
|
virtual int store_float(float val) = 0;
|
||||||
virtual int store_double(double val) = 0;
|
virtual int store_double(double val) = 0;
|
||||||
virtual int store_long_double(long double val) = 0;
|
virtual int store_long_double(long double val) = 0;
|
||||||
virtual int store_decimal64(int64_t val) = 0;
|
virtual int store_decimal64(const datatypes::VDecimal& dec) = 0;
|
||||||
virtual int store_decimal128(const int128_t &val) = 0;
|
virtual int store_decimal128(const datatypes::VDecimal& dec) = 0;
|
||||||
virtual int store_lob(const char *str, size_t length) = 0;
|
virtual int store_lob(const char *str, size_t length) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -195,45 +195,6 @@ namespace datatypes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Decimal::toString(VDecimal& value)
|
|
||||||
{
|
|
||||||
char buf[Decimal::MAXLENGTH16BYTES];
|
|
||||||
if (value.s128Value == Decimal128Null)
|
|
||||||
{
|
|
||||||
return std::string("NULL");
|
|
||||||
}
|
|
||||||
else if (value.s128Value == Decimal128Empty)
|
|
||||||
{
|
|
||||||
return std::string("EMPTY");
|
|
||||||
}
|
|
||||||
dataconvert::DataConvert::decimalToString(&value.s128Value,
|
|
||||||
value.scale, buf, (uint8_t) sizeof(buf),
|
|
||||||
datatypes::SystemCatalog::DECIMAL);
|
|
||||||
return std::string(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Decimal::toString(const VDecimal& value)
|
|
||||||
{
|
|
||||||
return toString(const_cast<VDecimal&>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Decimal::toString(const int128_t& value)
|
|
||||||
{
|
|
||||||
char buf[Decimal::MAXLENGTH16BYTES];
|
|
||||||
if (value == Decimal128Null)
|
|
||||||
{
|
|
||||||
return std::string("NULL");
|
|
||||||
}
|
|
||||||
else if (value == Decimal128Empty)
|
|
||||||
{
|
|
||||||
return std::string("EMPTY");
|
|
||||||
}
|
|
||||||
int128_t& constLessValue = const_cast<int128_t&>(value);
|
|
||||||
dataconvert::DataConvert::decimalToString(&constLessValue,
|
|
||||||
0, buf, sizeof(buf), datatypes::SystemCatalog::DECIMAL);
|
|
||||||
return std::string(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Decimal::compare(const VDecimal& l, const VDecimal& r)
|
int Decimal::compare(const VDecimal& l, const VDecimal& r)
|
||||||
{
|
{
|
||||||
int128_t divisorL, divisorR;
|
int128_t divisorL, divisorR;
|
||||||
@ -559,4 +520,221 @@ namespace datatypes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Writes integer part of a Decimal using int128 argument provided
|
||||||
|
uint8_t VDecimal::writeIntPart(const int128_t& x,
|
||||||
|
char* buf,
|
||||||
|
const uint8_t buflen) const
|
||||||
|
{
|
||||||
|
char* p = buf;
|
||||||
|
int128_t intPart = x;
|
||||||
|
int128_t high = 0, mid = 0, low = 0;
|
||||||
|
uint64_t maxUint64divisor = 10000000000000000000ULL;
|
||||||
|
|
||||||
|
// Assuming scale = [0, 56]
|
||||||
|
switch (scale / datatypes::maxPowOf10)
|
||||||
|
{
|
||||||
|
case 2: // scale = [38, 56]
|
||||||
|
intPart /= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||||
|
intPart /= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||||
|
low = intPart;
|
||||||
|
break;
|
||||||
|
case 1: // scale = [19, 37]
|
||||||
|
intPart /= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||||
|
intPart /= datatypes::mcs_pow_10[scale % datatypes::maxPowOf10];
|
||||||
|
low = intPart % maxUint64divisor;
|
||||||
|
mid = intPart / maxUint64divisor;
|
||||||
|
break;
|
||||||
|
case 0: // scale = [0, 18]
|
||||||
|
intPart /= datatypes::mcs_pow_10[scale % datatypes::maxPowOf10];
|
||||||
|
low = intPart % maxUint64divisor;
|
||||||
|
intPart /= maxUint64divisor;
|
||||||
|
mid = intPart % maxUint64divisor;
|
||||||
|
high = intPart / maxUint64divisor;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw logging::QueryDataExcept("VDecimal::writeIntPart() bad scale",
|
||||||
|
logging::formatErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
p += printPodParts(p, high, mid, low);
|
||||||
|
uint8_t written = p - buf;
|
||||||
|
if (buflen <= written)
|
||||||
|
{
|
||||||
|
throw logging::QueryDataExcept("VDecimal::writeIntPart() char buffer overflow.",
|
||||||
|
logging::formatErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t VDecimal::writeFractionalPart(const int128_t& x,
|
||||||
|
char* buf,
|
||||||
|
const uint8_t buflen) const
|
||||||
|
{
|
||||||
|
int128_t scaleDivisor = 1;
|
||||||
|
char* p = buf;
|
||||||
|
|
||||||
|
switch (scale / datatypes::maxPowOf10)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||||
|
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||||
|
//fallthrough
|
||||||
|
case 0:
|
||||||
|
scaleDivisor *= datatypes::mcs_pow_10[scale % datatypes::maxPowOf10];
|
||||||
|
}
|
||||||
|
|
||||||
|
int128_t fractionalPart = x % scaleDivisor;
|
||||||
|
|
||||||
|
// divide by the base until we have non-zero quotient
|
||||||
|
scaleDivisor /= 10;
|
||||||
|
|
||||||
|
while (scaleDivisor > 1 && fractionalPart / scaleDivisor == 0)
|
||||||
|
{
|
||||||
|
*p++ = '0';
|
||||||
|
scaleDivisor /= 10;
|
||||||
|
}
|
||||||
|
size_t written = p - buf;;
|
||||||
|
p += TSInt128::writeIntPart(fractionalPart, p, buflen - written);
|
||||||
|
return p - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The method writes Decimal based on TSInt128 with scale provided.
|
||||||
|
// It first writes sign, then extracts integer part
|
||||||
|
// prints delimiter and then decimal part.
|
||||||
|
std::string VDecimal::toStringTSInt128WithScale() const
|
||||||
|
{
|
||||||
|
char buf[Decimal::MAXLENGTH16BYTES];
|
||||||
|
uint8_t left = sizeof(buf);
|
||||||
|
char* p = buf;
|
||||||
|
int128_t tempValue = s128Value;
|
||||||
|
// sign
|
||||||
|
if (tempValue < static_cast<int128_t>(0))
|
||||||
|
{
|
||||||
|
*p++ = '-';
|
||||||
|
tempValue *= -1;
|
||||||
|
left--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// integer part
|
||||||
|
p += writeIntPart(tempValue, p, left);
|
||||||
|
|
||||||
|
// decimal delimiter
|
||||||
|
*p++ = '.';
|
||||||
|
// decimal part
|
||||||
|
left = sizeof(buf) - (p - buf);
|
||||||
|
p += writeFractionalPart(tempValue, p, left);
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
uint8_t written = p - buf;
|
||||||
|
if (sizeof(buf) <= written)
|
||||||
|
{
|
||||||
|
throw logging::QueryDataExcept("VDecimal::toString() char buffer overflow.",
|
||||||
|
logging::formatErr);
|
||||||
|
}
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VDecimal::toStringTSInt64() const
|
||||||
|
{
|
||||||
|
char buf[Decimal::MAXLENGTH8BYTES];
|
||||||
|
// Need 19 digits maxium to hold a sum result of 18 digits decimal column.
|
||||||
|
// We don't make a copy of value b/c we mutate its string
|
||||||
|
// representation.
|
||||||
|
#ifndef __LP64__
|
||||||
|
snprintf(buf, sizeof(buf), "%lld", value);
|
||||||
|
#else
|
||||||
|
snprintf(buf, sizeof(buf), "%ld", value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//we want to move the last dt_scale chars right by one spot
|
||||||
|
// to insert the dp we want to move the trailing null as well,
|
||||||
|
// so it's really dt_scale+1 chars
|
||||||
|
size_t l1 = strlen(buf);
|
||||||
|
char* ptr = &buf[0];
|
||||||
|
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
ptr++;
|
||||||
|
idbassert(l1 >= 2);
|
||||||
|
l1--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//need to make sure we have enough leading zeros for this to work.
|
||||||
|
//at this point scale is always > 0
|
||||||
|
size_t l2 = 1;
|
||||||
|
|
||||||
|
if ((unsigned)scale > l1)
|
||||||
|
{
|
||||||
|
const char* zeros = "00000000000000000000"; //20 0's
|
||||||
|
size_t diff = 0;
|
||||||
|
|
||||||
|
if (value != 0)
|
||||||
|
diff = scale - l1; //this will always be > 0
|
||||||
|
else
|
||||||
|
diff = scale;
|
||||||
|
|
||||||
|
memmove((ptr + diff), ptr, l1 + 1); //also move null
|
||||||
|
memcpy(ptr, zeros, diff);
|
||||||
|
|
||||||
|
if (value != 0)
|
||||||
|
l1 = 0;
|
||||||
|
else
|
||||||
|
l1 = 1;
|
||||||
|
}
|
||||||
|
else if ((unsigned)scale == l1)
|
||||||
|
{
|
||||||
|
l1 = 0;
|
||||||
|
l2 = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l1 -= scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove((ptr + l1 + l2), (ptr + l1), scale + 1); //also move null
|
||||||
|
|
||||||
|
if (l2 == 2)
|
||||||
|
*(ptr + l1++) = '0';
|
||||||
|
|
||||||
|
*(ptr + l1) = '.';
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatcher method for toString() implementations
|
||||||
|
std::string VDecimal::toString(bool hasTSInt128) const
|
||||||
|
{
|
||||||
|
// There must be no empty at this point though
|
||||||
|
if (isNull())
|
||||||
|
{
|
||||||
|
return std::string("NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LIKELY(hasTSInt128 || isTSInt128ByPrecision()))
|
||||||
|
{
|
||||||
|
if (scale)
|
||||||
|
{
|
||||||
|
return toStringTSInt128WithScale();
|
||||||
|
}
|
||||||
|
return TSInt128::toString();
|
||||||
|
}
|
||||||
|
// TSInt64 Decimal
|
||||||
|
if (scale)
|
||||||
|
{
|
||||||
|
return toStringTSInt64();
|
||||||
|
}
|
||||||
|
return std::to_string(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const VDecimal& dec)
|
||||||
|
{
|
||||||
|
os << dec.toString();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
@ -131,8 +131,8 @@ const int128_t mcs_pow_10_128[20] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint32_t maxPowOf10 = sizeof(mcs_pow_10)/sizeof(mcs_pow_10[0])-1;
|
constexpr uint32_t maxPowOf10 = sizeof(mcs_pow_10)/sizeof(mcs_pow_10[0])-1;
|
||||||
constexpr int128_t Decimal128Null = int128_t(0x8000000000000000LL) << 64;
|
constexpr int128_t Decimal128Null = TSInt128::NullValue;
|
||||||
constexpr int128_t Decimal128Empty = (int128_t(0x8000000000000000LL) << 64) + 1;
|
constexpr int128_t Decimal128Empty = TSInt128::EmptyValue;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,7 +172,7 @@ class Decimal
|
|||||||
Decimal() { };
|
Decimal() { };
|
||||||
~Decimal() { };
|
~Decimal() { };
|
||||||
|
|
||||||
static constexpr uint8_t MAXLENGTH16BYTES = 42;
|
static constexpr uint8_t MAXLENGTH16BYTES = TSInt128::maxLength();
|
||||||
static constexpr uint8_t MAXLENGTH8BYTES = 23;
|
static constexpr uint8_t MAXLENGTH8BYTES = 23;
|
||||||
|
|
||||||
static inline bool isWideDecimalNullValue(const int128_t& val)
|
static inline bool isWideDecimalNullValue(const int128_t& val)
|
||||||
@ -259,13 +259,6 @@ class Decimal
|
|||||||
const VDecimal& r,
|
const VDecimal& r,
|
||||||
VDecimal& result);
|
VDecimal& result);
|
||||||
|
|
||||||
/**
|
|
||||||
@brief Convenience methods to put decimal into a std::string.
|
|
||||||
*/
|
|
||||||
static std::string toString(VDecimal& value);
|
|
||||||
static std::string toString(const VDecimal& value);
|
|
||||||
static std::string toString(const int128_t& value);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief The method detects whether decimal type is wide
|
@brief The method detects whether decimal type is wide
|
||||||
using precision.
|
using precision.
|
||||||
@ -558,6 +551,14 @@ class VDecimal: public TSInt128
|
|||||||
precision(p)
|
precision(p)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
VDecimal(int64_t unused, int8_t s, uint8_t p, const int128_t* val128Ptr) :
|
||||||
|
TSInt128(val128Ptr),
|
||||||
|
value(unused),
|
||||||
|
scale(s),
|
||||||
|
precision(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
int decimalComp(const VDecimal& d) const
|
int decimalComp(const VDecimal& d) const
|
||||||
{
|
{
|
||||||
lldiv_t d1 = lldiv(value, static_cast<int64_t>(mcs_pow_10[scale]));
|
lldiv_t d1 = lldiv(value, static_cast<int64_t>(mcs_pow_10[scale]));
|
||||||
@ -819,9 +820,35 @@ class VDecimal: public TSInt128
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isTSInt128ByPrecision() const
|
||||||
|
{
|
||||||
|
return precision > INT64MAXPRECISION
|
||||||
|
&& precision <= INT128MAXPRECISION;
|
||||||
|
}
|
||||||
|
// hasTSInt128 explicitly tells to print int128 out in cases
|
||||||
|
// where precision can't detect decimal type properly, e.g.
|
||||||
|
// DECIMAL(10)/DECIMAL(38)
|
||||||
|
std::string toString(bool hasTSInt128 = false) const;
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const VDecimal& dec);
|
||||||
|
|
||||||
int64_t value;
|
int64_t value;
|
||||||
int8_t scale; // 0~38
|
int8_t scale; // 0~38
|
||||||
uint8_t precision; // 1~38
|
uint8_t precision; // 1~38
|
||||||
|
|
||||||
|
// STRICTLY for unit tests!!!
|
||||||
|
void setTSInt64Value(const int64_t x) { value = x; }
|
||||||
|
void setTSInt128Value(const int128_t& x) { s128Value = x; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t writeIntPart(const int128_t& x,
|
||||||
|
char* buf,
|
||||||
|
const uint8_t buflen) const;
|
||||||
|
uint8_t writeFractionalPart(const int128_t& x,
|
||||||
|
char* buf,
|
||||||
|
const uint8_t buflen) const;
|
||||||
|
std::string toStringTSInt128WithScale() const;
|
||||||
|
std::string toStringTSInt64() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //end of namespace
|
} //end of namespace
|
||||||
|
@ -17,7 +17,10 @@
|
|||||||
MA 02110-1301, USA.
|
MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "mcs_int128.h"
|
#include "mcs_int128.h"
|
||||||
|
#include "exceptclasses.h"
|
||||||
|
|
||||||
namespace datatypes
|
namespace datatypes
|
||||||
{
|
{
|
||||||
@ -33,6 +36,99 @@ namespace datatypes
|
|||||||
return getLongDoubleFromFloat128(static_cast<__float128>(s128Value));
|
return getLongDoubleFromFloat128(static_cast<__float128>(s128Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t TSInt128::printPodParts(char* buf,
|
||||||
|
const int128_t& high,
|
||||||
|
const int128_t& mid,
|
||||||
|
const int128_t& low) const
|
||||||
|
{
|
||||||
|
char* p = buf;
|
||||||
|
// pod[0] is low 8 bytes, pod[1] is high 8 bytes
|
||||||
|
const uint64_t* high_pod = reinterpret_cast<const uint64_t*>(&high);
|
||||||
|
const uint64_t* mid_pod = reinterpret_cast<const uint64_t*>(&mid);
|
||||||
|
const uint64_t* low_pod = reinterpret_cast<const uint64_t*>(&low);
|
||||||
|
|
||||||
|
if (high_pod[0] != 0)
|
||||||
|
{
|
||||||
|
p += sprintf(p, "%lu", high_pod[0]);
|
||||||
|
p += sprintf(p, "%019lu", mid_pod[0]);
|
||||||
|
p += sprintf(p, "%019lu", low_pod[0]);
|
||||||
|
}
|
||||||
|
else if (mid_pod[0] != 0)
|
||||||
|
{
|
||||||
|
p += sprintf(p, "%lu", mid_pod[0]);
|
||||||
|
p += sprintf(p, "%019lu", low_pod[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p += sprintf(p, "%lu", low_pod[0]);
|
||||||
|
}
|
||||||
|
return p - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method writes unsigned integer representation of TSInt128
|
||||||
|
uint8_t TSInt128::writeIntPart(const int128_t& x,
|
||||||
|
char* buf,
|
||||||
|
const uint8_t buflen) const
|
||||||
|
{
|
||||||
|
char* p = buf;
|
||||||
|
int128_t high = 0, mid = 0, low = 0;
|
||||||
|
uint64_t maxUint64divisor = 10000000000000000000ULL;
|
||||||
|
|
||||||
|
low = x % maxUint64divisor;
|
||||||
|
int128_t value = x / maxUint64divisor;
|
||||||
|
mid = value % maxUint64divisor;
|
||||||
|
high = value / maxUint64divisor;
|
||||||
|
|
||||||
|
p += printPodParts(p, high, mid, low);
|
||||||
|
uint8_t written = p - buf;
|
||||||
|
if (buflen <= written)
|
||||||
|
{
|
||||||
|
throw logging::QueryDataExcept("TSInt128::writeIntPart() char buffer overflow.",
|
||||||
|
logging::formatErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
// conversion to std::string
|
||||||
|
std::string TSInt128::toString() const
|
||||||
|
{
|
||||||
|
if (isNull())
|
||||||
|
{
|
||||||
|
return std::string("NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty())
|
||||||
|
{
|
||||||
|
return std::string("EMPTY");
|
||||||
|
}
|
||||||
|
|
||||||
|
int128_t tempValue = s128Value;
|
||||||
|
char buf[TSInt128::MAXLENGTH16BYTES];
|
||||||
|
uint8_t left = sizeof(buf);
|
||||||
|
char* p = buf;
|
||||||
|
// sign
|
||||||
|
if (tempValue < static_cast<int128_t>(0))
|
||||||
|
{
|
||||||
|
*p++ = '-';
|
||||||
|
tempValue *= -1;
|
||||||
|
left--;
|
||||||
|
}
|
||||||
|
// integer part
|
||||||
|
// reduce the size by one to account for \0
|
||||||
|
left--;
|
||||||
|
p += writeIntPart(tempValue, p, left);
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const TSInt128& x)
|
||||||
|
{
|
||||||
|
os << x.toString();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
// The method converts a wide decimal s128Value to an int64_t,
|
// The method converts a wide decimal s128Value to an int64_t,
|
||||||
// saturating the s128Value if necessary.
|
// saturating the s128Value if necessary.
|
||||||
inline int64_t TSInt128::getInt64FromWideDecimal()
|
inline int64_t TSInt128::getInt64FromWideDecimal()
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// Inline asm has three argument lists: output, input and clobber list
|
// Inline asm has three argument lists: output, input and clobber list
|
||||||
#if defined(__GNUC__) && (__GNUC___ > 7)
|
#if defined(__GNUC__) && (__GNUC___ > 7)
|
||||||
@ -116,18 +117,41 @@ static inline long double getLongDoubleFromFloat128(const __float128& value)
|
|||||||
class TSInt128
|
class TSInt128
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// A variety of ctors for aligned and unaligned arguments
|
static constexpr uint8_t MAXLENGTH16BYTES = 42;
|
||||||
|
static constexpr int128_t NullValue = int128_t(0x8000000000000000LL) << 64;
|
||||||
|
static constexpr int128_t EmptyValue = (int128_t(0x8000000000000000LL) << 64) + 1;
|
||||||
|
|
||||||
|
|
||||||
|
// A variety of ctors for aligned and unaligned arguments
|
||||||
TSInt128(): s128Value(0) { }
|
TSInt128(): s128Value(0) { }
|
||||||
|
|
||||||
// aligned argument
|
// aligned argument
|
||||||
TSInt128(const int128_t& x) { s128Value = x; }
|
TSInt128(const int128_t& x) { s128Value = x; }
|
||||||
|
|
||||||
// unaligned argument
|
// unaligned argument
|
||||||
TSInt128(const int128_t* x) { assignPtrPtr(&s128Value, x); }
|
TSInt128(const int128_t* x) { assignPtrPtr(&s128Value, x); }
|
||||||
|
|
||||||
// unaligned argument
|
// unaligned argument
|
||||||
TSInt128(const unsigned char* x) { assignPtrPtr(&s128Value, x); }
|
TSInt128(const unsigned char* x) { assignPtrPtr(&s128Value, x); }
|
||||||
|
|
||||||
|
// Method returns max length of a string representation
|
||||||
|
static constexpr uint8_t maxLength()
|
||||||
|
{
|
||||||
|
return TSInt128::MAXLENGTH16BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the value is NULL
|
||||||
|
inline bool isNull() const
|
||||||
|
{
|
||||||
|
return s128Value == NullValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the value is Empty
|
||||||
|
inline bool isEmpty() const
|
||||||
|
{
|
||||||
|
return s128Value == EmptyValue;
|
||||||
|
}
|
||||||
|
|
||||||
// The method copies 16 bytes from one memory cell
|
// The method copies 16 bytes from one memory cell
|
||||||
// into another using memcpy or SIMD.
|
// into another using memcpy or SIMD.
|
||||||
// memcpy in gcc >= 7 is replaced with SIMD instructions
|
// memcpy in gcc >= 7 is replaced with SIMD instructions
|
||||||
@ -158,6 +182,22 @@ class TSInt128
|
|||||||
return s128Value == static_cast<int128_t>(x);
|
return s128Value == static_cast<int128_t>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print int128_t parts represented as PODs
|
||||||
|
uint8_t printPodParts(char* buf,
|
||||||
|
const int128_t& high,
|
||||||
|
const int128_t& mid,
|
||||||
|
const int128_t& low) const;
|
||||||
|
|
||||||
|
// writes integer part of dec into a buffer
|
||||||
|
uint8_t writeIntPart(const int128_t& x,
|
||||||
|
char* buf,
|
||||||
|
const uint8_t buflen) const;
|
||||||
|
|
||||||
|
// string representation of TSInt128
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const TSInt128& x);
|
||||||
|
|
||||||
// The method converts a wide decimal s128Value to a double.
|
// The method converts a wide decimal s128Value to a double.
|
||||||
inline double getDoubleFromWideDecimal();
|
inline double getDoubleFromWideDecimal();
|
||||||
|
|
||||||
|
@ -153,8 +153,10 @@ void SimpleColumn_Decimal<len>::setNullVal()
|
|||||||
template<int len>
|
template<int len>
|
||||||
inline const std::string& SimpleColumn_Decimal<len>:: getStrVal(rowgroup::Row& row, bool& isNull)
|
inline const std::string& SimpleColumn_Decimal<len>:: getStrVal(rowgroup::Row& row, bool& isNull)
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString((int64_t)row.getIntField<len>(fInputIndex), fResultType.scale, tmp, 22, fResultType.colDataType);
|
datatypes::VDecimal dec((int64_t)row.getIntField<len>(fInputIndex),
|
||||||
fResult.strVal = std::string(tmp);
|
fResultType.scale,
|
||||||
|
fResultType.precision);
|
||||||
|
fResult.strVal = dec.toString();
|
||||||
return fResult.strVal;
|
return fResult.strVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,10 +632,10 @@ inline const std::string& TreeNode::getStrVal(const std::string& timeZone)
|
|||||||
case CalpontSystemCatalog::UDECIMAL:
|
case CalpontSystemCatalog::UDECIMAL:
|
||||||
{
|
{
|
||||||
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
|
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
dataconvert::DataConvert::decimalToString(&fResult.decimalVal.s128Value, fResult.decimalVal.scale, tmp, datatypes::Decimal::MAXLENGTH16BYTES, fResultType.colDataType);
|
// Explicit path for TSInt128 decimals with low precision
|
||||||
|
fResult.strVal = fResult.decimalVal.toString(true);
|
||||||
else
|
else
|
||||||
dataconvert::DataConvert::decimalToString(fResult.decimalVal.value, fResult.decimalVal.scale, tmp, 22, fResultType.colDataType);
|
fResult.strVal = fResult.decimalVal.toString();
|
||||||
fResult.strVal = std::string(tmp);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,13 +460,11 @@ void GroupConcator::outputRow(std::ostringstream& oss, const rowgroup::Row& row)
|
|||||||
|
|
||||||
if (LIKELY(row.getColumnWidth(*i) == datatypes::MAXDECIMALWIDTH))
|
if (LIKELY(row.getColumnWidth(*i) == datatypes::MAXDECIMALWIDTH))
|
||||||
{
|
{
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
datatypes::VDecimal dec(0,
|
||||||
|
scale,
|
||||||
int128_t* dec = row.getBinaryField<int128_t>(*i);
|
row.getPrecision(*i),
|
||||||
dataconvert::DataConvert::decimalToString(dec,
|
row.getBinaryField<int128_t>(*i));
|
||||||
static_cast<uint32_t>(scale), buf,
|
oss << fixed << dec;
|
||||||
(uint8_t) sizeof(buf), types[*i]);
|
|
||||||
oss << fixed << buf;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1099,8 +1099,8 @@ dec4: /* have to pick a scale to use for the double. using 5... */
|
|||||||
case CalpontSystemCatalog::DECIMAL:
|
case CalpontSystemCatalog::DECIMAL:
|
||||||
case CalpontSystemCatalog::UDECIMAL:
|
case CalpontSystemCatalog::UDECIMAL:
|
||||||
{
|
{
|
||||||
int64_t val;
|
int64_t val = 0;
|
||||||
int128_t val128;
|
int128_t val128 = 0;
|
||||||
bool isInputWide = false;
|
bool isInputWide = false;
|
||||||
|
|
||||||
if (in.getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
if (in.getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
||||||
@ -1185,15 +1185,21 @@ dec4: /* have to pick a scale to use for the double. using 5... */
|
|||||||
case CalpontSystemCatalog::VARCHAR:
|
case CalpontSystemCatalog::VARCHAR:
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
char buf[50];
|
if (LIKELY(isInputWide))
|
||||||
dataconvert::DataConvert::decimalToString(val, scale, buf, 50, out->getColTypes()[i]);
|
{
|
||||||
/* ostringstream oss;
|
datatypes::VDecimal dec(0,
|
||||||
if (scale == 0)
|
in.getScale(i),
|
||||||
oss << val;
|
in.getPrecision(i),
|
||||||
else
|
val128);
|
||||||
oss << (val / IDB_pow[scale]) << "."
|
out->setStringField(dec.toString(), i);
|
||||||
<< setw(scale) << setfill('0') << (val % IDB_pow[scale]); */
|
}
|
||||||
out->setStringField(string(buf), i);
|
else
|
||||||
|
{
|
||||||
|
datatypes::VDecimal dec(val,
|
||||||
|
in.getScale(i),
|
||||||
|
in.getPrecision(i));
|
||||||
|
out->setStringField(dec.toString(), i);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
const CalpontSystemCatalog::ColType &type() const { return m_type; }
|
const CalpontSystemCatalog::ColType &type() const { return m_type; }
|
||||||
int32_t colWidth() const override { return m_type.colWidth; }
|
int32_t colWidth() const override { return m_type.colWidth; }
|
||||||
int32_t precision() const override { return m_type.precision; }
|
int32_t precision() const override { return m_type.precision; }
|
||||||
|
int32_t scale() const override { return m_type.scale; }
|
||||||
|
|
||||||
int store_date(int64_t val) override
|
int store_date(int64_t val) override
|
||||||
{
|
{
|
||||||
@ -160,30 +161,16 @@ public:
|
|||||||
return m_field->store(static_cast<double>(dl));
|
return m_field->store(static_cast<double>(dl));
|
||||||
}
|
}
|
||||||
|
|
||||||
int store_decimal64(int64_t val) override
|
int store_decimal64(const datatypes::VDecimal& dec) override
|
||||||
{
|
{
|
||||||
// @bug4388 stick to InfiniDB's scale in case mysql gives wrong scale due
|
std::string decAsAStr = dec.toString();
|
||||||
// to create vtable limitation.
|
return m_field->store(decAsAStr.c_str(), decAsAStr.length(), m_field->charset());
|
||||||
//if (f2->dec < m_type.scale)
|
|
||||||
// f2->dec = m_type.scale;
|
|
||||||
|
|
||||||
// WIP MCOL-641
|
|
||||||
// This is too much
|
|
||||||
char buf[256];
|
|
||||||
dataconvert::DataConvert::decimalToString(val, (unsigned)m_type.scale,
|
|
||||||
buf, sizeof(buf), m_type.colDataType);
|
|
||||||
return m_field->store(buf, strlen(buf), m_field->charset());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int store_decimal128(const int128_t &val) override
|
int store_decimal128(const datatypes::VDecimal& dec) override
|
||||||
{
|
{
|
||||||
// We won't have more than [+-][0][.] + up to 38 digits
|
std::string decAsAStr = dec.toString(true);
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
return m_field->store(decAsAStr.c_str(), decAsAStr.length(), m_field->charset());
|
||||||
dataconvert::DataConvert::decimalToString((int128_t*) &val,
|
|
||||||
(unsigned) m_type.scale,
|
|
||||||
buf, (uint8_t) sizeof(buf),
|
|
||||||
m_type.colDataType);
|
|
||||||
return m_field->store(buf, strlen(buf), m_field->charset());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int store_lob(const char *str, size_t length) override
|
int store_lob(const char *str, size_t length) override
|
||||||
|
@ -112,12 +112,11 @@ static int generate_result(BRM::OID_t oid, BRM::DBRM* emp, TABLE* table, THD* th
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
table->field[4]->set_notnull();
|
table->field[4]->set_notnull();
|
||||||
|
std::string decAsAStr = datatypes::TSInt128(iter->partition.cprange.bigLoVal)
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
.toString();
|
||||||
dataconvert::DataConvert::decimalToString(
|
table->field[4]->store(decAsAStr.c_str(),
|
||||||
&iter->partition.cprange.bigLoVal,
|
decAsAStr.length(),
|
||||||
0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL);
|
table->field[4]->charset());
|
||||||
table->field[4]->store(buf, strlen(buf), table->field[4]->charset());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter->partition.cprange.bigHiVal <= (utils::minInt128 + 1))
|
if (iter->partition.cprange.bigHiVal <= (utils::minInt128 + 1))
|
||||||
@ -127,12 +126,11 @@ static int generate_result(BRM::OID_t oid, BRM::DBRM* emp, TABLE* table, THD* th
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
table->field[5]->set_notnull();
|
table->field[5]->set_notnull();
|
||||||
|
std::string decAsAStr = datatypes::TSInt128(iter->partition.cprange.bigHiVal)
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
.toString();
|
||||||
dataconvert::DataConvert::decimalToString(
|
table->field[5]->store(decAsAStr.c_str(),
|
||||||
&iter->partition.cprange.bigHiVal,
|
decAsAStr.length(),
|
||||||
0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL);
|
table->field[5]->charset());
|
||||||
table->field[5]->store(buf, strlen(buf), table->field[5]->charset());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@ using namespace dataconvert;
|
|||||||
#include "joblisttypes.h"
|
#include "joblisttypes.h"
|
||||||
#include "columnwidth.h"
|
#include "columnwidth.h"
|
||||||
|
|
||||||
using CSCDataType = execplan::CalpontSystemCatalog::ColDataType;
|
|
||||||
|
|
||||||
TEST(DataConvertTest, Strtoll128)
|
TEST(DataConvertTest, Strtoll128)
|
||||||
{
|
{
|
||||||
char *ep = NULL;
|
char *ep = NULL;
|
||||||
@ -543,252 +541,6 @@ TEST(DataConvertTest, NumberIntValue)
|
|||||||
EXPECT_EQ(b2, b4);
|
EXPECT_EQ(b2, b4);
|
||||||
EXPECT_TRUE(pushWarning);
|
EXPECT_TRUE(pushWarning);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DataConvertTest, DecimalToStringCheckScale0)
|
|
||||||
{
|
|
||||||
datatypes::SystemCatalog::TypeHolderStd ct;
|
|
||||||
ct.colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
string input, expected;
|
|
||||||
ct.precision = 38;
|
|
||||||
ct.scale = 0;
|
|
||||||
int128_t res;
|
|
||||||
|
|
||||||
// test simple values
|
|
||||||
res = 0;
|
|
||||||
expected = "0";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 2;
|
|
||||||
expected = "2";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -2;
|
|
||||||
expected = "-2";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 123;
|
|
||||||
expected = "123";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -123;
|
|
||||||
expected = "-123";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test max/min decimal (i.e. 38 9's)
|
|
||||||
res = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99;
|
|
||||||
expected = "99999999999999999999999999999999999999";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-99999999999999999999999999999999999999";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test trailing zeros
|
|
||||||
res = 123000;
|
|
||||||
expected = "123000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-123000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
}
|
|
||||||
TEST(DataConvertTest, DecimalToStringCheckScale10)
|
|
||||||
{
|
|
||||||
datatypes::SystemCatalog::TypeHolderStd ct;
|
|
||||||
ct.colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
string input, expected;
|
|
||||||
ct.precision = 38;
|
|
||||||
ct.scale = 10;
|
|
||||||
int128_t res;
|
|
||||||
|
|
||||||
// test simple values
|
|
||||||
res = 0;
|
|
||||||
expected = "0.0000000000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 2;
|
|
||||||
expected = "0.0000000002";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -2;
|
|
||||||
expected = "-0.0000000002";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 123;
|
|
||||||
expected = "0.0000000123";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -123;
|
|
||||||
expected = "-0.0000000123";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 12345678901;
|
|
||||||
expected = "1.2345678901";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -12345678901;
|
|
||||||
expected = "-1.2345678901";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test max/min decimal (i.e. 38 9's)
|
|
||||||
res = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99;
|
|
||||||
expected = "9999999999999999999999999999.9999999999";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-9999999999999999999999999999.9999999999";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test trailing zeros
|
|
||||||
res = 123000;
|
|
||||||
expected = "0.0000123000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-0.0000123000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test leading zeros
|
|
||||||
res = 10000000009;
|
|
||||||
expected = "1.0000000009";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-1.0000000009";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(DataConvertTest, DecimalToStringCheckScale38)
|
|
||||||
{
|
|
||||||
datatypes::SystemCatalog::TypeHolderStd ct;
|
|
||||||
ct.colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
string input, expected;
|
|
||||||
ct.precision = 38;
|
|
||||||
ct.scale = 38;
|
|
||||||
int128_t res;
|
|
||||||
|
|
||||||
// test simple values
|
|
||||||
res = 0;
|
|
||||||
expected = "0.00000000000000000000000000000000000000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 2;
|
|
||||||
expected = "0.00000000000000000000000000000000000002";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -2;
|
|
||||||
expected = "-0.00000000000000000000000000000000000002";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 123;
|
|
||||||
expected = "0.00000000000000000000000000000000000123";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -123;
|
|
||||||
expected = "-0.00000000000000000000000000000000000123";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = ((((((int128_t)1234567890 * 10000000000) + 1234567890) * 10000000000) + 1234567890) * 100000000 ) + 12345678;
|
|
||||||
expected = "0.12345678901234567890123456789012345678";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-0.12345678901234567890123456789012345678";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test max/min decimal (i.e. 38 9's)
|
|
||||||
res = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99;
|
|
||||||
expected = "0.99999999999999999999999999999999999999";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-0.99999999999999999999999999999999999999";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test trailing zeros
|
|
||||||
res = 123000;
|
|
||||||
expected = "0.00000000000000000000000000000000123000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-0.00000000000000000000000000000000123000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(DataConvertTest, DecimalToStringCheckScale37)
|
|
||||||
{
|
|
||||||
datatypes::SystemCatalog::TypeHolderStd ct;
|
|
||||||
ct.colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
string expected;
|
|
||||||
ct.precision = 38;
|
|
||||||
ct.scale = 37;
|
|
||||||
int128_t res;
|
|
||||||
|
|
||||||
// test simple values
|
|
||||||
res = 0;
|
|
||||||
expected = "0.0000000000000000000000000000000000000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 2;
|
|
||||||
expected = "0.0000000000000000000000000000000000002";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -2;
|
|
||||||
expected = "-0.0000000000000000000000000000000000002";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = 123;
|
|
||||||
expected = "0.0000000000000000000000000000000000123";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -123;
|
|
||||||
expected = "-0.0000000000000000000000000000000000123";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = ((((((int128_t)1234567890 * 10000000000) + 1234567890) * 10000000000) + 1234567890) * 100000000 ) + 12345678;
|
|
||||||
expected = "1.2345678901234567890123456789012345678";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-1.2345678901234567890123456789012345678";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test max/min decimal (i.e. 38 9's)
|
|
||||||
res = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99;
|
|
||||||
expected = "9.9999999999999999999999999999999999999";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-9.9999999999999999999999999999999999999";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
|
|
||||||
// test trailing zeros
|
|
||||||
res = 123000;
|
|
||||||
expected = "0.0000000000000000000000000000000123000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
res = -res;
|
|
||||||
expected = "-0.0000000000000000000000000000000123000";
|
|
||||||
DataConvert::decimalToString(&res, ct.scale, buf, 42, ct.colDataType);
|
|
||||||
EXPECT_EQ(string(buf), expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(DataConvertTest, ConvertColumnData)
|
TEST(DataConvertTest, ConvertColumnData)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,6 @@ TEST(Decimal, compareCheck)
|
|||||||
|
|
||||||
TEST(Decimal, additionNoOverflowCheck)
|
TEST(Decimal, additionNoOverflowCheck)
|
||||||
{
|
{
|
||||||
datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
// Addition w/o overflow check
|
// Addition w/o overflow check
|
||||||
execplan::IDB_Decimal l, r, result;
|
execplan::IDB_Decimal l, r, result;
|
||||||
// same precision, same scale, both positive values
|
// same precision, same scale, both positive values
|
||||||
@ -143,8 +141,7 @@ TEST(Decimal, additionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000042000000000000000000000042", result.toString());
|
||||||
EXPECT_EQ("0.00000000000042000000000000000000000042", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, both negative values
|
// same precision, L scale > R scale, both negative values
|
||||||
l.s128Value = -42;
|
l.s128Value = -42;
|
||||||
@ -152,8 +149,7 @@ TEST(Decimal, additionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.00000000000042000000000000000000000042", result.toString());
|
||||||
EXPECT_EQ("-0.00000000000042000000000000000000000042", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, +- values
|
// same precision, L scale > R scale, +- values
|
||||||
l.s128Value = 42;
|
l.s128Value = 42;
|
||||||
@ -161,8 +157,7 @@ TEST(Decimal, additionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.00000000000041999999999999999999999958", result.toString());
|
||||||
EXPECT_EQ("-0.00000000000041999999999999999999999958", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, both 0
|
// same precision, L scale > R scale, both 0
|
||||||
l.s128Value = 0;
|
l.s128Value = 0;
|
||||||
@ -186,8 +181,7 @@ TEST(Decimal, additionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000004200000000000000000000420", result.toString());
|
||||||
EXPECT_EQ("0.00000000000004200000000000000000000420", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, both negative values
|
// same precision, L scale < R scale, both negative values
|
||||||
l.s128Value = -42;
|
l.s128Value = -42;
|
||||||
@ -195,8 +189,7 @@ TEST(Decimal, additionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.00000000000004200000000000000000000420", result.toString());
|
||||||
EXPECT_EQ("-0.00000000000004200000000000000000000420", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, +- values
|
// same precision, L scale < R scale, +- values
|
||||||
l.s128Value = 42;
|
l.s128Value = 42;
|
||||||
@ -204,8 +197,7 @@ TEST(Decimal, additionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
datatypes::Decimal::addition<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000004199999999999999999999580", result.toString());
|
||||||
EXPECT_EQ("0.00000000000004199999999999999999999580", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, both 0
|
// same precision, L scale < R scale, both 0
|
||||||
l.s128Value = 0;
|
l.s128Value = 0;
|
||||||
@ -220,8 +212,6 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
{
|
{
|
||||||
// DIVISION
|
// DIVISION
|
||||||
// same precision, same scale, both positive values
|
// same precision, same scale, both positive values
|
||||||
datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
execplan::IDB_Decimal l, r, result;
|
execplan::IDB_Decimal l, r, result;
|
||||||
|
|
||||||
l.scale = 38;
|
l.scale = 38;
|
||||||
@ -237,8 +227,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("9.7674418605", result.toString());
|
||||||
EXPECT_EQ("9.7674418605", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, same scale, both negative values
|
// same precision, same scale, both negative values
|
||||||
l.s128Value = -43;
|
l.s128Value = -43;
|
||||||
@ -246,8 +235,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("9.7674418605", result.toString());
|
||||||
EXPECT_EQ("9.7674418605", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, same scale, +- values
|
// same precision, same scale, +- values
|
||||||
l.s128Value = 2200000;
|
l.s128Value = 2200000;
|
||||||
@ -255,8 +243,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(l, r, result);
|
datatypes::Decimal::division<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-1157.8947368421", result.toString());
|
||||||
EXPECT_EQ("-1157.8947368421", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, same scale, l = 0
|
// same precision, same scale, l = 0
|
||||||
l.s128Value = 0;
|
l.s128Value = 0;
|
||||||
@ -278,8 +265,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("115789473684210526315789.4736842105", result.toString());
|
||||||
EXPECT_EQ("115789473684210526315789.4736842105", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, both negative values
|
// same precision, L scale > R scale, both negative values
|
||||||
l.s128Value = -22;
|
l.s128Value = -22;
|
||||||
@ -287,8 +273,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("86363636363636363636363.6363636364", result.toString());
|
||||||
EXPECT_EQ("86363636363636363636363.6363636364", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, +- values
|
// same precision, L scale > R scale, +- values
|
||||||
l.s128Value = 19;
|
l.s128Value = 19;
|
||||||
@ -296,8 +281,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-115789473684210526315789.4736842105", result.toString());
|
||||||
EXPECT_EQ("-115789473684210526315789.4736842105", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, R = 0
|
// same precision, L scale > R scale, R = 0
|
||||||
l.s128Value = 424242;
|
l.s128Value = 424242;
|
||||||
@ -313,8 +297,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("100000000000000000000000.0000000000", result.toString());
|
||||||
EXPECT_EQ("100000000000000000000000.0000000000", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, both MIN negative values
|
// same precision, L scale > R scale, both MIN negative values
|
||||||
utils::int128Min(l.s128Value);
|
utils::int128Min(l.s128Value);
|
||||||
@ -322,8 +305,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("100000000000000000000000.0000000000", result.toString());
|
||||||
EXPECT_EQ("100000000000000000000000.0000000000", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, both positive values
|
// same precision, L scale < R scale, both positive values
|
||||||
l.scale = 15;
|
l.scale = 15;
|
||||||
@ -339,8 +321,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000000000000001000000000000000", result.toString());
|
||||||
EXPECT_EQ("0.00000000000000000000001000000000000000", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, both negative values
|
// same precision, L scale < R scale, both negative values
|
||||||
l.s128Value = -22;
|
l.s128Value = -22;
|
||||||
@ -348,8 +329,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000000000000000863636363636364", result.toString());
|
||||||
EXPECT_EQ("0.00000000000000000000000863636363636364", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, +- values
|
// same precision, L scale < R scale, +- values
|
||||||
l.s128Value = 22;
|
l.s128Value = 22;
|
||||||
@ -357,8 +337,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.00000000000000000000000863636363636364", result.toString());
|
||||||
EXPECT_EQ("-0.00000000000000000000000863636363636364", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, R = 0
|
// same precision, L scale < R scale, R = 0
|
||||||
l.s128Value = 42;
|
l.s128Value = 42;
|
||||||
@ -375,8 +354,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000000000000001000000000000000", result.toString());
|
||||||
EXPECT_EQ("0.00000000000000000000001000000000000000", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, both MIN negative values
|
// same precision, L scale < R scale, both MIN negative values
|
||||||
utils::int128Min(l.s128Value);
|
utils::int128Min(l.s128Value);
|
||||||
@ -384,8 +362,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000000000000001000000000000000", result.toString());
|
||||||
EXPECT_EQ("0.00000000000000000000001000000000000000", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
||||||
// both positive values
|
// both positive values
|
||||||
@ -402,8 +379,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("1", result.toString());
|
||||||
EXPECT_EQ("1", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
||||||
// both negative values
|
// both negative values
|
||||||
@ -412,8 +388,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("9", result.toString());
|
||||||
EXPECT_EQ("9", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
||||||
// +- values
|
// +- values
|
||||||
@ -422,8 +397,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-9", result.toString());
|
||||||
EXPECT_EQ("-9", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
||||||
// R = 0
|
// R = 0
|
||||||
@ -441,8 +415,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0", result.toString());
|
||||||
EXPECT_EQ("0", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
// same precision, L scale < R scale, result.scale < (r.scale-l.scale)
|
||||||
// both MIN negative values
|
// both MIN negative values
|
||||||
@ -451,8 +424,7 @@ TEST(Decimal, divisionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
datatypes::Decimal::division<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0", result.toString());
|
||||||
EXPECT_EQ("0", std::string(buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void doDiv(const execplan::IDB_Decimal& l,
|
void doDiv(const execplan::IDB_Decimal& l,
|
||||||
@ -464,8 +436,6 @@ void doDiv(const execplan::IDB_Decimal& l,
|
|||||||
|
|
||||||
TEST(Decimal, divisionWithOverflowCheck)
|
TEST(Decimal, divisionWithOverflowCheck)
|
||||||
{
|
{
|
||||||
datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
// Divide min int128 by -1
|
// Divide min int128 by -1
|
||||||
execplan::IDB_Decimal l, r, result;
|
execplan::IDB_Decimal l, r, result;
|
||||||
l.scale = 0;
|
l.scale = 0;
|
||||||
@ -503,8 +473,7 @@ TEST(Decimal, divisionWithOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
EXPECT_NO_THROW(doDiv(l, r, result));
|
EXPECT_NO_THROW(doDiv(l, r, result));
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("9223372036854775809", result.toString());
|
||||||
EXPECT_EQ("9223372036854775809", std::string(buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void doAdd(const execplan::IDB_Decimal& l,
|
void doAdd(const execplan::IDB_Decimal& l,
|
||||||
@ -516,8 +485,6 @@ void doAdd(const execplan::IDB_Decimal& l,
|
|||||||
|
|
||||||
TEST(Decimal, additionWithOverflowCheck)
|
TEST(Decimal, additionWithOverflowCheck)
|
||||||
{
|
{
|
||||||
datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
// Add two max ints
|
// Add two max ints
|
||||||
execplan::IDB_Decimal l, r, result;
|
execplan::IDB_Decimal l, r, result;
|
||||||
l.scale = 0;
|
l.scale = 0;
|
||||||
@ -555,14 +522,11 @@ TEST(Decimal, additionWithOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
EXPECT_NO_THROW(doAdd(l, r, result));
|
EXPECT_NO_THROW(doAdd(l, r, result));
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-170141183460469231713240559642174554113", result.toString());
|
||||||
EXPECT_EQ("-170141183460469231713240559642174554113", std::string(buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Decimal, subtractionNoOverflowCheck)
|
TEST(Decimal, subtractionNoOverflowCheck)
|
||||||
{
|
{
|
||||||
datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
// Subtractio w/o overflow check
|
// Subtractio w/o overflow check
|
||||||
execplan::IDB_Decimal l, r, result;
|
execplan::IDB_Decimal l, r, result;
|
||||||
// same precision, same scale, both positive values
|
// same precision, same scale, both positive values
|
||||||
@ -579,8 +543,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.00000000000000000000000000000000000378", result.toString());
|
||||||
EXPECT_EQ("-0.00000000000000000000000000000000000378", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, same scale, both negative values
|
// same precision, same scale, both negative values
|
||||||
l.s128Value = -42;
|
l.s128Value = -42;
|
||||||
@ -588,8 +551,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000000000000000000000000000378", result.toString());
|
||||||
EXPECT_EQ("0.00000000000000000000000000000000000378", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, same scale, +- values
|
// same precision, same scale, +- values
|
||||||
l.s128Value = 42;
|
l.s128Value = 42;
|
||||||
@ -597,8 +559,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000000000000000000000000000462", result.toString());
|
||||||
EXPECT_EQ("0.00000000000000000000000000000000000462", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, same scale, both 0
|
// same precision, same scale, both 0
|
||||||
l.s128Value = 0;
|
l.s128Value = 0;
|
||||||
@ -623,8 +584,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.00000000000041999999999999999999999958", result.toString());
|
||||||
EXPECT_EQ("-0.00000000000041999999999999999999999958", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, both negative values
|
// same precision, L scale > R scale, both negative values
|
||||||
l.s128Value = -42;
|
l.s128Value = -42;
|
||||||
@ -632,8 +592,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000041999999999999999999999958", result.toString());
|
||||||
EXPECT_EQ("0.00000000000041999999999999999999999958", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, +- values
|
// same precision, L scale > R scale, +- values
|
||||||
l.s128Value = 42;
|
l.s128Value = 42;
|
||||||
@ -641,8 +600,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000042000000000000000000000042", result.toString());
|
||||||
EXPECT_EQ("0.00000000000042000000000000000000000042", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale > R scale, both 0
|
// same precision, L scale > R scale, both 0
|
||||||
l.s128Value = 0;
|
l.s128Value = 0;
|
||||||
@ -666,8 +624,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000004199999999999999999999580", result.toString());
|
||||||
EXPECT_EQ("0.00000000000004199999999999999999999580", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, both negative values
|
// same precision, L scale < R scale, both negative values
|
||||||
l.s128Value = -42;
|
l.s128Value = -42;
|
||||||
@ -675,8 +632,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.00000000000004199999999999999999999580", result.toString());
|
||||||
EXPECT_EQ("-0.00000000000004199999999999999999999580", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, +- values
|
// same precision, L scale < R scale, +- values
|
||||||
l.s128Value = 42;
|
l.s128Value = 42;
|
||||||
@ -684,8 +640,7 @@ TEST(Decimal, subtractionNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
datatypes::Decimal::subtraction<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.00000000000004200000000000000000000420", result.toString());
|
||||||
EXPECT_EQ("0.00000000000004200000000000000000000420", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, L scale < R scale, both 0
|
// same precision, L scale < R scale, both 0
|
||||||
l.s128Value = 0;
|
l.s128Value = 0;
|
||||||
@ -705,8 +660,6 @@ void doSubtract(const execplan::IDB_Decimal& l,
|
|||||||
|
|
||||||
TEST(Decimal, subtractionWithOverflowCheck)
|
TEST(Decimal, subtractionWithOverflowCheck)
|
||||||
{
|
{
|
||||||
datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
// Subtract a max int from a min int
|
// Subtract a max int from a min int
|
||||||
execplan::IDB_Decimal l, r, result;
|
execplan::IDB_Decimal l, r, result;
|
||||||
l.scale = 0;
|
l.scale = 0;
|
||||||
@ -744,16 +697,13 @@ TEST(Decimal, subtractionWithOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
EXPECT_NO_THROW(doSubtract(l, r, result));
|
EXPECT_NO_THROW(doSubtract(l, r, result));
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("170141183460469231713240559642174554112", result.toString());
|
||||||
EXPECT_EQ("170141183460469231713240559642174554112", std::string(buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Decimal, multiplicationNoOverflowCheck)
|
TEST(Decimal, multiplicationNoOverflowCheck)
|
||||||
{
|
{
|
||||||
// Multiplication
|
// Multiplication
|
||||||
// same precision, l.scale + r.scale = result.scale, both positive values
|
// same precision, l.scale + r.scale = result.scale, both positive values
|
||||||
datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
execplan::IDB_Decimal l, r, result;
|
execplan::IDB_Decimal l, r, result;
|
||||||
|
|
||||||
l.scale = 19;
|
l.scale = 19;
|
||||||
@ -769,8 +719,7 @@ TEST(Decimal, multiplicationNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.85070591730234615861231965839514664960", result.toString());
|
||||||
EXPECT_EQ("0.85070591730234615861231965839514664960", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale = result.scale, both negative values
|
// same precision, l.scale + r.scale = result.scale, both negative values
|
||||||
l.s128Value = -4611686018427387904;
|
l.s128Value = -4611686018427387904;
|
||||||
@ -779,8 +728,7 @@ TEST(Decimal, multiplicationNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.85070591730234615861231965839514664960", result.toString());
|
||||||
EXPECT_EQ("0.85070591730234615861231965839514664960", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale = result.scale, +- values
|
// same precision, l.scale + r.scale = result.scale, +- values
|
||||||
l.s128Value = -4611686018427387904;
|
l.s128Value = -4611686018427387904;
|
||||||
@ -788,8 +736,7 @@ TEST(Decimal, multiplicationNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(l, r, result);
|
datatypes::Decimal::multiplication<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.85070591730234615861231965839514664960", result.toString());
|
||||||
EXPECT_EQ("-0.85070591730234615861231965839514664960", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale = result.scale, l = 0
|
// same precision, l.scale + r.scale = result.scale, l = 0
|
||||||
l.s128Value = 0;
|
l.s128Value = 0;
|
||||||
@ -813,8 +760,7 @@ TEST(Decimal, multiplicationNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.66461399789245793645190353014017228800", result.toString());
|
||||||
EXPECT_EQ("0.66461399789245793645190353014017228800", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale < result.scale, both negative values
|
// same precision, l.scale + r.scale < result.scale, both negative values
|
||||||
l.s128Value = -72057594037927936;
|
l.s128Value = -72057594037927936;
|
||||||
@ -823,8 +769,7 @@ TEST(Decimal, multiplicationNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.66461399789245793645190353014017228800", result.toString());
|
||||||
EXPECT_EQ("0.66461399789245793645190353014017228800", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale < result.scale, +- values
|
// same precision, l.scale + r.scale < result.scale, +- values
|
||||||
l.s128Value = -72057594037927936;
|
l.s128Value = -72057594037927936;
|
||||||
@ -832,8 +777,7 @@ TEST(Decimal, multiplicationNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(l, r, result);
|
datatypes::Decimal::multiplication<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.66461399789245793645190353014017228800", result.toString());
|
||||||
EXPECT_EQ("-0.66461399789245793645190353014017228800", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale < result.scale, l = 0
|
// same precision, l.scale + r.scale < result.scale, l = 0
|
||||||
l.s128Value = 0;
|
l.s128Value = 0;
|
||||||
@ -859,8 +803,7 @@ TEST(Decimal, multiplicationNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.01524157875323883675019051998750190521", result.toString());
|
||||||
EXPECT_EQ("0.01524157875323883675019051998750190521", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale > result.scale, both negative values
|
// same precision, l.scale + r.scale > result.scale, both negative values
|
||||||
l.s128Value = -l.s128Value;
|
l.s128Value = -l.s128Value;
|
||||||
@ -868,16 +811,14 @@ TEST(Decimal, multiplicationNoOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
datatypes::Decimal::multiplication<int128_t, false>(r, l, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("0.01524157875323883675019051998750190521", result.toString());
|
||||||
EXPECT_EQ("0.01524157875323883675019051998750190521", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale > result.scale, +- values
|
// same precision, l.scale + r.scale > result.scale, +- values
|
||||||
r.s128Value = -r.s128Value;
|
r.s128Value = -r.s128Value;
|
||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
datatypes::Decimal::multiplication<int128_t, false>(l, r, result);
|
datatypes::Decimal::multiplication<int128_t, false>(l, r, result);
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("-0.01524157875323883675019051998750190521", result.toString());
|
||||||
EXPECT_EQ("-0.01524157875323883675019051998750190521", std::string(buf));
|
|
||||||
|
|
||||||
// same precision, l.scale + r.scale > result.scale, l = 0
|
// same precision, l.scale + r.scale > result.scale, l = 0
|
||||||
r.s128Value = 0;
|
r.s128Value = 0;
|
||||||
@ -896,8 +837,6 @@ void doMultiply(const execplan::IDB_Decimal& l,
|
|||||||
|
|
||||||
TEST(Decimal, multiplicationWithOverflowCheck)
|
TEST(Decimal, multiplicationWithOverflowCheck)
|
||||||
{
|
{
|
||||||
datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL;
|
|
||||||
char buf[42];
|
|
||||||
execplan::IDB_Decimal l, r, result;
|
execplan::IDB_Decimal l, r, result;
|
||||||
// result.scale >= l.scale + r.scale
|
// result.scale >= l.scale + r.scale
|
||||||
l.scale = 0;
|
l.scale = 0;
|
||||||
@ -940,6 +879,248 @@ TEST(Decimal, multiplicationWithOverflowCheck)
|
|||||||
result.s128Value = 0;
|
result.s128Value = 0;
|
||||||
|
|
||||||
EXPECT_NO_THROW(doMultiply(l, r, result));
|
EXPECT_NO_THROW(doMultiply(l, r, result));
|
||||||
dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType);
|
EXPECT_EQ("21267647932558653966460912964485513216", result.toString());
|
||||||
EXPECT_EQ("21267647932558653966460912964485513216", std::string(buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Decimal, DecimalToStringCheckScale0)
|
||||||
|
{
|
||||||
|
string input, expected;
|
||||||
|
int128_t res;
|
||||||
|
int precision = 38;
|
||||||
|
int scale = 0;
|
||||||
|
res = 0;
|
||||||
|
datatypes::VDecimal dec(0, scale, precision, res);
|
||||||
|
|
||||||
|
// test simple values
|
||||||
|
expected = "0";
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = 2;
|
||||||
|
expected = "2";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -2;
|
||||||
|
expected = "-2";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = 123;
|
||||||
|
expected = "123";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -123;
|
||||||
|
expected = "-123";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test max/min decimal (i.e. 38 9's)
|
||||||
|
res = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99;
|
||||||
|
expected = "99999999999999999999999999999999999999";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-99999999999999999999999999999999999999";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test trailing zeros
|
||||||
|
res = 123000;
|
||||||
|
expected = "123000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-123000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
}
|
||||||
|
TEST(Decimal, DecimalToStringCheckScale10)
|
||||||
|
{
|
||||||
|
string input, expected;
|
||||||
|
int128_t res;
|
||||||
|
int precision = 38;
|
||||||
|
int scale = 10;
|
||||||
|
res = 0;
|
||||||
|
datatypes::VDecimal dec(0, scale, precision, res);
|
||||||
|
|
||||||
|
// test simple values
|
||||||
|
expected = "0.0000000000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
res = 2;
|
||||||
|
expected = "0.0000000002";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
res = -2;
|
||||||
|
expected = "-0.0000000002";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
res = 123;
|
||||||
|
expected = "0.0000000123";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -123;
|
||||||
|
expected = "-0.0000000123";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = 12345678901;
|
||||||
|
expected = "1.2345678901";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -12345678901;
|
||||||
|
expected = "-1.2345678901";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test max/min decimal (i.e. 38 9's)
|
||||||
|
res = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99;
|
||||||
|
expected = "9999999999999999999999999999.9999999999";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-9999999999999999999999999999.9999999999";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test trailing zeros
|
||||||
|
res = 123000;
|
||||||
|
expected = "0.0000123000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-0.0000123000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test leading zeros
|
||||||
|
res = 10000000009;
|
||||||
|
expected = "1.0000000009";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-1.0000000009";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Decimal, DecimalToStringCheckScale38)
|
||||||
|
{
|
||||||
|
string input, expected;
|
||||||
|
int128_t res;
|
||||||
|
int precision = 38;
|
||||||
|
int scale = 38;
|
||||||
|
res = 0;
|
||||||
|
datatypes::VDecimal dec(0, scale, precision, res);
|
||||||
|
|
||||||
|
// test simple values
|
||||||
|
res = 0;
|
||||||
|
expected = "0.00000000000000000000000000000000000000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = 2;
|
||||||
|
expected = "0.00000000000000000000000000000000000002";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -2;
|
||||||
|
expected = "-0.00000000000000000000000000000000000002";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = 123;
|
||||||
|
expected = "0.00000000000000000000000000000000000123";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -123;
|
||||||
|
expected = "-0.00000000000000000000000000000000000123";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = ((((((int128_t)1234567890 * 10000000000) + 1234567890) * 10000000000) + 1234567890) * 100000000 ) + 12345678;
|
||||||
|
expected = "0.12345678901234567890123456789012345678";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-0.12345678901234567890123456789012345678";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test max/min decimal (i.e. 38 9's)
|
||||||
|
res = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99;
|
||||||
|
expected = "0.99999999999999999999999999999999999999";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-0.99999999999999999999999999999999999999";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test trailing zeros
|
||||||
|
res = 123000;
|
||||||
|
expected = "0.00000000000000000000000000000000123000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-0.00000000000000000000000000000000123000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Decimal, DecimalToStringCheckScale37)
|
||||||
|
{
|
||||||
|
string input, expected;
|
||||||
|
int128_t res;
|
||||||
|
int precision = 38;
|
||||||
|
int scale = 37;
|
||||||
|
res = 0;
|
||||||
|
datatypes::VDecimal dec(0, scale, precision, res);
|
||||||
|
|
||||||
|
// test simple values
|
||||||
|
res = 0;
|
||||||
|
expected = "0.0000000000000000000000000000000000000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = 2;
|
||||||
|
expected = "0.0000000000000000000000000000000000002";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -2;
|
||||||
|
expected = "-0.0000000000000000000000000000000000002";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = 123;
|
||||||
|
expected = "0.0000000000000000000000000000000000123";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -123;
|
||||||
|
expected = "-0.0000000000000000000000000000000000123";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = ((((((int128_t)1234567890 * 10000000000) + 1234567890) * 10000000000) + 1234567890) * 100000000 ) + 12345678;
|
||||||
|
expected = "1.2345678901234567890123456789012345678";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-1.2345678901234567890123456789012345678";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test max/min decimal (i.e. 38 9's)
|
||||||
|
res = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99;
|
||||||
|
expected = "9.9999999999999999999999999999999999999";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-9.9999999999999999999999999999999999999";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
|
||||||
|
// test trailing zeros
|
||||||
|
res = 123000;
|
||||||
|
expected = "0.0000000000000000000000000000000123000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
res = -res;
|
||||||
|
expected = "-0.0000000000000000000000000000000123000";
|
||||||
|
dec.setTSInt128Value(res);
|
||||||
|
EXPECT_EQ(dec.toString(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,14 +191,7 @@ const string fmt(T v)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
oss << datatypes::TSInt128(v);
|
||||||
|
|
||||||
int128_t tmp = v;
|
|
||||||
|
|
||||||
dataconvert::DataConvert::decimalToString(
|
|
||||||
&tmp, 0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL);
|
|
||||||
|
|
||||||
oss << buf;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (uflg)
|
else if (uflg)
|
||||||
@ -218,14 +211,7 @@ const string fmt(T v)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
oss << datatypes::TSInt128(v);
|
||||||
|
|
||||||
int128_t tmp = static_cast<uint128_t>(v);
|
|
||||||
|
|
||||||
dataconvert::DataConvert::decimalToString(
|
|
||||||
&tmp, 0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL);
|
|
||||||
|
|
||||||
oss << buf;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -247,14 +233,7 @@ const string fmt(T v)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
oss << datatypes::TSInt128(v);
|
||||||
|
|
||||||
int128_t tmp = v;
|
|
||||||
|
|
||||||
dataconvert::DataConvert::decimalToString(
|
|
||||||
&tmp, 0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL);
|
|
||||||
|
|
||||||
oss << buf;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1204,175 +1204,6 @@ bool stringToTimestampStruct(const string& data, TimeStamp& timeStamp, const str
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DataConvert::writeIntPart(int128_t* dec,
|
|
||||||
char* p,
|
|
||||||
const unsigned int buflen,
|
|
||||||
const uint8_t scale)
|
|
||||||
{
|
|
||||||
int128_t intPart = *dec;
|
|
||||||
int128_t high = 0, mid = 0, low = 0;
|
|
||||||
uint64_t maxUint64divisor = 10000000000000000000ULL;
|
|
||||||
|
|
||||||
if (scale)
|
|
||||||
{
|
|
||||||
// Assuming scale = [0, 56]
|
|
||||||
switch (scale / datatypes::maxPowOf10)
|
|
||||||
{
|
|
||||||
case 2: // scale = [38, 56]
|
|
||||||
intPart /= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
|
||||||
intPart /= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
|
||||||
low = intPart;
|
|
||||||
break;
|
|
||||||
case 1: // scale = [19, 37]
|
|
||||||
intPart /= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
|
||||||
intPart /= datatypes::mcs_pow_10[scale % datatypes::maxPowOf10];
|
|
||||||
low = intPart % maxUint64divisor;
|
|
||||||
mid = intPart / maxUint64divisor;
|
|
||||||
break;
|
|
||||||
case 0: // scale = [0, 18]
|
|
||||||
intPart /= datatypes::mcs_pow_10[scale % datatypes::maxPowOf10];
|
|
||||||
low = intPart % maxUint64divisor;
|
|
||||||
intPart /= maxUint64divisor;
|
|
||||||
mid = intPart % maxUint64divisor;
|
|
||||||
high = intPart / maxUint64divisor;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw QueryDataExcept("writeIntPart() bad scale", formatErr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
low = intPart % maxUint64divisor;
|
|
||||||
intPart /= maxUint64divisor;
|
|
||||||
mid = intPart % maxUint64divisor;
|
|
||||||
high = intPart / maxUint64divisor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pod[0] is low 8 bytes, pod[1] is high 8 bytes
|
|
||||||
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);
|
|
||||||
char* original_p = p;
|
|
||||||
|
|
||||||
// WIP replace sprintf with streams
|
|
||||||
if (high_pod[0] != 0)
|
|
||||||
{
|
|
||||||
p += sprintf(p, "%lu", high_pod[0]);
|
|
||||||
p += sprintf(p, "%019lu", mid_pod[0]);
|
|
||||||
p += sprintf(p, "%019lu", low_pod[0]);
|
|
||||||
}
|
|
||||||
else if (mid_pod[0] != 0)
|
|
||||||
{
|
|
||||||
p += sprintf(p, "%lu", mid_pod[0]);
|
|
||||||
p += sprintf(p, "%019lu", low_pod[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p += sprintf(p, "%lu", low_pod[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t written = p - original_p;
|
|
||||||
|
|
||||||
if (buflen <= written)
|
|
||||||
{
|
|
||||||
throw QueryDataExcept("writeIntPart() char buffer overflow.", formatErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t DataConvert::writeFractionalPart(int128_t* dec,
|
|
||||||
char* p,
|
|
||||||
const unsigned int buflen,
|
|
||||||
const uint8_t scale)
|
|
||||||
{
|
|
||||||
int128_t scaleDivisor = 1;
|
|
||||||
|
|
||||||
switch (scale / datatypes::maxPowOf10)
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
|
||||||
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
|
||||||
case 0:
|
|
||||||
scaleDivisor *= datatypes::mcs_pow_10[scale % datatypes::maxPowOf10];
|
|
||||||
}
|
|
||||||
|
|
||||||
int128_t fractionalPart = *dec % scaleDivisor;
|
|
||||||
|
|
||||||
// divide by the base until we have non-zero quotient
|
|
||||||
size_t written = 0;
|
|
||||||
scaleDivisor /= 10;
|
|
||||||
|
|
||||||
char* original_p = p;
|
|
||||||
|
|
||||||
while (scaleDivisor > 1 && fractionalPart / scaleDivisor == 0)
|
|
||||||
{
|
|
||||||
*p++ = '0';
|
|
||||||
written++;
|
|
||||||
scaleDivisor /= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
p += writeIntPart(&fractionalPart, p, buflen - written, 0);
|
|
||||||
|
|
||||||
written = p - original_p;
|
|
||||||
|
|
||||||
// this should never be true
|
|
||||||
if (written < scale)
|
|
||||||
{
|
|
||||||
for (size_t left = written; left < scale; left++)
|
|
||||||
{
|
|
||||||
*p++ = '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataConvert::decimalToString(int128_t* dec,
|
|
||||||
const uint8_t scale,
|
|
||||||
char *p,
|
|
||||||
const unsigned int buflen,
|
|
||||||
cscDataType colDataType) // colDataType is redundant
|
|
||||||
{
|
|
||||||
char* original_p = p;
|
|
||||||
size_t written = 0;
|
|
||||||
// Raise exception on NULL and EMPTY value
|
|
||||||
if (datatypes::Decimal::isWideDecimalNullValue(*dec) ||
|
|
||||||
datatypes::Decimal::isWideDecimalEmptyValue(*dec))
|
|
||||||
{
|
|
||||||
throw QueryDataExcept("toString() char buffer overflow.", formatErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*dec < static_cast<int128_t>(0))
|
|
||||||
{
|
|
||||||
*p++ = '-';
|
|
||||||
*dec *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
written = writeIntPart(dec, p, buflen, scale);
|
|
||||||
p += written;
|
|
||||||
|
|
||||||
if (scale)
|
|
||||||
{
|
|
||||||
*p++ = '.';
|
|
||||||
written = p - original_p;
|
|
||||||
p += writeFractionalPart(dec, p, buflen - written, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
written = p - original_p;
|
|
||||||
|
|
||||||
if (buflen <= written)
|
|
||||||
{
|
|
||||||
throw QueryDataExcept("toString() char buffer overflow.", formatErr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
boost::any
|
boost::any
|
||||||
DataConvert::StringToBit(const datatypes::SystemCatalog::TypeAttributesStd& colType,
|
DataConvert::StringToBit(const datatypes::SystemCatalog::TypeAttributesStd& colType,
|
||||||
const datatypes::ConvertFromStringParam &prm,
|
const datatypes::ConvertFromStringParam &prm,
|
||||||
|
@ -1037,15 +1037,6 @@ public:
|
|||||||
EXPORT static bool isColumnTimeValid( int64_t time );
|
EXPORT static bool isColumnTimeValid( int64_t time );
|
||||||
EXPORT static bool isColumnTimeStampValid( int64_t timeStamp );
|
EXPORT static bool isColumnTimeStampValid( int64_t timeStamp );
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
static void decimalToString(int128_t* dec, const uint8_t scale, char* buf, const unsigned int buflen, cscDataType colDataType);
|
|
||||||
static size_t writeIntPart(int128_t* dec, char* p, const unsigned int buflen,
|
|
||||||
const uint8_t scale);
|
|
||||||
static size_t writeFractionalPart(int128_t* dec, char* p, const unsigned int buflen,
|
|
||||||
const uint8_t scale);
|
|
||||||
|
|
||||||
static inline std::string constructRegexp(const std::string& str);
|
static inline std::string constructRegexp(const std::string& str);
|
||||||
static inline void trimWhitespace(int64_t& charData);
|
static inline void trimWhitespace(int64_t& charData);
|
||||||
static inline bool isEscapedChar(char c)
|
static inline bool isEscapedChar(char c)
|
||||||
@ -1298,96 +1289,6 @@ inline void DataConvert::timeToString1( long long timevalue, char* buf, unsigned
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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, cscDataType colDataType)
|
|
||||||
{
|
|
||||||
// Need to convert a string with a binary unsigned number in it to a 64-bit signed int
|
|
||||||
|
|
||||||
// MySQL seems to round off values unless we use the string store method. Groan.
|
|
||||||
// Taken from ha_mcs_impl.cpp
|
|
||||||
|
|
||||||
//biggest Calpont supports is DECIMAL(18,x), or 18 total digits+dp+sign for column
|
|
||||||
// Need 19 digits maxium to hold a sum result of 18 digits decimal column.
|
|
||||||
if (isUnsigned(colDataType))
|
|
||||||
{
|
|
||||||
#ifndef __LP64__
|
|
||||||
snprintf(buf, buflen, "%llu", static_cast<uint64_t>(int_val));
|
|
||||||
#else
|
|
||||||
snprintf(buf, buflen, "%lu", static_cast<uint64_t>(int_val));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifndef __LP64__
|
|
||||||
snprintf(buf, buflen, "%lld", int_val);
|
|
||||||
#else
|
|
||||||
snprintf(buf, buflen, "%ld", int_val);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scale == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//we want to move the last dt_scale chars right by one spot to insert the dp
|
|
||||||
//we want to move the trailing null as well, so it's really dt_scale+1 chars
|
|
||||||
size_t l1 = strlen(buf);
|
|
||||||
char* ptr = &buf[0];
|
|
||||||
|
|
||||||
if (int_val < 0)
|
|
||||||
{
|
|
||||||
ptr++;
|
|
||||||
idbassert(l1 >= 2);
|
|
||||||
l1--;
|
|
||||||
}
|
|
||||||
|
|
||||||
//need to make sure we have enough leading zeros for this to work...
|
|
||||||
//at this point scale is always > 0
|
|
||||||
size_t l2 = 1;
|
|
||||||
|
|
||||||
if ((unsigned)scale > l1)
|
|
||||||
{
|
|
||||||
const char* zeros = "00000000000000000000"; //20 0's
|
|
||||||
size_t diff = 0;
|
|
||||||
|
|
||||||
if (int_val != 0)
|
|
||||||
diff = scale - l1; //this will always be > 0
|
|
||||||
else
|
|
||||||
diff = scale;
|
|
||||||
|
|
||||||
memmove((ptr + diff), ptr, l1 + 1); //also move null
|
|
||||||
memcpy(ptr, zeros, diff);
|
|
||||||
|
|
||||||
if (int_val != 0)
|
|
||||||
l1 = 0;
|
|
||||||
else
|
|
||||||
l1 = 1;
|
|
||||||
}
|
|
||||||
else if ((unsigned)scale == l1)
|
|
||||||
{
|
|
||||||
l1 = 0;
|
|
||||||
l2 = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l1 -= scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
memmove((ptr + l1 + l2), (ptr + l1), scale + 1); //also move null
|
|
||||||
|
|
||||||
if (l2 == 2)
|
|
||||||
*(ptr + l1++) = '0';
|
|
||||||
|
|
||||||
*(ptr + l1) = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void DataConvert::trimWhitespace(int64_t& charData)
|
inline void DataConvert::trimWhitespace(int64_t& charData)
|
||||||
{
|
{
|
||||||
// Trims whitespace characters off non-dict character data
|
// Trims whitespace characters off non-dict character data
|
||||||
|
@ -542,15 +542,10 @@ string Func_cast_char::getStrVal(Row& row,
|
|||||||
{
|
{
|
||||||
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
|
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
|
||||||
|
|
||||||
char buf[80];
|
|
||||||
|
|
||||||
if (parm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
if (parm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
dataconvert::DataConvert::decimalToString( &d.s128Value, d.scale, buf, 80, parm[0]->data()->resultType().colDataType);
|
return d.toString(true).substr(0, length);
|
||||||
else
|
else
|
||||||
dataconvert::DataConvert::decimalToString( d.value, d.scale, buf, 80, parm[0]->data()->resultType().colDataType);
|
return d.toString().substr(0, length);
|
||||||
|
|
||||||
string sbuf = buf;
|
|
||||||
return sbuf.substr(0, length);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1231,17 +1226,10 @@ string Func_cast_decimal::getStrVal(Row& row,
|
|||||||
parm,
|
parm,
|
||||||
isNull,
|
isNull,
|
||||||
operationColType);
|
operationColType);
|
||||||
|
if (operationColType.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
char buf[80];
|
return decimal.toString(true);
|
||||||
|
|
||||||
if (decimal.precision > datatypes::INT64MAXPRECISION)
|
|
||||||
dataconvert::DataConvert::decimalToString( &decimal.s128Value, decimal.scale, buf, 80, operationColType.colDataType);
|
|
||||||
else
|
else
|
||||||
dataconvert::DataConvert::decimalToString( decimal.value, decimal.scale, buf, 80, operationColType.colDataType);
|
return decimal.toString();
|
||||||
|
|
||||||
string value = buf;
|
|
||||||
return value;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -515,11 +515,11 @@ string Func_ceil::getStrVal(Row& row,
|
|||||||
|
|
||||||
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString(&d.s128Value, d.scale, tmp, 511, op_ct.colDataType);
|
return d.toString(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString(d.value, d.scale, tmp, 511, op_ct.colDataType);
|
return d.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isUnsigned(op_ct.colDataType))
|
else if (isUnsigned(op_ct.colDataType))
|
||||||
|
@ -436,11 +436,11 @@ string Func_floor::getStrVal(Row& row,
|
|||||||
|
|
||||||
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString(&d.s128Value, d.scale, tmp, 511, op_ct.colDataType);
|
return d.toString(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString(d.value, d.scale, tmp, 511, op_ct.colDataType);
|
return d.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isUnsigned(op_ct.colDataType))
|
else if (isUnsigned(op_ct.colDataType))
|
||||||
|
@ -1849,8 +1849,7 @@ string Func_format::getStrVal(Row& row,
|
|||||||
{
|
{
|
||||||
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
|
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
|
||||||
|
|
||||||
char buf[80];
|
// This is an unacceptable way of doing rounding
|
||||||
|
|
||||||
//perform rouding if needed
|
//perform rouding if needed
|
||||||
if ( scale < 0 )
|
if ( scale < 0 )
|
||||||
scale = 0;
|
scale = 0;
|
||||||
@ -1912,9 +1911,7 @@ string Func_format::getStrVal(Row& row,
|
|||||||
|
|
||||||
decimal.s128Value = x;
|
decimal.s128Value = x;
|
||||||
}
|
}
|
||||||
|
value = decimal.toString(true);
|
||||||
dataconvert::DataConvert::decimalToString(&decimal.s128Value,
|
|
||||||
decimal.scale, buf, 80, parm[0]->data()->resultType().colDataType);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1973,12 +1970,8 @@ string Func_format::getStrVal(Row& row,
|
|||||||
|
|
||||||
decimal.value = x;
|
decimal.value = x;
|
||||||
}
|
}
|
||||||
|
value = decimal.toString();
|
||||||
dataconvert::DataConvert::decimalToString( decimal.value,
|
|
||||||
decimal.scale, buf, 80, parm[0]->data()->resultType().colDataType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value = buf;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -116,18 +116,15 @@ inline bool getBool(rowgroup::Row& row,
|
|||||||
{
|
{
|
||||||
IDB_Decimal d = pm[0]->data()->getDecimalVal(row, isNull);
|
IDB_Decimal d = pm[0]->data()->getDecimalVal(row, isNull);
|
||||||
|
|
||||||
char buf[80];
|
|
||||||
|
|
||||||
if (pm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
if (pm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString(&d.s128Value, d.scale, buf, 80, pm[0]->data()->resultType().colDataType);
|
expr = d.toString(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString(d.value, d.scale, buf, 80, pm[0]->data()->resultType().colDataType);
|
expr = d.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
expr = buf;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,18 +195,14 @@ inline bool getBool(rowgroup::Row& row,
|
|||||||
{
|
{
|
||||||
IDB_Decimal d = pm[1]->data()->getDecimalVal(row, isNull);
|
IDB_Decimal d = pm[1]->data()->getDecimalVal(row, isNull);
|
||||||
|
|
||||||
char buf[80];
|
|
||||||
|
|
||||||
if (pm[1]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
if (pm[1]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString(&d.s128Value, d.scale, buf, 80, pm[1]->data()->resultType().colDataType);
|
pattern = d.toString(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataconvert::DataConvert::decimalToString(d.value, d.scale, buf, 80, pm[1]->data()->resultType().colDataType);
|
pattern = d.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
pattern = buf;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,13 +721,9 @@ string Func_round::getStrVal(Row& row,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!op_ct.isWideDecimalType())
|
if (!op_ct.isWideDecimalType())
|
||||||
return dataconvert::DataConvert::decimalToString(x.value, x.scale, op_ct.colDataType);
|
return x.toString();
|
||||||
else
|
else
|
||||||
{
|
return x.toString(true);
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
|
||||||
dataconvert::DataConvert::decimalToString( &x.s128Value, x.scale, buf, (uint8_t) sizeof(buf), op_ct.colDataType);
|
|
||||||
return string(buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -740,13 +740,9 @@ string Func_truncate::getStrVal(Row& row,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!op_ct.isWideDecimalType())
|
if (!op_ct.isWideDecimalType())
|
||||||
return dataconvert::DataConvert::decimalToString(x.value, x.scale, op_ct.colDataType);
|
return x.toString();
|
||||||
else
|
else
|
||||||
{
|
return x.toString(true);
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
|
||||||
dataconvert::DataConvert::decimalToString( &x.s128Value, x.scale, buf, (uint8_t) sizeof(buf), op_ct.colDataType);
|
|
||||||
return string(buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -785,10 +785,6 @@ string longDoubleToString(long double ld)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@bug6146, remove duplicate function with incorrect impl. Use the DataConvert::decimalToString()
|
|
||||||
//string decimalToString( execplan::IDB_Decimal x, int p )
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t dateAdd( uint64_t time, const std::string& expr, execplan::IntervalColumn::interval_type unit, bool dateType, execplan::OpType funcType );
|
uint64_t dateAdd( uint64_t time, const std::string& expr, execplan::IntervalColumn::interval_type unit, bool dateType, execplan::OpType funcType );
|
||||||
const std::string IDB_date_format(const dataconvert::DateTime&, const std::string&);
|
const std::string IDB_date_format(const dataconvert::DateTime&, const std::string&);
|
||||||
const std::string timediff(int64_t, int64_t, bool isDateTime = true);
|
const std::string timediff(int64_t, int64_t, bool isDateTime = true);
|
||||||
|
@ -640,12 +640,11 @@ string Row::toString() const
|
|||||||
case CalpontSystemCatalog::UDECIMAL:
|
case CalpontSystemCatalog::UDECIMAL:
|
||||||
if (colWidths[i] == datatypes::MAXDECIMALWIDTH)
|
if (colWidths[i] == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
unsigned int buflen = datatypes::Decimal::MAXLENGTH16BYTES;
|
datatypes::VDecimal dec(0,
|
||||||
char *buf = (char*)alloca(buflen);
|
scale[i],
|
||||||
// empty the buffer
|
precision[i],
|
||||||
dataconvert::DataConvert::decimalToString(getBinaryField<int128_t>(i),
|
getBinaryField<int128_t>(i));
|
||||||
scale[i], buf, buflen, types[i]);
|
os << dec << " ";
|
||||||
os << buf << " ";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//fallthrough
|
//fallthrough
|
||||||
|
@ -300,7 +300,6 @@ void BRMReporter::sendCPToFile( )
|
|||||||
{
|
{
|
||||||
if (fCPInfo.size() > 0)
|
if (fCPInfo.size() > 0)
|
||||||
{
|
{
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Writing " << fCPInfo.size() << " CP updates for table " <<
|
oss << "Writing " << fCPInfo.size() << " CP updates for table " <<
|
||||||
fTableName << " to report file " << fRptFileName;
|
fTableName << " to report file " << fRptFileName;
|
||||||
@ -319,14 +318,9 @@ void BRMReporter::sendCPToFile( )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string bigMin, bigMax;
|
datatypes::TSInt128 bigMin(&fCPInfo[i].bigMin);
|
||||||
|
datatypes::TSInt128 bigMax(&fCPInfo[i].bigMax);
|
||||||
dataconvert::DataConvert::decimalToString(&fCPInfo[i].bigMin, 0, buf, (uint8_t) sizeof(buf), fCPInfo[i].type);
|
|
||||||
bigMin = buf;
|
|
||||||
|
|
||||||
dataconvert::DataConvert::decimalToString(&fCPInfo[i].bigMax, 0, buf, (uint8_t) sizeof(buf), fCPInfo[i].type);
|
|
||||||
bigMax = buf;
|
|
||||||
|
|
||||||
fRptFile << "CP: " << fCPInfo[i].startLbid << ' ' <<
|
fRptFile << "CP: " << fCPInfo[i].startLbid << ' ' <<
|
||||||
bigMax << ' ' <<
|
bigMax << ' ' <<
|
||||||
bigMin << ' ' <<
|
bigMin << ' ' <<
|
||||||
|
@ -2994,16 +2994,11 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs,
|
|||||||
{
|
{
|
||||||
if (fetchColColwidths[fetchColPos] == datatypes::MAXDECIMALWIDTH)
|
if (fetchColColwidths[fetchColPos] == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
int128_t* dec;
|
datatypes::VDecimal dec(0,
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
fetchColScales[fetchColPos],
|
||||||
dec = row.getBinaryField<int128_t>(fetchColPos);
|
rowGroups[txnId]->getPrecision()[fetchColPos],
|
||||||
|
row.getBinaryField<int128_t>(fetchColPos));
|
||||||
dataconvert::DataConvert::decimalToString(dec,
|
value = dec.toString(true);
|
||||||
(unsigned)fetchColScales[fetchColPos], buf,
|
|
||||||
(uint8_t) sizeof(buf), fetchColTypes[fetchColPos]);
|
|
||||||
|
|
||||||
value.assign(buf);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3042,12 +3037,10 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const int ctmp_size = 65 + 1 + 1 + 1;
|
datatypes::VDecimal dec(intColVal,
|
||||||
char ctmp[ctmp_size] = {0};
|
fetchColScales[fetchColPos],
|
||||||
DataConvert::decimalToString(
|
rowGroups[txnId]->getPrecision()[fetchColPos]);
|
||||||
intColVal, fetchColScales[fetchColPos],
|
value = dec.toString();
|
||||||
ctmp, ctmp_size, fetchColTypes[fetchColPos]);
|
|
||||||
value = ctmp; // null termination by decimalToString
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3356,16 +3349,11 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs,
|
|||||||
{
|
{
|
||||||
if (fetchColColwidths[fetchColPos] == datatypes::MAXDECIMALWIDTH)
|
if (fetchColColwidths[fetchColPos] == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
int128_t* dec;
|
datatypes::VDecimal dec(0,
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
fetchColScales[fetchColPos],
|
||||||
dec = row.getBinaryField<int128_t>(fetchColPos);
|
rowGroups[txnId]->getPrecision()[fetchColPos],
|
||||||
|
row.getBinaryField<int128_t>(fetchColPos));
|
||||||
dataconvert::DataConvert::decimalToString(dec,
|
value = dec.toString(true);
|
||||||
(unsigned)fetchColScales[fetchColPos], buf,
|
|
||||||
(uint8_t) sizeof(buf), fetchColTypes[fetchColPos]);
|
|
||||||
|
|
||||||
value = buf;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3405,12 +3393,10 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const int ctmp_size = 65 + 1 + 1 + 1;
|
datatypes::VDecimal dec(intColVal,
|
||||||
char ctmp[ctmp_size] = {0};
|
fetchColScales[fetchColPos],
|
||||||
DataConvert::decimalToString(
|
rowGroups[txnId]->getPrecision()[fetchColPos]);
|
||||||
intColVal, fetchColScales[fetchColPos],
|
value = dec.toString();
|
||||||
ctmp, ctmp_size, fetchColTypes[fetchColPos]);
|
|
||||||
value = ctmp; // null termination by decimalToString
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3896,11 +3896,8 @@ void WriteEngineWrapper::printInputValue(const ColStructList& colStructList,
|
|||||||
curStr = boost::lexical_cast<string>(boost::any_cast<long long>(curTuple.data));
|
curStr = boost::lexical_cast<string>(boost::any_cast<long long>(curTuple.data));
|
||||||
else if (curTuple.data.type() == typeid(int128_t))
|
else if (curTuple.data.type() == typeid(int128_t))
|
||||||
{
|
{
|
||||||
// WIP replace with a single call
|
datatypes::TSInt128 val(boost::any_cast<int128_t>(curTuple.data));
|
||||||
char buf[datatypes::Decimal::MAXLENGTH16BYTES];
|
curStr = val.toString();
|
||||||
int128_t val = boost::any_cast<int128_t>(curTuple.data);
|
|
||||||
dataconvert::DataConvert::decimalToString(&val, 0, buf, (uint8_t) sizeof(buf), curColStruct.colDataType);
|
|
||||||
curStr.assign(buf);
|
|
||||||
}
|
}
|
||||||
else if (curTuple.data.type() == typeid(double))
|
else if (curTuple.data.type() == typeid(double))
|
||||||
curStr = boost::lexical_cast<string>(boost::any_cast<double>(curTuple.data));
|
curStr = boost::lexical_cast<string>(boost::any_cast<double>(curTuple.data));
|
||||||
|
Reference in New Issue
Block a user