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 #1607 from drrtuy/MCOL-4394
MCOL-4394 __float128 related code had been moved into a separate file
This commit is contained in:
@ -25,6 +25,7 @@
|
|||||||
#include "exceptclasses.h"
|
#include "exceptclasses.h"
|
||||||
#include "widedecimalutils.h"
|
#include "widedecimalutils.h"
|
||||||
#include "mcs_int128.h"
|
#include "mcs_int128.h"
|
||||||
|
#include "mcs_float128.h"
|
||||||
|
|
||||||
|
|
||||||
namespace datatypes
|
namespace datatypes
|
||||||
@ -334,36 +335,6 @@ class Decimal
|
|||||||
return static_cast<uint64_t>(value);
|
return static_cast<uint64_t>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
@brief The method converts a wide decimal value to a double.
|
|
||||||
*/
|
|
||||||
static inline double getDoubleFromWideDecimal(const int128_t& value, int8_t scale)
|
|
||||||
{
|
|
||||||
int128_t scaleDivisor;
|
|
||||||
|
|
||||||
getScaleDivisor(scaleDivisor, scale);
|
|
||||||
|
|
||||||
__float128 tmpval = (__float128) value / scaleDivisor;
|
|
||||||
|
|
||||||
return getDoubleFromFloat128(tmpval);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
@brief The method converts a wide decimal value to a double.
|
|
||||||
*/
|
|
||||||
static inline double getDoubleFromWideDecimal(const int128_t& value)
|
|
||||||
{
|
|
||||||
return getDoubleFromFloat128(static_cast<__float128>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
@brief The method converts a wide decimal value to a long double.
|
|
||||||
*/
|
|
||||||
static inline long double getLongDoubleFromWideDecimal(const int128_t& value)
|
|
||||||
{
|
|
||||||
return getLongDoubleFromFloat128(static_cast<__float128>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief The method converts a wide decimal value to an int64_t,
|
@brief The method converts a wide decimal value to an int64_t,
|
||||||
saturating the value if necessary.
|
saturating the value if necessary.
|
||||||
@ -598,6 +569,35 @@ class VDecimal: public TSInt128
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline TSInt128 toTSInt128() const
|
||||||
|
{
|
||||||
|
return TSInt128(s128Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TFloat128 toTFloat128() const
|
||||||
|
{
|
||||||
|
return TFloat128(s128Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double toDouble() const
|
||||||
|
{
|
||||||
|
int128_t scaleDivisor;
|
||||||
|
getScaleDivisor(scaleDivisor, scale);
|
||||||
|
datatypes::TFloat128 tmpval((__float128) s128Value / scaleDivisor);
|
||||||
|
return static_cast<double>(tmpval);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator double() const
|
||||||
|
{
|
||||||
|
return toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long double toLongDouble() const
|
||||||
|
{
|
||||||
|
datatypes::TFloat128 y(s128Value);
|
||||||
|
return static_cast<long double>(y);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const VDecimal& rhs) const
|
bool operator==(const VDecimal& rhs) const
|
||||||
{
|
{
|
||||||
if (precision > datatypes::INT64MAXPRECISION &&
|
if (precision > datatypes::INT64MAXPRECISION &&
|
||||||
|
87
datatypes/mcs_float128.h
Normal file
87
datatypes/mcs_float128.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2020 MariaDB Corporation
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; version 2 of
|
||||||
|
the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#ifndef MCS_TSFLOAT128_H_INCLUDED
|
||||||
|
#define MCS_TSFLOAT128_H_INCLUDED
|
||||||
|
|
||||||
|
#include <cfloat>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace datatypes
|
||||||
|
{
|
||||||
|
|
||||||
|
//class TSInt128;
|
||||||
|
using int128_t = __int128;
|
||||||
|
|
||||||
|
class TFloat128
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint16_t MAXLENGTH16BYTES = 42;
|
||||||
|
// A variety of ctors for aligned and unaligned arguments
|
||||||
|
TFloat128(): value(0) { }
|
||||||
|
|
||||||
|
// aligned argument
|
||||||
|
TFloat128(const __float128& x) { value = x; }
|
||||||
|
TFloat128(const int128_t& x) { value = static_cast<__float128>(x); }
|
||||||
|
|
||||||
|
// Method returns max length of a string representation
|
||||||
|
static constexpr uint8_t maxLength()
|
||||||
|
{
|
||||||
|
return TFloat128::MAXLENGTH16BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The method converts a TFloat128 to integral types
|
||||||
|
inline operator double() const
|
||||||
|
{
|
||||||
|
return toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double toDouble() const
|
||||||
|
{
|
||||||
|
if (value > static_cast<__float128>(DBL_MAX))
|
||||||
|
return DBL_MAX;
|
||||||
|
else if (value < -static_cast<__float128>(DBL_MAX))
|
||||||
|
return -DBL_MAX;
|
||||||
|
|
||||||
|
return static_cast<double>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator long double() const
|
||||||
|
{
|
||||||
|
return toLongDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline long double toLongDouble() const
|
||||||
|
{
|
||||||
|
if (value > static_cast<__float128>(LDBL_MAX))
|
||||||
|
return LDBL_MAX;
|
||||||
|
else if (value < -static_cast<__float128>(LDBL_MAX))
|
||||||
|
return -LDBL_MAX;
|
||||||
|
|
||||||
|
return static_cast<long double>(value);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
__float128 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} //end of namespace
|
||||||
|
|
||||||
|
#endif // MCS_TSFLOAT128_H_INCLUDED
|
||||||
|
// vim:ts=2 sw=2:
|
||||||
|
|
@ -24,18 +24,6 @@
|
|||||||
|
|
||||||
namespace datatypes
|
namespace datatypes
|
||||||
{
|
{
|
||||||
// The method converts a wide decimal s128Value to a double.
|
|
||||||
inline double TSInt128::getDoubleFromWideDecimal()
|
|
||||||
{
|
|
||||||
return getDoubleFromFloat128(static_cast<__float128>(s128Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// The method converts a wide decimal s128Value to a long double.
|
|
||||||
inline long double TSInt128::getLongDoubleFromWideDecimal()
|
|
||||||
{
|
|
||||||
return getLongDoubleFromFloat128(static_cast<__float128>(s128Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t TSInt128::printPodParts(char* buf,
|
uint8_t TSInt128::printPodParts(char* buf,
|
||||||
const int128_t& high,
|
const int128_t& high,
|
||||||
const int128_t& mid,
|
const int128_t& mid,
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "mcs_float128.h"
|
||||||
|
|
||||||
// Inline asm has three argument lists: output, input and clobber list
|
// Inline asm has three argument lists: output, input and clobber list
|
||||||
#if defined(__GNUC__) && (__GNUC___ > 7)
|
#if defined(__GNUC__) && (__GNUC___ > 7)
|
||||||
@ -111,30 +112,6 @@ struct is_uint128_t<uint128_t> {
|
|||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The method converts a __float128 s128Value to a double.
|
|
||||||
static inline double getDoubleFromFloat128(const __float128& value)
|
|
||||||
{
|
|
||||||
if (value > static_cast<__float128>(DBL_MAX))
|
|
||||||
return DBL_MAX;
|
|
||||||
else if (value < -static_cast<__float128>(DBL_MAX))
|
|
||||||
return -DBL_MAX;
|
|
||||||
|
|
||||||
return static_cast<double>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// The method converts a __float128 value to a long double.
|
|
||||||
static inline long double getLongDoubleFromFloat128(const __float128& value)
|
|
||||||
{
|
|
||||||
if (value > static_cast<__float128>(LDBL_MAX))
|
|
||||||
return LDBL_MAX;
|
|
||||||
else if (value < -static_cast<__float128>(LDBL_MAX))
|
|
||||||
return -LDBL_MAX;
|
|
||||||
|
|
||||||
return static_cast<long double>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TSInt128
|
class TSInt128
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -203,6 +180,36 @@ class TSInt128
|
|||||||
return s128Value == static_cast<int128_t>(x);
|
return s128Value == static_cast<int128_t>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline operator double() const
|
||||||
|
{
|
||||||
|
return toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long double toDouble() const
|
||||||
|
{
|
||||||
|
return static_cast<double>(s128Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator long double() const
|
||||||
|
{
|
||||||
|
return toLongDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long double toLongDouble() const
|
||||||
|
{
|
||||||
|
return static_cast<long double>(s128Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator TFloat128() const
|
||||||
|
{
|
||||||
|
return toTFloat128();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TFloat128 toTFloat128() const
|
||||||
|
{
|
||||||
|
return TFloat128(s128Value);
|
||||||
|
}
|
||||||
|
|
||||||
// print int128_t parts represented as PODs
|
// print int128_t parts represented as PODs
|
||||||
uint8_t printPodParts(char* buf,
|
uint8_t printPodParts(char* buf,
|
||||||
const int128_t& high,
|
const int128_t& high,
|
||||||
@ -219,12 +226,6 @@ class TSInt128
|
|||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const TSInt128& x);
|
friend std::ostream& operator<<(std::ostream& os, const TSInt128& x);
|
||||||
|
|
||||||
// The method converts a wide decimal s128Value to a double.
|
|
||||||
inline double getDoubleFromWideDecimal();
|
|
||||||
|
|
||||||
// The method converts a wide decimal s128Value to a long double.
|
|
||||||
inline long double getLongDoubleFromWideDecimal();
|
|
||||||
|
|
||||||
// The method converts a wide decimal s128Value to an int64_t,
|
// The method converts a wide decimal s128Value to an int64_t,
|
||||||
// saturating the s128Value if necessary.
|
// saturating the s128Value if necessary.
|
||||||
inline int64_t getInt64FromWideDecimal();
|
inline int64_t getInt64FromWideDecimal();
|
||||||
|
@ -927,7 +927,7 @@ inline double TreeNode::getDoubleVal()
|
|||||||
{
|
{
|
||||||
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
|
if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
return datatypes::Decimal::getDoubleFromWideDecimal(fResult.decimalVal.s128Value, fResult.decimalVal.scale);
|
return static_cast<double>(fResult.decimalVal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1881,9 +1881,11 @@ double Func_cast_decimal::getDoubleVal(Row& row,
|
|||||||
isNull,
|
isNull,
|
||||||
operationColType);
|
operationColType);
|
||||||
|
|
||||||
|
// WIP MCOL-641 This could deliver wrong result b/c wide DECIMAL might have
|
||||||
|
// p <= INT64MAXPRECISION
|
||||||
if (decimal.precision > datatypes::INT64MAXPRECISION)
|
if (decimal.precision > datatypes::INT64MAXPRECISION)
|
||||||
{
|
{
|
||||||
return datatypes::Decimal::getDoubleFromWideDecimal(decimal.s128Value, decimal.scale);
|
return static_cast<double>(decimal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (double) decimal.value / helpers::powerOf10_c[decimal.scale];
|
return (double) decimal.value / helpers::powerOf10_c[decimal.scale];
|
||||||
@ -1994,7 +1996,7 @@ double Func_cast_double::getDoubleVal(Row& row,
|
|||||||
|
|
||||||
if (parm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
if (parm[0]->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
dblval = datatypes::Decimal::getDoubleFromWideDecimal(decimal.s128Value, decimal.scale);
|
dblval = static_cast<double>(decimal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -392,7 +392,7 @@ double Func_ceil::getDoubleVal(Row& row,
|
|||||||
|
|
||||||
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
ret = datatypes::Decimal::getDoubleFromWideDecimal(tmp.s128Value);
|
ret = static_cast<double>(tmp.toTSInt128());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -448,7 +448,7 @@ long double Func_ceil::getLongDoubleVal(Row& row,
|
|||||||
|
|
||||||
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
ret = datatypes::Decimal::getLongDoubleFromWideDecimal(tmp.s128Value);
|
ret = static_cast<long double>(tmp.toTSInt128());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -330,7 +330,7 @@ double Func_floor::getDoubleVal(Row& row,
|
|||||||
|
|
||||||
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
ret = datatypes::Decimal::getDoubleFromWideDecimal(tmp.s128Value);
|
ret = static_cast<double>(tmp.toTSInt128());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -377,7 +377,7 @@ long double Func_floor::getLongDoubleVal(Row& row,
|
|||||||
|
|
||||||
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||||
{
|
{
|
||||||
ret = datatypes::Decimal::getLongDoubleFromWideDecimal(tmp.s128Value);
|
ret = static_cast<long double>(tmp.toTSInt128());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -241,8 +241,8 @@ double Func_mod::getDoubleVal(Row& row,
|
|||||||
datatypes::getScaleDivisor(scaleDivisor, d.scale);
|
datatypes::getScaleDivisor(scaleDivisor, d.scale);
|
||||||
int128_t value = d.s128Value / scaleDivisor;
|
int128_t value = d.s128Value / scaleDivisor;
|
||||||
int128_t lefto = d.s128Value % scaleDivisor;
|
int128_t lefto = d.s128Value % scaleDivisor;
|
||||||
__float128 tmp = (__float128) (value % div) + (__float128) lefto / scaleDivisor;
|
datatypes::TFloat128 tmp((__float128) (value % div) + (__float128) lefto / scaleDivisor);
|
||||||
mod = datatypes::getDoubleFromFloat128(tmp);
|
mod = static_cast<double>(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -364,8 +364,8 @@ long double Func_mod::getLongDoubleVal(Row& row,
|
|||||||
datatypes::getScaleDivisor(scaleDivisor, d.scale);
|
datatypes::getScaleDivisor(scaleDivisor, d.scale);
|
||||||
int128_t value = d.s128Value / scaleDivisor;
|
int128_t value = d.s128Value / scaleDivisor;
|
||||||
int128_t lefto = d.s128Value % scaleDivisor;
|
int128_t lefto = d.s128Value % scaleDivisor;
|
||||||
__float128 tmp = (__float128) (value % div) + (__float128) lefto / scaleDivisor;
|
datatypes::TFloat128 tmp((__float128) (value % div) + (__float128) lefto / scaleDivisor);
|
||||||
mod = datatypes::getLongDoubleFromFloat128(tmp);
|
mod = static_cast<long double>(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -221,7 +221,7 @@ double Func_round::getDoubleVal(Row& row,
|
|||||||
if (!op_ct.isWideDecimalType())
|
if (!op_ct.isWideDecimalType())
|
||||||
d = x.value;
|
d = x.value;
|
||||||
else
|
else
|
||||||
d = datatypes::Decimal::getDoubleFromWideDecimal(x.s128Value);
|
d = static_cast<double>(x.toTSInt128());
|
||||||
|
|
||||||
if (x.scale > 0)
|
if (x.scale > 0)
|
||||||
{
|
{
|
||||||
@ -288,7 +288,7 @@ long double Func_round::getLongDoubleVal(Row& row,
|
|||||||
if (!op_ct.isWideDecimalType())
|
if (!op_ct.isWideDecimalType())
|
||||||
d = x.value;
|
d = x.value;
|
||||||
else
|
else
|
||||||
d = datatypes::Decimal::getDoubleFromWideDecimal(x.s128Value);
|
d = static_cast<double>(x.toTSInt128());
|
||||||
|
|
||||||
if (x.scale > 0)
|
if (x.scale > 0)
|
||||||
{
|
{
|
||||||
|
@ -233,7 +233,7 @@ double Func_truncate::getDoubleVal(Row& row,
|
|||||||
if (!op_ct.isWideDecimalType())
|
if (!op_ct.isWideDecimalType())
|
||||||
d = x.value;
|
d = x.value;
|
||||||
else
|
else
|
||||||
d = datatypes::Decimal::getDoubleFromWideDecimal(x.s128Value);
|
d = static_cast<double>(x.toTSInt128());
|
||||||
|
|
||||||
if (x.scale > 0)
|
if (x.scale > 0)
|
||||||
{
|
{
|
||||||
@ -293,7 +293,7 @@ long double Func_truncate::getLongDoubleVal(Row& row,
|
|||||||
if (!op_ct.isWideDecimalType())
|
if (!op_ct.isWideDecimalType())
|
||||||
d = x.value;
|
d = x.value;
|
||||||
else
|
else
|
||||||
d = datatypes::Decimal::getDoubleFromWideDecimal(x.s128Value);
|
d = static_cast<double>(x.toTSInt128());
|
||||||
|
|
||||||
if (x.scale > 0)
|
if (x.scale > 0)
|
||||||
{
|
{
|
||||||
|
@ -2045,8 +2045,9 @@ void RowAggregation::doStatistics(const Row& rowIn, int64_t colIn, int64_t colOu
|
|||||||
case execplan::CalpontSystemCatalog::UDECIMAL: // handle scale later
|
case execplan::CalpontSystemCatalog::UDECIMAL: // handle scale later
|
||||||
if (LIKELY(fRowGroupIn.getColumnWidth(colIn) == datatypes::MAXDECIMALWIDTH))
|
if (LIKELY(fRowGroupIn.getColumnWidth(colIn) == datatypes::MAXDECIMALWIDTH))
|
||||||
{
|
{
|
||||||
int128_t* val128InPtr = rowIn.getBinaryField<int128_t>(colIn);
|
// To save from unaligned memory
|
||||||
valIn = Dec::getLongDoubleFromWideDecimal(*val128InPtr);
|
datatypes::TSInt128 val128In(rowIn.getBinaryField<int128_t>(colIn));
|
||||||
|
valIn = static_cast<long double>(val128In.toTFloat128());
|
||||||
}
|
}
|
||||||
else if (fRowGroupIn.getColumnWidth(colIn) <= datatypes::MAXLEGACYWIDTH)
|
else if (fRowGroupIn.getColumnWidth(colIn) <= datatypes::MAXLEGACYWIDTH)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user