1
0
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:
Gagan Goel
2020-11-19 18:56:40 -05:00
parent aa64d81cde
commit a159f8a0b6
8 changed files with 125 additions and 44 deletions

View File

@ -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

View File

@ -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.
*/ */

View File

@ -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;

View File

@ -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; }

View File

@ -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;
} }

View File

@ -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.");

View File

@ -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);
} }

View File

@ -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 ||