You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-641 Initial version of Math operations for wide decimal.
This commit is contained in:
@ -18,7 +18,6 @@
|
||||
#ifndef UTILS_COLWIDTH_H
|
||||
#define UTILS_COLWIDTH_H
|
||||
|
||||
#include "calpontsystemcatalog.h"
|
||||
#include "branchpred.h"
|
||||
|
||||
namespace utils
|
||||
@ -36,13 +35,6 @@ namespace utils
|
||||
return width <= MAXLEGACYWIDTH;
|
||||
}
|
||||
|
||||
inline bool isWideDecimalType(const execplan::CalpontSystemCatalog::ColType& ct)
|
||||
{
|
||||
return ((ct.colDataType == execplan::CalpontSystemCatalog::DECIMAL ||
|
||||
ct.colDataType == execplan::CalpontSystemCatalog::UDECIMAL) &&
|
||||
ct.colWidth == MAXCOLUMNWIDTH);
|
||||
}
|
||||
|
||||
/** @brief Map a DECIMAL precision to data width in bytes */
|
||||
inline uint8_t widthByPrecision(unsigned p)
|
||||
{
|
||||
|
@ -80,9 +80,7 @@ namespace utils
|
||||
|
||||
inline void int128Min(int128_t& val)
|
||||
{
|
||||
uint64_t* ptr = reinterpret_cast<uint64_t*>(&val);
|
||||
ptr[0] = 0;
|
||||
ptr[1] = 0x8000000000000000;
|
||||
val = int128_t(0x8000000000000000LL) << 64;
|
||||
}
|
||||
|
||||
inline void uint128Max(uint128_t& val)
|
||||
|
@ -102,30 +102,6 @@ const string columnstore_big_precision[20] =
|
||||
"99999999999999999999999999999999999999"
|
||||
};
|
||||
|
||||
const uint64_t columnstore_pow_10[20] =
|
||||
{
|
||||
1ULL,
|
||||
10ULL,
|
||||
100ULL,
|
||||
1000ULL,
|
||||
10000ULL,
|
||||
100000ULL,
|
||||
1000000ULL,
|
||||
10000000ULL,
|
||||
100000000ULL,
|
||||
1000000000ULL,
|
||||
10000000000ULL,
|
||||
100000000000ULL,
|
||||
1000000000000ULL,
|
||||
10000000000000ULL,
|
||||
100000000000000ULL,
|
||||
1000000000000000ULL,
|
||||
10000000000000000ULL,
|
||||
100000000000000000ULL,
|
||||
1000000000000000000ULL,
|
||||
10000000000000000000ULL
|
||||
};
|
||||
|
||||
template <class T>
|
||||
bool from_string(T& t, const std::string& s, std::ios_base & (*f)(std::ios_base&))
|
||||
{
|
||||
@ -1257,33 +1233,30 @@ size_t DataConvert::writeIntPart(int128_t* dec,
|
||||
{
|
||||
int128_t intPart = *dec;
|
||||
int128_t high = 0, mid = 0, low = 0;
|
||||
uint64_t div = 10000000000000000000ULL;
|
||||
uint64_t maxUint64divisor = 10000000000000000000ULL;
|
||||
|
||||
if (scale)
|
||||
{
|
||||
const uint8_t maxPowOf10 =
|
||||
(sizeof(columnstore_pow_10) / sizeof(columnstore_pow_10[0])) - 1;
|
||||
|
||||
// Assuming scale = [0, 56]
|
||||
switch (scale / maxPowOf10)
|
||||
switch (scale / datatypes::maxPowOf10)
|
||||
{
|
||||
case 2: // scale = [38, 56]
|
||||
intPart /= columnstore_pow_10[maxPowOf10];
|
||||
intPart /= columnstore_pow_10[maxPowOf10];
|
||||
intPart /= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||
intPart /= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||
low = intPart;
|
||||
break;
|
||||
case 1: // scale = [19, 37]
|
||||
intPart /= columnstore_pow_10[maxPowOf10];
|
||||
intPart /= columnstore_pow_10[scale % maxPowOf10];
|
||||
low = intPart % div;
|
||||
mid = intPart / div;
|
||||
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 /= columnstore_pow_10[scale % maxPowOf10];
|
||||
low = intPart % div;
|
||||
intPart /= div;
|
||||
mid = intPart % div;
|
||||
high = intPart / div;
|
||||
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);
|
||||
@ -1291,10 +1264,10 @@ size_t DataConvert::writeIntPart(int128_t* dec,
|
||||
}
|
||||
else
|
||||
{
|
||||
low = intPart % div;
|
||||
intPart /= div;
|
||||
mid = intPart % div;
|
||||
high = intPart / div;
|
||||
low = intPart % maxUint64divisor;
|
||||
intPart /= maxUint64divisor;
|
||||
mid = intPart % maxUint64divisor;
|
||||
high = intPart / maxUint64divisor;
|
||||
}
|
||||
|
||||
// pod[0] is low 8 bytes, pod[1] is high 8 bytes
|
||||
@ -1337,19 +1310,16 @@ size_t DataConvert::writeFractionalPart(int128_t* dec,
|
||||
{
|
||||
int128_t scaleDivisor = 1;
|
||||
|
||||
const uint8_t maxPowOf10 =
|
||||
(sizeof(columnstore_pow_10) / sizeof(columnstore_pow_10[0])) - 1;
|
||||
|
||||
switch (scale / maxPowOf10)
|
||||
switch (scale / datatypes::maxPowOf10)
|
||||
{
|
||||
case 2:
|
||||
scaleDivisor *= columnstore_pow_10[maxPowOf10];
|
||||
scaleDivisor *= columnstore_pow_10[maxPowOf10];
|
||||
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||
break;
|
||||
case 1:
|
||||
scaleDivisor *= columnstore_pow_10[maxPowOf10];
|
||||
scaleDivisor *= datatypes::mcs_pow_10[datatypes::maxPowOf10];
|
||||
case 0:
|
||||
scaleDivisor *= columnstore_pow_10[scale % maxPowOf10];
|
||||
scaleDivisor *= datatypes::mcs_pow_10[scale % datatypes::maxPowOf10];
|
||||
}
|
||||
|
||||
int128_t fractionalPart = *dec % scaleDivisor;
|
||||
|
@ -42,6 +42,8 @@ using namespace joblist;
|
||||
#include "../udfsdk/udfsdk.h"
|
||||
#endif
|
||||
|
||||
#include "mcs_decimal.h"
|
||||
|
||||
namespace funcexp
|
||||
{
|
||||
|
||||
@ -471,13 +473,22 @@ void FuncExp::evaluate(rowgroup::Row& row, std::vector<execplan::SRCP>& expressi
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
IDB_Decimal val = expression[i]->getDecimalVal(row, isNull);
|
||||
|
||||
// WIP check for null and overflow here.
|
||||
if (expression[i]->resultType().colWidth == 16)
|
||||
if (expression[i]->resultType().colWidth
|
||||
== datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
row.setBinaryField_offset(&val.s128Value,
|
||||
expression[i]->resultType().colWidth,
|
||||
row.getOffset(expression[i]->outputIndex()));
|
||||
if (isNull)
|
||||
{
|
||||
row.setBinaryField_offset(
|
||||
const_cast<int128_t*>(&datatypes::Decimal128Null),
|
||||
expression[i]->resultType().colWidth,
|
||||
row.getOffset(expression[i]->outputIndex()));
|
||||
}
|
||||
else
|
||||
{
|
||||
row.setBinaryField_offset(&val.s128Value,
|
||||
expression[i]->resultType().colWidth,
|
||||
row.getOffset(expression[i]->outputIndex()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -187,6 +187,16 @@ public:
|
||||
std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
/** @brief Exception for F&E framework to throw on op overflow
|
||||
* Invalid Operation Exception
|
||||
*/
|
||||
class OperationOverflowExcept : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
/** Takes a character string describing the error. */
|
||||
OperationOverflowExcept(const std::string& msg) :
|
||||
std::runtime_error(msg) { }
|
||||
};
|
||||
/** @brief specific error exception class for getSysData in Calpontsystemcatalog.
|
||||
* @bug 2574
|
||||
*
|
||||
|
@ -1629,7 +1629,6 @@ void applyMapping(const int* mapping, const Row& in, Row* out)
|
||||
out->setVarBinaryField(in.getVarBinaryField(i), in.getVarBinaryLength(i), mapping[i]);
|
||||
else if (UNLIKELY(in.isLongString(i)))
|
||||
out->setStringField(in.getStringPointer(i), in.getStringLength(i), mapping[i]);
|
||||
//out->setStringField(in.getStringField(i), mapping[i]);
|
||||
else if (UNLIKELY(in.isShortString(i)))
|
||||
out->setUintField(in.getUintField(i), mapping[i]);
|
||||
else if (UNLIKELY(in.getColTypes()[i] == execplan::CalpontSystemCatalog::LONGDOUBLE))
|
||||
|
Reference in New Issue
Block a user