1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-29 08:21:15 +03:00

MCOL-641 Addition now works for DECIMAL columns with precision > 18.

This commit is contained in:
drrtuy
2020-01-26 11:07:45 +03:00
committed by Roman Nozdrin
parent 54c152d6c8
commit 98213c0094
11 changed files with 175 additions and 14 deletions

View File

@ -43,6 +43,7 @@ namespace execplan
class ArithmeticOperator : public Operator
{
using cscType = execplan::CalpontSystemCatalog::ColType;
public:
ArithmeticOperator();
@ -200,6 +201,7 @@ private:
template <typename result_t>
inline result_t execute(result_t op1, result_t op2, bool& isNull);
inline void execute(IDB_Decimal& result, IDB_Decimal op1, IDB_Decimal op2, bool& isNull);
inline void execute(IDB_Decimal& result, IDB_Decimal op1, IDB_Decimal op2, bool& isNull, cscType& resultCscType);
std::string fTimeZone;
};
@ -236,12 +238,11 @@ inline void ArithmeticOperator::evaluate(rowgroup::Row& row, bool& isNull, Parse
case execplan::CalpontSystemCatalog::LONGDOUBLE:
fResult.longDoubleVal = execute(lop->getLongDoubleVal(row, isNull), rop->getLongDoubleVal(row, isNull), isNull);
break;
// WIP MCOL-641
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
execute (fResult.decimalVal, lop->getDecimalVal(row, isNull), rop->getDecimalVal(row, isNull), isNull);
execute(fResult.decimalVal, lop->getDecimalVal(row, isNull), rop->getDecimalVal(row, isNull), isNull, fOperationType);
break;
default:
{
std::ostringstream oss;
@ -282,11 +283,21 @@ inline result_t ArithmeticOperator::execute(result_t op1, result_t op2, bool& is
}
}
inline void ArithmeticOperator::execute(IDB_Decimal& result, IDB_Decimal op1, IDB_Decimal op2, bool& isNull)
inline void ArithmeticOperator::execute(IDB_Decimal& result, IDB_Decimal op1, IDB_Decimal op2, bool& isNull, cscType& resultCscType)
{
switch (fOp)
{
case OP_ADD:
if (resultCscType.precision > 18)
{
// WIP make this a separate function w and w/o overflow check
if (resultCscType.colDataType == execplan::CalpontSystemCatalog::DECIMAL)
result.__v.__s128 = op1.__v.__s128 + op2.__v.__s128;
else
result.__v.__u128 = op1.__v.__u128 + op2.__v.__u128;
break;
}
if (result.scale == op1.scale && result.scale == op2.scale)
{
result.value = op1.value + op2.value;

View File

@ -49,6 +49,7 @@ ReturnedColumn::ReturnedColumn(): fReturnAll (false),
fColPosition(-1),
fHasAggregate(false),
fInputIndex(-1),
fInputOffset(-1),
fOutputIndex(-1),
fExpressionId ((uint32_t) - 1)
{
@ -69,6 +70,7 @@ ReturnedColumn::ReturnedColumn(const string& sql):
fHasAggregate(false),
fData(sql),
fInputIndex(-1),
fInputOffset(-1),
fOutputIndex(-1),
fExpressionId ((uint32_t) - 1)
{
@ -88,6 +90,7 @@ ReturnedColumn::ReturnedColumn(const uint32_t sessionID, const bool returnAll):
fColPosition(-1),
fHasAggregate(false),
fInputIndex(-1),
fInputOffset(-1),
fOutputIndex(-1),
fExpressionId ((uint32_t) - 1)
{
@ -109,6 +112,7 @@ ReturnedColumn::ReturnedColumn(const ReturnedColumn& rhs, const uint32_t session
fHasAggregate(rhs.fHasAggregate),
fData(rhs.fData),
fInputIndex(rhs.fInputIndex),
fInputOffset(rhs.fInputOffset),
fOutputIndex(rhs.fOutputIndex),
fExpressionId (rhs.fExpressionId)
{
@ -141,6 +145,7 @@ void ReturnedColumn::serialize(messageqcpp::ByteStream& b) const
b << (uint64_t)fColSource;
b << (int64_t)fColPosition;
b << (uint32_t)fInputIndex;
b << (uint32_t)fInputOffset;
b << (uint32_t)fOutputIndex;
b << (int32_t)fSequence;
b << (uint8_t)fReturnAll;
@ -163,6 +168,7 @@ void ReturnedColumn::unserialize(messageqcpp::ByteStream& b)
b >> (uint64_t&)fColSource;
b >> (int64_t&)fColPosition;
b >> (uint32_t&)fInputIndex;
b >> (uint32_t&)fInputOffset;
b >> (uint32_t&)fOutputIndex;
b >> (int32_t&)fSequence;
b >> (uint8_t&)fReturnAll;

View File

@ -374,6 +374,7 @@ public:
protected:
std::string fErrMsg; /// error occured in evaluation
uint32_t fInputIndex; /// index to the input rowgroup
uint32_t fInputOffset; /// index to the input rowgroup
uint32_t fOutputIndex; /// index to the output rowgroup
uint32_t fExpressionId; /// unique id for this expression
};

View File

@ -51,6 +51,7 @@ using namespace joblist;
#include "aggregatecolumn.h"
#include "constantfilter.h"
#include "../../utils/windowfunction/windowfunction.h"
#include "utils/common/branchpred.h"
namespace execplan
{
@ -482,6 +483,7 @@ void SimpleColumn::setDerivedTable()
// @todo make aggregate filter to having clause. not optimize it for now
if (fDerivedRefCol &&
// WIP replace with typeid()
(dynamic_cast<AggregateColumn*>(fDerivedRefCol) ||
dynamic_cast<WindowFunctionColumn*>(fDerivedRefCol)))
fDerivedTable = "";
@ -500,6 +502,12 @@ bool SimpleColumn::singleTable(CalpontSystemCatalog::TableAliasName& tan)
// @todo move to inline
void SimpleColumn::evaluate(Row& row, bool& isNull)
{
// WIP Move this block into an appropriate place
if (UNLIKELY(fInputOffset == -1))
{
fInputOffset = row.getOffset(fInputIndex);
}
bool isNull2 = row.isNullValue(fInputIndex);
if (isNull2)
@ -627,7 +635,16 @@ void SimpleColumn::evaluate(Row& row, bool& isNull)
{
case 16:
{
fResult.decimalVal.value = row.getIntField<16>(fInputIndex);
if (fResultType.colDataType == CalpontSystemCatalog::UDECIMAL)
{
fResult.decimalVal.__v.__u128 =
*row.getBinaryField_offset<decltype(fResult.decimalVal.__v.__u128)>(fInputOffset);
}
else
{
fResult.decimalVal.__v.__s128 =
*row.getBinaryField_offset<decltype(fResult.decimalVal.__v.__s128)>(fInputOffset);
}
fResult.decimalVal.scale = (unsigned)fResultType.scale;
break;
}

View File

@ -36,6 +36,7 @@
#include "exceptclasses.h"
#include "dataconvert.h"
using int128_t = __int128;
using uint128_t = unsigned __int128;
namespace messageqcpp
@ -63,11 +64,17 @@ typedef execplan::CalpontSystemCatalog::ColType Type;
*/
struct IDB_Decimal
{
IDB_Decimal(): val(0), value(0), scale(0), precision(0) {}
IDB_Decimal(): value(0), scale(0), precision(0)
{
__v.__s128 = 0;
}
IDB_Decimal(int64_t val, int8_t s, uint8_t p) :
value (val),
scale(s),
precision(p) {}
precision(p)
{
__v.__s128 = 0;
}
int decimalComp(const IDB_Decimal& d) const
{
@ -151,7 +158,11 @@ struct IDB_Decimal
return (decimalComp(rhs) != 0);
}
uint128_t val;
union {
uint128_t __u128;
int128_t __s128;
int64_t __s64[2];
} __v;
int64_t value;
int8_t scale; // 0~38
uint8_t precision; // 1~38