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-4188 Regression fixes for MCOL-641.
1. Add wide decimal support to AggregateColumn::evaluate and TreeNode::getDecimalVal(). 2. Use the pm aggregate attributes to determine um aggregate attributes in TupleAggregateStep::prep2PhasesAggregate.
This commit is contained in:
@ -230,6 +230,16 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The method returns true if the column precision
|
||||||
|
belongs to a wide decimal range.
|
||||||
|
*/
|
||||||
|
inline bool isWideDecimalPrecision() const
|
||||||
|
{
|
||||||
|
return ((precision > INT64MAXPRECISION) &&
|
||||||
|
(precision <= INT128MAXPRECISION));
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeHolderStd: public TypeAttributesStd
|
class TypeHolderStd: public TypeAttributesStd
|
||||||
|
@ -172,6 +172,8 @@ class Decimal: public TSInt128
|
|||||||
public:
|
public:
|
||||||
static constexpr uint8_t MAXLENGTH16BYTES = TSInt128::maxLength();
|
static constexpr uint8_t MAXLENGTH16BYTES = TSInt128::maxLength();
|
||||||
static constexpr uint8_t MAXLENGTH8BYTES = 23;
|
static constexpr uint8_t MAXLENGTH8BYTES = 23;
|
||||||
|
static constexpr int128_t minInt128 = TFloat128::minInt128;
|
||||||
|
static constexpr int128_t maxInt128 = TFloat128::maxInt128;
|
||||||
|
|
||||||
static inline bool isWideDecimalNullValue(const int128_t& val)
|
static inline bool isWideDecimalNullValue(const int128_t& val)
|
||||||
{
|
{
|
||||||
@ -193,9 +195,6 @@ class Decimal: public TSInt128
|
|||||||
val = TSInt128::EmptyValue;
|
val = TSInt128::EmptyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr int128_t minInt128 = int128_t(0x8000000000000000LL) << 64;
|
|
||||||
static constexpr int128_t maxInt128 = (int128_t(0x7FFFFFFFFFFFFFFFLL) << 64) + 0xFFFFFFFFFFFFFFFFLL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Compares two Decimal taking scale into account.
|
@brief Compares two Decimal taking scale into account.
|
||||||
*/
|
*/
|
||||||
|
@ -50,6 +50,9 @@ struct get_integral_type<TSInt128>{
|
|||||||
class TFloat128
|
class TFloat128
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static constexpr int128_t minInt128 = int128_t(0x8000000000000000LL) << 64;
|
||||||
|
static constexpr int128_t maxInt128 = (int128_t(0x7FFFFFFFFFFFFFFFLL) << 64) + 0xFFFFFFFFFFFFFFFFLL;
|
||||||
|
|
||||||
static constexpr uint16_t MAXLENGTH16BYTES = 42;
|
static constexpr uint16_t MAXLENGTH16BYTES = 42;
|
||||||
// A variety of ctors for aligned and unaligned arguments
|
// A variety of ctors for aligned and unaligned arguments
|
||||||
TFloat128(): value(0) { }
|
TFloat128(): value(0) { }
|
||||||
@ -64,7 +67,21 @@ class TFloat128
|
|||||||
return TFloat128::MAXLENGTH16BYTES;
|
return TFloat128::MAXLENGTH16BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The method converts a TFloat128 to integral types
|
inline int128_t toTSInt128() const
|
||||||
|
{
|
||||||
|
if (value > static_cast<__float128>(maxInt128))
|
||||||
|
return maxInt128;
|
||||||
|
else if (value < static_cast<__float128>(minInt128))
|
||||||
|
return minInt128;
|
||||||
|
|
||||||
|
return static_cast<int128_t>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator int128_t() const
|
||||||
|
{
|
||||||
|
return toTSInt128();
|
||||||
|
}
|
||||||
|
|
||||||
inline operator double() const
|
inline operator double() const
|
||||||
{
|
{
|
||||||
return toDouble();
|
return toDouble();
|
||||||
@ -100,7 +117,7 @@ class TFloat128
|
|||||||
return toTSInt64();
|
return toTSInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int64_t toTUInt64() const
|
inline uint64_t toTUInt64() const
|
||||||
{
|
{
|
||||||
if (value > static_cast<__float128>(UINT64_MAX))
|
if (value > static_cast<__float128>(UINT64_MAX))
|
||||||
return UINT64_MAX;
|
return UINT64_MAX;
|
||||||
|
@ -119,10 +119,12 @@ class TSInt128
|
|||||||
static constexpr int128_t NullValue = int128_t(0x8000000000000000LL) << 64;
|
static constexpr int128_t NullValue = int128_t(0x8000000000000000LL) << 64;
|
||||||
static constexpr int128_t EmptyValue = (int128_t(0x8000000000000000LL) << 64) + 1;
|
static constexpr int128_t EmptyValue = (int128_t(0x8000000000000000LL) << 64) + 1;
|
||||||
|
|
||||||
|
|
||||||
// A variety of ctors for aligned and unaligned arguments
|
// A variety of ctors for aligned and unaligned arguments
|
||||||
TSInt128(): s128Value(0) { }
|
TSInt128(): s128Value(0) { }
|
||||||
|
|
||||||
|
// Copy ctor
|
||||||
|
TSInt128(const TSInt128& other): s128Value(other.s128Value) { }
|
||||||
|
|
||||||
// aligned argument
|
// aligned argument
|
||||||
TSInt128(const int128_t& x) { s128Value = x; }
|
TSInt128(const int128_t& x) { s128Value = x; }
|
||||||
|
|
||||||
|
@ -525,14 +525,26 @@ void AggregateColumn::evaluate(Row& row, bool& isNull)
|
|||||||
case CalpontSystemCatalog::UDECIMAL:
|
case CalpontSystemCatalog::UDECIMAL:
|
||||||
switch (fResultType.colWidth)
|
switch (fResultType.colWidth)
|
||||||
{
|
{
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
datatypes::TSInt128 val = row.getTSInt128Field(fInputIndex);
|
||||||
|
|
||||||
|
if (val.isNull())
|
||||||
|
isNull = true;
|
||||||
|
else
|
||||||
|
fResult.decimalVal = IDB_Decimal(val, fResultType.scale, fResultType.precision);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (row.equals<1>(TINYINTNULL, fInputIndex))
|
if (row.equals<1>(TINYINTNULL, fInputIndex))
|
||||||
isNull = true;
|
isNull = true;
|
||||||
else
|
else
|
||||||
{
|
fResult.decimalVal = IDB_Decimal(
|
||||||
fResult.decimalVal.value = row.getIntField<1>(fInputIndex);
|
row.getIntField<1>(fInputIndex),
|
||||||
fResult.decimalVal.scale = (unsigned)fResultType.scale;
|
fResultType.scale,
|
||||||
}
|
fResultType.precision);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -540,10 +552,10 @@ void AggregateColumn::evaluate(Row& row, bool& isNull)
|
|||||||
if (row.equals<2>(SMALLINTNULL, fInputIndex))
|
if (row.equals<2>(SMALLINTNULL, fInputIndex))
|
||||||
isNull = true;
|
isNull = true;
|
||||||
else
|
else
|
||||||
{
|
fResult.decimalVal = IDB_Decimal(
|
||||||
fResult.decimalVal.value = row.getIntField<2>(fInputIndex);
|
row.getIntField<2>(fInputIndex),
|
||||||
fResult.decimalVal.scale = (unsigned)fResultType.scale;
|
fResultType.scale,
|
||||||
}
|
fResultType.precision);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -551,10 +563,10 @@ void AggregateColumn::evaluate(Row& row, bool& isNull)
|
|||||||
if (row.equals<4>(INTNULL, fInputIndex))
|
if (row.equals<4>(INTNULL, fInputIndex))
|
||||||
isNull = true;
|
isNull = true;
|
||||||
else
|
else
|
||||||
{
|
fResult.decimalVal = IDB_Decimal(
|
||||||
fResult.decimalVal.value = row.getIntField<4>(fInputIndex);
|
row.getIntField<4>(fInputIndex),
|
||||||
fResult.decimalVal.scale = (unsigned)fResultType.scale;
|
fResultType.scale,
|
||||||
}
|
fResultType.precision);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -562,10 +574,10 @@ void AggregateColumn::evaluate(Row& row, bool& isNull)
|
|||||||
if (row.equals<8>(BIGINTNULL, fInputIndex))
|
if (row.equals<8>(BIGINTNULL, fInputIndex))
|
||||||
isNull = true;
|
isNull = true;
|
||||||
else
|
else
|
||||||
{
|
fResult.decimalVal = IDB_Decimal(
|
||||||
fResult.decimalVal.value = (int64_t)row.getUintField<8>(fInputIndex);
|
(int64_t) row.getUintField<8>(fInputIndex),
|
||||||
fResult.decimalVal.scale = (unsigned)fResultType.scale;
|
fResultType.scale,
|
||||||
}
|
fResultType.precision);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1003,41 +1003,82 @@ inline IDB_Decimal TreeNode::getDecimalVal()
|
|||||||
throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: non-support conversion from binary string");
|
throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: non-support conversion from binary string");
|
||||||
|
|
||||||
case CalpontSystemCatalog::BIGINT:
|
case CalpontSystemCatalog::BIGINT:
|
||||||
|
{
|
||||||
|
idbassert(fResultType.scale == 0);
|
||||||
|
|
||||||
|
if (fResultType.isWideDecimalPrecision())
|
||||||
|
fResult.decimalVal = IDB_Decimal(0, 0, fResultType.precision,
|
||||||
|
(int128_t)fResult.intVal);
|
||||||
|
else
|
||||||
|
fResult.decimalVal = IDB_Decimal(fResult.intVal, 0,
|
||||||
|
fResultType.precision);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::MEDINT:
|
case CalpontSystemCatalog::MEDINT:
|
||||||
case CalpontSystemCatalog::INT:
|
case CalpontSystemCatalog::INT:
|
||||||
case CalpontSystemCatalog::SMALLINT:
|
case CalpontSystemCatalog::SMALLINT:
|
||||||
case CalpontSystemCatalog::TINYINT:
|
case CalpontSystemCatalog::TINYINT:
|
||||||
fResult.decimalVal.value = (int64_t)(fResult.intVal * pow((double)10.0, fResultType.scale));
|
{
|
||||||
fResult.decimalVal.scale = fResultType.scale;
|
idbassert(fResultType.scale == 0);
|
||||||
fResult.decimalVal.precision = fResultType.precision;
|
|
||||||
|
fResult.decimalVal = IDB_Decimal(fResult.intVal, 0,
|
||||||
|
fResultType.precision);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::UBIGINT:
|
case CalpontSystemCatalog::UBIGINT:
|
||||||
|
{
|
||||||
|
idbassert(fResultType.scale == 0);
|
||||||
|
|
||||||
|
if (fResultType.isWideDecimalPrecision())
|
||||||
|
fResult.decimalVal = IDB_Decimal(0, 0, fResultType.precision,
|
||||||
|
(int128_t)fResult.uintVal);
|
||||||
|
else
|
||||||
|
fResult.decimalVal = IDB_Decimal((int64_t)fResult.uintVal, 0,
|
||||||
|
fResultType.precision);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::UMEDINT:
|
case CalpontSystemCatalog::UMEDINT:
|
||||||
case CalpontSystemCatalog::UINT:
|
case CalpontSystemCatalog::UINT:
|
||||||
case CalpontSystemCatalog::USMALLINT:
|
case CalpontSystemCatalog::USMALLINT:
|
||||||
case CalpontSystemCatalog::UTINYINT:
|
case CalpontSystemCatalog::UTINYINT:
|
||||||
fResult.decimalVal.value = (int64_t)(fResult.uintVal * pow((double)10.0, fResultType.scale));
|
{
|
||||||
fResult.decimalVal.scale = fResultType.scale;
|
idbassert(fResultType.scale == 0);
|
||||||
fResult.decimalVal.precision = fResultType.precision;
|
|
||||||
|
fResult.decimalVal = IDB_Decimal((int64_t)fResult.uintVal, 0,
|
||||||
|
fResultType.precision);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::LONGDOUBLE:
|
case CalpontSystemCatalog::LONGDOUBLE:
|
||||||
|
{
|
||||||
|
long double dlScaled = fResult.longDoubleVal;
|
||||||
|
|
||||||
|
if (fResultType.scale > 0)
|
||||||
{
|
{
|
||||||
long double dlScaled = fResult.longDoubleVal;
|
dlScaled = fResult.longDoubleVal * pow((double)10.0, fResultType.scale);
|
||||||
if (fResultType.scale > 0)
|
|
||||||
{
|
|
||||||
dlScaled= fResult.longDoubleVal * pow((double)10.0, fResultType.scale);
|
|
||||||
}
|
|
||||||
if (dlScaled > (double)MAX_BIGINT)
|
|
||||||
{
|
|
||||||
throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: decimal overflow.");
|
|
||||||
}
|
|
||||||
fResult.decimalVal.value = (int64_t)roundl((fResult.longDoubleVal * pow((double)10.0, fResultType.scale)));
|
|
||||||
fResult.decimalVal.scale = fResultType.scale;
|
|
||||||
fResult.decimalVal.precision = fResultType.precision;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((dlScaled > (long double)INT64_MAX) || (dlScaled < (long double)(INT64_MIN)))
|
||||||
|
{
|
||||||
|
datatypes::TFloat128 temp((__float128)dlScaled);
|
||||||
|
fResult.decimalVal = IDB_Decimal(0, fResultType.scale,
|
||||||
|
fResultType.precision, static_cast<int128_t>(temp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fResult.decimalVal = IDB_Decimal((int64_t)lroundl(dlScaled),
|
||||||
|
fResultType.scale, fResultType.precision);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::DATE:
|
case CalpontSystemCatalog::DATE:
|
||||||
throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion from date.");
|
throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion from date.");
|
||||||
|
@ -3475,11 +3475,11 @@ void TupleAggregateStep::prep2PhasesAggregate(
|
|||||||
|
|
||||||
if (aggOp == ROWAGG_SUM)
|
if (aggOp == ROWAGG_SUM)
|
||||||
{
|
{
|
||||||
wideDecimalOrLongDouble(colPm, typeProj[colPm],
|
wideDecimalOrLongDouble(colPm, typeAggPm[colPm],
|
||||||
precisionProj, scaleProj, widthAggPm,
|
precisionAggPm, scaleAggPm, widthAggPm,
|
||||||
typeAggUm, scaleAggUm, precisionAggUm, widthAggUm);
|
typeAggUm, scaleAggUm, precisionAggUm, widthAggUm);
|
||||||
|
|
||||||
oidsAggUm.push_back(oidsProj[colPm]);
|
oidsAggUm.push_back(oidsAggPm[colPm]);
|
||||||
keysAggUm.push_back(retKey);
|
keysAggUm.push_back(retKey);
|
||||||
csNumAggUm.push_back(8);
|
csNumAggUm.push_back(8);
|
||||||
}
|
}
|
||||||
|
@ -4949,7 +4949,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
|||||||
CalpontSystemCatalog::ColType ct;
|
CalpontSystemCatalog::ColType ct;
|
||||||
ct.colDataType = CalpontSystemCatalog::BIGINT;
|
ct.colDataType = CalpontSystemCatalog::BIGINT;
|
||||||
ct.colWidth = 8;
|
ct.colWidth = 8;
|
||||||
ct.scale = parm->resultType().scale;
|
ct.scale = 0;
|
||||||
ac->resultType(ct);
|
ac->resultType(ct);
|
||||||
}
|
}
|
||||||
else if (isp->sum_func() == Item_sum::STD_FUNC ||
|
else if (isp->sum_func() == Item_sum::STD_FUNC ||
|
||||||
|
Reference in New Issue
Block a user