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
Merge pull request #1856 from mariadb-corporation/bar-develop-MCOL-4361
MCOL-4361 Replace pow(10.0, (double)scale) expressions with a static …
This commit is contained in:
@ -195,6 +195,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T applySignedScale(const T & val, int32_t scale)
|
||||||
|
{
|
||||||
|
return scale < 0 ?
|
||||||
|
val / datatypes::scaleDivisor<T>((uint32_t) -scale) :
|
||||||
|
val * datatypes::scaleDivisor<T>((uint32_t) scale);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief The function to produce scale multiplier/divisor for
|
@brief The function to produce scale multiplier/divisor for
|
||||||
wide decimals.
|
wide decimals.
|
||||||
@ -267,6 +275,14 @@ public:
|
|||||||
{
|
{
|
||||||
return DecomposedDecimal<int64_t>(value, scale).toSIntCeil();
|
return DecomposedDecimal<int64_t>(value, scale).toSIntCeil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert to an arbitrary floating point data type,
|
||||||
|
// e.g. float, double, long double
|
||||||
|
template<typename T>
|
||||||
|
T toXFloat(uint32_t scale) const
|
||||||
|
{
|
||||||
|
return (T) value / scaleDivisor<T>(scale);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -590,6 +606,11 @@ class Decimal: public TDecimal128, public TDecimal64
|
|||||||
return TDecimal64::toUInt64Round((uint32_t) scale);
|
return TDecimal64::toUInt64Round((uint32_t) scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> T decimal64ToXFloat() const
|
||||||
|
{
|
||||||
|
return TDecimal64::toXFloat<T>((uint32_t) scale);
|
||||||
|
}
|
||||||
|
|
||||||
int64_t toSInt64Round() const
|
int64_t toSInt64Round() const
|
||||||
{
|
{
|
||||||
return isWideDecimalTypeByPrecision(precision) ?
|
return isWideDecimalTypeByPrecision(precision) ?
|
||||||
|
@ -166,7 +166,9 @@ inline int64_t SimpleColumn_Decimal<len>:: getIntVal(rowgroup::Row& row, bool& i
|
|||||||
if (row.equals<len>(fNullVal, fInputIndex))
|
if (row.equals<len>(fNullVal, fInputIndex))
|
||||||
isNull = true;
|
isNull = true;
|
||||||
|
|
||||||
return (int64_t)(row.getIntField<len>(fInputIndex) / pow((double)10, fResultType.scale));
|
// TODO: fix double division to integer division
|
||||||
|
return (int64_t)(row.getIntField<len>(fInputIndex) /
|
||||||
|
datatypes::scaleDivisor<double>(fResultType.scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int len>
|
template<int len>
|
||||||
@ -175,7 +177,8 @@ inline float SimpleColumn_Decimal<len>::getFloatVal(rowgroup::Row& row, bool& is
|
|||||||
if (row.equals<len>(fNullVal, fInputIndex))
|
if (row.equals<len>(fNullVal, fInputIndex))
|
||||||
isNull = true;
|
isNull = true;
|
||||||
|
|
||||||
return (row.getIntField<len>(fInputIndex) / pow((double)10, fResultType.scale));
|
return (row.getIntField<len>(fInputIndex) /
|
||||||
|
datatypes::scaleDivisor<double>(fResultType.scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int len>
|
template<int len>
|
||||||
@ -184,7 +187,8 @@ inline double SimpleColumn_Decimal<len>::getDoubleVal(rowgroup::Row& row, bool&
|
|||||||
if (row.equals<len>(fNullVal, fInputIndex))
|
if (row.equals<len>(fNullVal, fInputIndex))
|
||||||
isNull = true;
|
isNull = true;
|
||||||
|
|
||||||
return (row.getIntField<len>(fInputIndex) / pow((double)10, fResultType.scale));
|
return (row.getIntField<len>(fInputIndex) /
|
||||||
|
datatypes::scaleDivisor<double>(fResultType.scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int len>
|
template<int len>
|
||||||
@ -193,7 +197,8 @@ inline long double SimpleColumn_Decimal<len>::getLongDoubleVal(rowgroup::Row& ro
|
|||||||
if (row.equals<len>(fNullVal, fInputIndex))
|
if (row.equals<len>(fNullVal, fInputIndex))
|
||||||
isNull = true;
|
isNull = true;
|
||||||
|
|
||||||
return (row.getIntField<len>(fInputIndex) / pow((double)10, fResultType.scale));
|
return (row.getIntField<len>(fInputIndex) /
|
||||||
|
datatypes::scaleDivisor<long double>(fResultType.scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int len>
|
template<int len>
|
||||||
|
@ -828,7 +828,7 @@ inline float TreeNode::getFloatVal()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale));
|
return (float) fResult.decimalVal.decimal64ToXFloat<double>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,8 +903,7 @@ inline double TreeNode::getDoubleVal()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// this may not be accurate. if this is problematic, change to pre-calculated power array.
|
return fResult.decimalVal.decimal64ToXFloat<double>();
|
||||||
return (double)(fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,8 +978,7 @@ inline long double TreeNode::getLongDoubleVal()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// this may not be accurate. if this is problematic, change to pre-calculated power array.
|
return fResult.decimalVal.decimal64ToXFloat<long double>();
|
||||||
return (long double)(fResult.decimalVal.value / pow((long double)10, fResult.decimalVal.scale));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,45 +479,22 @@ void TupleUnion::normalize(const Row& in, Row* out)
|
|||||||
case CalpontSystemCatalog::FLOAT:
|
case CalpontSystemCatalog::FLOAT:
|
||||||
case CalpontSystemCatalog::UFLOAT:
|
case CalpontSystemCatalog::UFLOAT:
|
||||||
{
|
{
|
||||||
int scale = in.getScale(i);
|
auto d = in.getScaledSInt64FieldAsXFloat<double>(i);
|
||||||
|
out->setFloatField((float) d, i);
|
||||||
if (scale != 0)
|
|
||||||
{
|
|
||||||
float f = in.getIntField(i);
|
|
||||||
f /= (uint64_t) pow(10.0, scale);
|
|
||||||
out->setFloatField(f, i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
out->setFloatField(in.getIntField(i), i);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::DOUBLE:
|
case CalpontSystemCatalog::DOUBLE:
|
||||||
case CalpontSystemCatalog::UDOUBLE:
|
case CalpontSystemCatalog::UDOUBLE:
|
||||||
{
|
{
|
||||||
int scale = in.getScale(i);
|
auto d = in.getScaledSInt64FieldAsXFloat<double>(i);
|
||||||
|
out->setDoubleField(d, i);
|
||||||
if (scale != 0)
|
|
||||||
{
|
|
||||||
double d = in.getIntField(i);
|
|
||||||
d /= (uint64_t) pow(10.0, scale);
|
|
||||||
out->setDoubleField(d, i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
out->setDoubleField(in.getIntField(i), i);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::LONGDOUBLE:
|
case CalpontSystemCatalog::LONGDOUBLE:
|
||||||
{
|
{
|
||||||
int scale = in.getScale(i);
|
auto d = in.getScaledSInt64FieldAsXFloat<long double>(i);
|
||||||
long double d = in.getIntField(i);
|
|
||||||
if (scale != 0)
|
|
||||||
{
|
|
||||||
d /= (uint64_t) pow(10.0, scale);
|
|
||||||
}
|
|
||||||
out->setLongDoubleField(d, i);
|
out->setLongDoubleField(d, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -526,13 +503,30 @@ void TupleUnion::normalize(const Row& in, Row* out)
|
|||||||
case CalpontSystemCatalog::UDECIMAL:
|
case CalpontSystemCatalog::UDECIMAL:
|
||||||
{
|
{
|
||||||
dec1:
|
dec1:
|
||||||
uint64_t val = in.getIntField(i);
|
|
||||||
int diff = out->getScale(i) - in.getScale(i);
|
int diff = out->getScale(i) - in.getScale(i);
|
||||||
|
/*
|
||||||
if (diff < 0)
|
Signed INT to XDecimal
|
||||||
val /= (uint64_t) pow((double) 10, (double) - diff);
|
TODO: there are a few problems here:
|
||||||
else
|
- This code is not wide decimal friendly.
|
||||||
val *= (uint64_t) pow((double) 10, (double) diff);
|
`uint64_t val` can overflow when applying a positive scale
|
||||||
|
It's not possible to make a reproducible bug report
|
||||||
|
at the moment: MCOL-4612 and MCOL-4613 should be fixed first.
|
||||||
|
- Using uint64_t is wrong here. The data type of "in" field is
|
||||||
|
signed. In case of a negative diff, the result will be wrong,
|
||||||
|
because division (unlike multiplication) is sensitive to
|
||||||
|
the signess of the operands.
|
||||||
|
Perhaps diff cannot be negative and we can put an assert for it.
|
||||||
|
Anyway, it's safer to change `uint64_t val` to `int64_t val`.
|
||||||
|
- This code does not handle overflow that may happen on
|
||||||
|
scale multiplication (MCOL-4613). Instead of returning a garbage
|
||||||
|
we should probably apply saturation here. In long terms we
|
||||||
|
should implement DECIMAL(65,x) to avoid overflow completely
|
||||||
|
(so the UNION between DECIMAL and integer can choose a proper
|
||||||
|
DECIMAL(M,N) result data type to guarantee that any incoming
|
||||||
|
integer value can fit into it).
|
||||||
|
*/
|
||||||
|
// TODO: isn't overflow possible below?
|
||||||
|
uint64_t val = datatypes::applySignedScale<uint64_t>(in.getIntField(i), diff);
|
||||||
|
|
||||||
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
||||||
out->setInt128Field(val, i);
|
out->setInt128Field(val, i);
|
||||||
@ -606,50 +600,23 @@ dec1:
|
|||||||
case CalpontSystemCatalog::FLOAT:
|
case CalpontSystemCatalog::FLOAT:
|
||||||
case CalpontSystemCatalog::UFLOAT:
|
case CalpontSystemCatalog::UFLOAT:
|
||||||
{
|
{
|
||||||
int scale = in.getScale(i);
|
auto d = in.getScaledUInt64FieldAsXFloat<double>(i);
|
||||||
|
out->setFloatField((float) d, i);
|
||||||
if (scale != 0)
|
|
||||||
{
|
|
||||||
float f = in.getUintField(i);
|
|
||||||
f /= (uint64_t) pow(10.0, scale);
|
|
||||||
out->setFloatField(f, i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
out->setFloatField(in.getUintField(i), i);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::DOUBLE:
|
case CalpontSystemCatalog::DOUBLE:
|
||||||
case CalpontSystemCatalog::UDOUBLE:
|
case CalpontSystemCatalog::UDOUBLE:
|
||||||
{
|
{
|
||||||
int scale = in.getScale(i);
|
auto d = in.getScaledUInt64FieldAsXFloat<double>(i);
|
||||||
|
out->setDoubleField(d, i);
|
||||||
if (scale != 0)
|
|
||||||
{
|
|
||||||
double d = in.getUintField(i);
|
|
||||||
d /= (uint64_t) pow(10.0, scale);
|
|
||||||
out->setDoubleField(d, i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
out->setDoubleField(in.getUintField(i), i);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CalpontSystemCatalog::LONGDOUBLE:
|
case CalpontSystemCatalog::LONGDOUBLE:
|
||||||
{
|
{
|
||||||
int scale = in.getScale(i);
|
auto d = in.getScaledUInt64FieldAsXFloat<long double>(i);
|
||||||
|
out->setLongDoubleField(d, i);
|
||||||
if (scale != 0)
|
|
||||||
{
|
|
||||||
long double d = in.getUintField(i);
|
|
||||||
d /= (uint64_t) pow(10.0, scale);
|
|
||||||
out->setLongDoubleField(d, i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
out->setLongDoubleField(in.getUintField(i), i);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,13 +624,16 @@ dec1:
|
|||||||
case CalpontSystemCatalog::UDECIMAL:
|
case CalpontSystemCatalog::UDECIMAL:
|
||||||
{
|
{
|
||||||
dec2:
|
dec2:
|
||||||
uint64_t val = in.getIntField(i);
|
|
||||||
int diff = out->getScale(i) - in.getScale(i);
|
int diff = out->getScale(i) - in.getScale(i);
|
||||||
|
/*
|
||||||
if (diff < 0)
|
Unsigned INT to XDecimal
|
||||||
val /= (uint64_t) pow((double) 10, (double) - diff);
|
TODO: There are a few problems here:
|
||||||
else
|
- It should use in.getUintField() instead of in.getIntField()
|
||||||
val *= (uint64_t) pow((double) 10, (double) diff);
|
- All problems mentioned in the code under label "dec1:" are
|
||||||
|
also applicable here.
|
||||||
|
*/
|
||||||
|
// TODO: isn't overflow possible below?
|
||||||
|
uint64_t val = datatypes::applySignedScale<uint64_t>(in.getIntField(i), diff);
|
||||||
|
|
||||||
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
||||||
out->setInt128Field(val, i);
|
out->setInt128Field(val, i);
|
||||||
@ -989,13 +959,15 @@ dec2:
|
|||||||
{
|
{
|
||||||
dec3: /* have to pick a scale to use for the double. using 5... */
|
dec3: /* have to pick a scale to use for the double. using 5... */
|
||||||
uint32_t scale = 5;
|
uint32_t scale = 5;
|
||||||
uint64_t ival = (uint64_t) (double) (val * pow((double) 10, (double) scale));
|
uint64_t ival = (uint64_t) (double) (val * datatypes::scaleDivisor<double>(scale));
|
||||||
int diff = out->getScale(i) - scale;
|
int diff = out->getScale(i) - scale;
|
||||||
|
// xFLOAT or xDOUBLE to xDECIMAL conversion. Is it really possible?
|
||||||
if (diff < 0)
|
// TODO:
|
||||||
ival /= (uint64_t) pow((double) 10, (double) - diff);
|
// Perhaps we should add an assert here that this combination is not possible
|
||||||
else
|
// In the current reduction all problems mentioned in the code under
|
||||||
ival *= (uint64_t) pow((double) 10, (double) diff);
|
// label "dec1:" are also applicable here.
|
||||||
|
// TODO: isn't overflow possible below?
|
||||||
|
ival = datatypes::applySignedScale<uint64_t>(ival, diff);
|
||||||
|
|
||||||
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
||||||
out->setInt128Field(ival, i);
|
out->setInt128Field(ival, i);
|
||||||
@ -1070,13 +1042,15 @@ dec3: /* have to pick a scale to use for the double. using 5..
|
|||||||
{
|
{
|
||||||
dec4: /* have to pick a scale to use for the double. using 5... */
|
dec4: /* have to pick a scale to use for the double. using 5... */
|
||||||
uint32_t scale = 5;
|
uint32_t scale = 5;
|
||||||
uint64_t ival = (uint64_t) (double) (val * pow((double) 10, (double) scale));
|
uint64_t ival = (uint64_t) (double) (val * datatypes::scaleDivisor<double>(scale));
|
||||||
int diff = out->getScale(i) - scale;
|
int diff = out->getScale(i) - scale;
|
||||||
|
|
||||||
if (diff < 0)
|
// LONGDOUBLE to xDECIMAL conversions: is it really possible?
|
||||||
ival /= (uint64_t) pow((double) 10, (double) - diff);
|
// TODO:
|
||||||
else
|
// Perhaps we should add an assert here that this combination is not possible
|
||||||
ival *= (uint64_t) pow((double) 10, (double) diff);
|
// In the current reduction all problems mentioned in the code under
|
||||||
|
// label "dec1:" are also applicable here.
|
||||||
|
ival = datatypes::applySignedScale<uint64_t>(ival, diff);
|
||||||
|
|
||||||
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
|
||||||
out->setInt128Field(ival, i);
|
out->setInt128Field(ival, i);
|
||||||
|
@ -4463,8 +4463,8 @@ ConstantColumn* buildDecimalColumn(Item* item, gp_walk_info& gwi)
|
|||||||
if (gwi.internalDecimalScale >= 0 && idp->decimals > (uint)gwi.internalDecimalScale)
|
if (gwi.internalDecimalScale >= 0 && idp->decimals > (uint)gwi.internalDecimalScale)
|
||||||
{
|
{
|
||||||
columnstore_decimal.scale = gwi.internalDecimalScale;
|
columnstore_decimal.scale = gwi.internalDecimalScale;
|
||||||
double val = (double)(columnstore_decimal.value / pow((double)10, idp->decimals - gwi.internalDecimalScale));
|
uint32_t diff = (uint32_t) (idp->decimals - gwi.internalDecimalScale);
|
||||||
columnstore_decimal.value = (int64_t)(val > 0 ? val + 0.5 : val - 0.5);
|
columnstore_decimal.value= columnstore_decimal.TDecimal64::toSInt64Round(diff);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
columnstore_decimal.scale = idp->decimal_scale();
|
columnstore_decimal.scale = idp->decimal_scale();
|
||||||
|
@ -97,8 +97,8 @@ Command* FilterCommand::makeFilterCommand(ByteStream& bs, vector<SCommand>& cmds
|
|||||||
|
|
||||||
ColumnCommand* cmd0 = dynamic_cast<ColumnCommand*>(cmds[nc - 2].get());
|
ColumnCommand* cmd0 = dynamic_cast<ColumnCommand*>(cmds[nc - 2].get());
|
||||||
ColumnCommand* cmd1 = dynamic_cast<ColumnCommand*>(cmds[nc - 1].get());
|
ColumnCommand* cmd1 = dynamic_cast<ColumnCommand*>(cmds[nc - 1].get());
|
||||||
int scale0 = cmd0->getScale();
|
uint32_t scale0 = cmd0->getScale();
|
||||||
int scale1 = cmd1->getScale();
|
uint32_t scale1 = cmd1->getScale();
|
||||||
|
|
||||||
// char[] is stored as int, but cannot directly compare if length is different
|
// char[] is stored as int, but cannot directly compare if length is different
|
||||||
// due to endian issue
|
// due to endian issue
|
||||||
@ -117,7 +117,8 @@ Command* FilterCommand::makeFilterCommand(ByteStream& bs, vector<SCommand>& cmds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScaledFilterCmd* sc = new ScaledFilterCmd();
|
ScaledFilterCmd* sc = new ScaledFilterCmd();
|
||||||
sc->setFactor(pow(10.0, scale1) / pow(10.0, scale0));
|
sc->setFactor(datatypes::scaleDivisor<double>(scale1) /
|
||||||
|
datatypes::scaleDivisor<double>(scale0));
|
||||||
fc = sc;
|
fc = sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1519,7 +1519,7 @@ double Func_cast_decimal::getDoubleVal(Row& row,
|
|||||||
return static_cast<double>(decimal);
|
return static_cast<double>(decimal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (double) decimal.value / helpers::powerOf10_c[decimal.scale];
|
return decimal.decimal64ToXFloat<double>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1631,7 +1631,7 @@ double Func_cast_double::getDoubleVal(Row& row,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dblval = (double)(decimal.value / pow((double)10, decimal.scale));
|
dblval = decimal.decimal64ToXFloat<double>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -248,7 +248,7 @@ mcsv1_UDAF::ReturnCode Moda_impl_T<T>::nextValue(mcsv1Context* context, ColumnDa
|
|||||||
|
|
||||||
if (val != 0 && scale > 0)
|
if (val != 0 && scale > 0)
|
||||||
{
|
{
|
||||||
val /= pow(10.0, (double)scale);
|
val /= datatypes::scaleDivisor<double>(scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1458,12 +1458,8 @@ void RowAggregation::doSum(const Row& rowIn, int64_t colIn, int64_t colOut, int
|
|||||||
}
|
}
|
||||||
else if (width <= datatypes::MAXLEGACYWIDTH)
|
else if (width <= datatypes::MAXLEGACYWIDTH)
|
||||||
{
|
{
|
||||||
valIn = rowIn.getIntField(colIn);
|
uint32_t scale = fRowGroupIn.getScale()[colIn];
|
||||||
double scale = (double)(fRowGroupIn.getScale())[colIn];
|
valIn = rowIn.getScaledSInt64FieldAsXFloat<long double>(colIn, scale);
|
||||||
if (valIn != 0 && scale > 0)
|
|
||||||
{
|
|
||||||
valIn /= pow(10.0, scale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1938,12 +1934,8 @@ void RowAggregation::doAvg(const Row& rowIn, int64_t colIn, int64_t colOut, int6
|
|||||||
}
|
}
|
||||||
else if (width <= datatypes::MAXLEGACYWIDTH)
|
else if (width <= datatypes::MAXLEGACYWIDTH)
|
||||||
{
|
{
|
||||||
valIn = rowIn.getIntField(colIn);
|
uint32_t scale = fRowGroupIn.getScale()[colIn];
|
||||||
double scale = (double)(fRowGroupIn.getScale())[colIn];
|
valIn = rowIn.getScaledSInt64FieldAsXFloat<long double>(colIn, scale);
|
||||||
if (valIn != 0 && scale > 0)
|
|
||||||
{
|
|
||||||
valIn /= pow(10.0, scale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3366,8 +3358,8 @@ void RowAggregationUM::calculateStatisticsFunctions()
|
|||||||
long double sum1 = fRow.getLongDoubleField(colAux);
|
long double sum1 = fRow.getLongDoubleField(colAux);
|
||||||
long double sum2 = fRow.getLongDoubleField(colAux + 1);
|
long double sum2 = fRow.getLongDoubleField(colAux + 1);
|
||||||
|
|
||||||
int scale = fRow.getScale(colOut);
|
uint32_t scale = fRow.getScale(colOut);
|
||||||
long double factor = pow(10.0, scale);
|
auto factor = datatypes::scaleDivisor<long double>(scale);
|
||||||
|
|
||||||
if (scale != 0) // adjust the scale if necessary
|
if (scale != 0) // adjust the scale if necessary
|
||||||
{
|
{
|
||||||
@ -3732,7 +3724,8 @@ void RowAggregationUM::doNotNullConstantAggregate(const ConstantAggData& aggData
|
|||||||
else if (width <= datatypes::MAXLEGACYWIDTH)
|
else if (width <= datatypes::MAXLEGACYWIDTH)
|
||||||
{
|
{
|
||||||
double dbl = strtod(aggData.fConstValue.c_str(), 0);
|
double dbl = strtod(aggData.fConstValue.c_str(), 0);
|
||||||
double scale = pow(10.0, (double) fRowGroupOut->getScale()[i]);
|
auto scale = datatypes::scaleDivisor<double>(fRowGroupOut->getScale()[i]);
|
||||||
|
// TODO: isn't overflow possible below:
|
||||||
fRow.setIntField((int64_t)(scale * dbl), colOut);
|
fRow.setIntField((int64_t)(scale * dbl), colOut);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3862,7 +3855,8 @@ void RowAggregationUM::doNotNullConstantAggregate(const ConstantAggData& aggData
|
|||||||
else if (width == datatypes::MAXLEGACYWIDTH)
|
else if (width == datatypes::MAXLEGACYWIDTH)
|
||||||
{
|
{
|
||||||
double dbl = strtod(aggData.fConstValue.c_str(), 0);
|
double dbl = strtod(aggData.fConstValue.c_str(), 0);
|
||||||
dbl *= pow(10.0, (double) fRowGroupOut->getScale()[i]);
|
// TODO: isn't precision loss possible below?
|
||||||
|
dbl *= datatypes::scaleDivisor<double>(fRowGroupOut->getScale()[i]);
|
||||||
dbl *= rowCnt;
|
dbl *= rowCnt;
|
||||||
|
|
||||||
if ((dbl > 0 && dbl > (double) numeric_limits<int64_t>::max()) ||
|
if ((dbl > 0 && dbl > (double) numeric_limits<int64_t>::max()) ||
|
||||||
@ -4077,9 +4071,9 @@ void RowAggregationUM::doNotNullConstantAggregate(const ConstantAggData& aggData
|
|||||||
case execplan::CalpontSystemCatalog::UDECIMAL:
|
case execplan::CalpontSystemCatalog::UDECIMAL:
|
||||||
{
|
{
|
||||||
double dbl = strtod(aggData.fConstValue.c_str(), 0);
|
double dbl = strtod(aggData.fConstValue.c_str(), 0);
|
||||||
double scale = pow(10.0, (double) fRowGroupOut->getScale()[i]);
|
// TODO: isn't overflow possible below?
|
||||||
datum.columnData = (int64_t)(scale * dbl);
|
datum.columnData = (int64_t) (dbl * datatypes::scaleDivisor<double>(fRowGroupOut->getScale()[i]));
|
||||||
datum.scale = scale;
|
datum.scale = fRowGroupOut->getScale()[i];
|
||||||
datum.precision = fRowGroupOut->getPrecision()[i];
|
datum.precision = fRowGroupOut->getPrecision()[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4454,12 +4448,8 @@ void RowAggregationUMP2::doAvg(const Row& rowIn, int64_t colIn, int64_t colOut,
|
|||||||
}
|
}
|
||||||
else if (width <= datatypes::MAXLEGACYWIDTH)
|
else if (width <= datatypes::MAXLEGACYWIDTH)
|
||||||
{
|
{
|
||||||
valIn = rowIn.getIntField(colIn);
|
uint32_t scale = fRowGroupIn.getScale()[colIn];
|
||||||
double scale = (double)(fRowGroupIn.getScale())[colIn];
|
valIn = rowIn.getScaledSInt64FieldAsXFloat<long double>(colIn, scale);
|
||||||
if (valIn != 0 && scale > 0)
|
|
||||||
{
|
|
||||||
valIn /= pow(10.0, scale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -376,6 +376,38 @@ public:
|
|||||||
inline uint64_t getUintField(uint32_t colIndex) const;
|
inline uint64_t getUintField(uint32_t colIndex) const;
|
||||||
template<int len> inline int64_t getIntField(uint32_t colIndex) const;
|
template<int len> inline int64_t getIntField(uint32_t colIndex) const;
|
||||||
inline int64_t getIntField(uint32_t colIndex) const;
|
inline int64_t getIntField(uint32_t colIndex) const;
|
||||||
|
// Get a signed 64-bit integer column value, convert to the given
|
||||||
|
// floating point data type T (e.g. float, double, long double)
|
||||||
|
// and divide it according to the scale.
|
||||||
|
template<typename T>
|
||||||
|
inline T getScaledSInt64FieldAsXFloat(uint32_t colIndex, uint32_t scale) const
|
||||||
|
{
|
||||||
|
const T d = getIntField(colIndex);
|
||||||
|
if (!scale)
|
||||||
|
return d;
|
||||||
|
return d / datatypes::scaleDivisor<T>(scale);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline T getScaledSInt64FieldAsXFloat(uint32_t colIndex) const
|
||||||
|
{
|
||||||
|
return getScaledSInt64FieldAsXFloat<T>(colIndex, getScale(colIndex));
|
||||||
|
}
|
||||||
|
// Get an unsigned 64-bit integer column value, convert to the given
|
||||||
|
// floating point data type T (e.g. float, double, long double)
|
||||||
|
// and divide it according to the scale.
|
||||||
|
template<typename T>
|
||||||
|
inline T getScaledUInt64FieldAsXFloat(uint32_t colIndex, uint32_t scale) const
|
||||||
|
{
|
||||||
|
const T d = getUintField(colIndex);
|
||||||
|
if (!scale)
|
||||||
|
return d;
|
||||||
|
return d / datatypes::scaleDivisor<T>(scale);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline T getScaledUInt64FieldAsXFloat(uint32_t colIndex) const
|
||||||
|
{
|
||||||
|
return getScaledUInt64FieldAsXFloat<T>(colIndex, getScale(colIndex));
|
||||||
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool equals(T* value, uint32_t colIndex) const;
|
inline bool equals(T* value, uint32_t colIndex) const;
|
||||||
template<int len> inline bool equals(uint64_t val, uint32_t colIndex) const;
|
template<int len> inline bool equals(uint64_t val, uint32_t colIndex) const;
|
||||||
|
@ -633,7 +633,7 @@ protected:
|
|||||||
{
|
{
|
||||||
double val = convertAnyTo<double>(datum.columnData);
|
double val = convertAnyTo<double>(datum.columnData);
|
||||||
if (val != 0 && datum.scale > 0)
|
if (val != 0 && datum.scale > 0)
|
||||||
val /= pow(10.0, (double) datum.scale);
|
val /= datatypes::scaleDivisor<double>(datum.scale);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,16 +181,16 @@ double MCS_add::getDoubleVal(Row& row,
|
|||||||
else if (op1.scale >= op2.scale)
|
else if (op1.scale >= op2.scale)
|
||||||
{
|
{
|
||||||
dec.scale = op2.scale;
|
dec.scale = op2.scale;
|
||||||
op1.value *= (int64_t)pow((double)10, op1.scale - op2.scale);
|
op1.value *= datatypes::scaleDivisor<int64_t>((uint32_t) (op1.scale - op2.scale));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dec.scale = op1.scale;
|
dec.scale = op1.scale;
|
||||||
op2.value *= (int64_t)pow((double)10, op2.scale - op1.scale);
|
op2.value *= datatypes::scaleDivisor<int64_t>((uint32_t) (op2.scale - op1.scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
dec.value = op1.value + op2.value;
|
dec.value = op1.value + op2.value;
|
||||||
return (double)(dec.value / pow((double)10, dec.scale));
|
return dec.decimal64ToXFloat<double>();
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -191,8 +191,8 @@ void WF_stats<T>::operator()(int64_t b, int64_t e, int64_t c)
|
|||||||
|
|
||||||
if (fCount > 1)
|
if (fCount > 1)
|
||||||
{
|
{
|
||||||
int scale = fRow.getScale(colIn);
|
uint32_t scale = fRow.getScale(colIn);
|
||||||
long double factor = pow(10.0, scale);
|
auto factor = datatypes::scaleDivisor<long double>(scale);
|
||||||
long double ldSum1 = fSum1;
|
long double ldSum1 = fSum1;
|
||||||
long double ldSum2 = fSum2;
|
long double ldSum2 = fSum2;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user