You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
MCOL-641 Addition now works for DECIMAL columns with precision > 18.
This commit is contained in:
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user