mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-21 09:10:48 +00:00
Make Field::getScaleMultiplier() inline to allow using FieldVisitorConvertToNumber
in the "clickhouse_parsers" library.
This commit is contained in:
parent
3e6619c076
commit
8035af3a79
@ -3,11 +3,18 @@
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#include <Core/Defines.h>
|
||||
|
||||
// Also defined in Core/Defines.h
|
||||
#if !defined(NO_SANITIZE_UNDEFINED)
|
||||
#if defined(__clang__)
|
||||
#define NO_SANITIZE_UNDEFINED __attribute__((__no_sanitize__("undefined")))
|
||||
#else
|
||||
#define NO_SANITIZE_UNDEFINED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/// On overlow, the function returns unspecified value.
|
||||
|
||||
inline NO_SANITIZE_UNDEFINED uint64_t intExp2(int x)
|
||||
{
|
||||
return 1ULL << x;
|
||||
|
@ -88,9 +88,9 @@ public:
|
||||
|
||||
Shift shift;
|
||||
if (scale_a < scale_b)
|
||||
shift.a = DataTypeDecimal<B>(maxDecimalPrecision<B>(), scale_b).getScaleMultiplier(scale_b - scale_a);
|
||||
shift.a = B::getScaleMultiplier(scale_b - scale_a);
|
||||
if (scale_a > scale_b)
|
||||
shift.b = DataTypeDecimal<A>(maxDecimalPrecision<A>(), scale_a).getScaleMultiplier(scale_a - scale_b);
|
||||
shift.b = A::getScaleMultiplier(scale_a - scale_b);
|
||||
|
||||
return applyWithScale(a, b, shift);
|
||||
}
|
||||
|
@ -300,21 +300,6 @@ namespace DB
|
||||
}
|
||||
|
||||
|
||||
template <> Decimal32 DecimalField<Decimal32>::getScaleMultiplier() const
|
||||
{
|
||||
return DataTypeDecimal<Decimal32>::getScaleMultiplier(scale);
|
||||
}
|
||||
|
||||
template <> Decimal64 DecimalField<Decimal64>::getScaleMultiplier() const
|
||||
{
|
||||
return DataTypeDecimal<Decimal64>::getScaleMultiplier(scale);
|
||||
}
|
||||
|
||||
template <> Decimal128 DecimalField<Decimal128>::getScaleMultiplier() const
|
||||
{
|
||||
return DataTypeDecimal<Decimal128>::getScaleMultiplier(scale);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool decEqual(T x, T y, UInt32 x_scale, UInt32 y_scale)
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
|
||||
operator T() const { return dec; }
|
||||
T getValue() const { return dec; }
|
||||
T getScaleMultiplier() const;
|
||||
T getScaleMultiplier() const { return T::getScaleMultiplier(scale); }
|
||||
UInt32 getScale() const { return scale; }
|
||||
|
||||
template <typename U>
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <common/Types.h>
|
||||
#include <Common/intExp.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -145,6 +146,8 @@ struct Decimal
|
||||
const Decimal<T> & operator /= (const T & x) { value /= x; return *this; }
|
||||
const Decimal<T> & operator %= (const T & x) { value %= x; return *this; }
|
||||
|
||||
static T getScaleMultiplier(UInt32 scale);
|
||||
|
||||
T value;
|
||||
};
|
||||
|
||||
@ -170,6 +173,10 @@ template <> struct NativeType<Decimal32> { using Type = Int32; };
|
||||
template <> struct NativeType<Decimal64> { using Type = Int64; };
|
||||
template <> struct NativeType<Decimal128> { using Type = Int128; };
|
||||
|
||||
template <> inline Int32 Decimal32::getScaleMultiplier(UInt32 scale) { return common::exp10_i32(scale); }
|
||||
template <> inline Int64 Decimal64::getScaleMultiplier(UInt32 scale) { return common::exp10_i64(scale); }
|
||||
template <> inline Int128 Decimal128::getScaleMultiplier(UInt32 scale) { return common::exp10_i128(scale); }
|
||||
|
||||
inline const char * getTypeName(TypeIndex idx)
|
||||
{
|
||||
switch (idx)
|
||||
|
@ -58,7 +58,7 @@ bool DataTypeDecimal<T>::tryReadText(T & x, ReadBuffer & istr, UInt32 precision,
|
||||
{
|
||||
UInt32 unread_scale = scale;
|
||||
bool done = tryReadDecimalText(istr, x, precision, unread_scale);
|
||||
x *= getScaleMultiplier(unread_scale);
|
||||
x *= T::getScaleMultiplier(unread_scale);
|
||||
return done;
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ void DataTypeDecimal<T>::readText(T & x, ReadBuffer & istr, UInt32 precision, UI
|
||||
readCSVDecimalText(istr, x, precision, unread_scale);
|
||||
else
|
||||
readDecimalText(istr, x, precision, unread_scale);
|
||||
x *= getScaleMultiplier(unread_scale);
|
||||
x *= T::getScaleMultiplier(unread_scale);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -96,7 +96,7 @@ T DataTypeDecimal<T>::parseFromString(const String & str) const
|
||||
T x;
|
||||
UInt32 unread_scale = scale;
|
||||
readDecimalText(buf, x, precision, unread_scale, true);
|
||||
x *= getScaleMultiplier(unread_scale);
|
||||
x *= T::getScaleMultiplier(unread_scale);
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -271,25 +271,6 @@ void registerDataTypeDecimal(DataTypeFactory & factory)
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
Decimal32 DataTypeDecimal<Decimal32>::getScaleMultiplier(UInt32 scale_)
|
||||
{
|
||||
return decimalScaleMultiplier<Int32>(scale_);
|
||||
}
|
||||
|
||||
template <>
|
||||
Decimal64 DataTypeDecimal<Decimal64>::getScaleMultiplier(UInt32 scale_)
|
||||
{
|
||||
return decimalScaleMultiplier<Int64>(scale_);
|
||||
}
|
||||
|
||||
template <>
|
||||
Decimal128 DataTypeDecimal<Decimal128>::getScaleMultiplier(UInt32 scale_)
|
||||
{
|
||||
return decimalScaleMultiplier<Int128>(scale_);
|
||||
}
|
||||
|
||||
|
||||
/// Explicit template instantiations.
|
||||
template class DataTypeDecimal<Decimal32>;
|
||||
template class DataTypeDecimal<Decimal64>;
|
||||
|
@ -130,7 +130,7 @@ public:
|
||||
|
||||
UInt32 getPrecision() const { return precision; }
|
||||
UInt32 getScale() const { return scale; }
|
||||
T getScaleMultiplier() const { return getScaleMultiplier(scale); }
|
||||
T getScaleMultiplier() const { return T::getScaleMultiplier(scale); }
|
||||
|
||||
T wholePart(T x) const
|
||||
{
|
||||
@ -148,7 +148,7 @@ public:
|
||||
return x % getScaleMultiplier();
|
||||
}
|
||||
|
||||
T maxWholeValue() const { return getScaleMultiplier(maxPrecision() - scale) - T(1); }
|
||||
T maxWholeValue() const { return T::getScaleMultiplier(maxPrecision() - scale) - T(1); }
|
||||
|
||||
bool canStoreWhole(T x) const
|
||||
{
|
||||
@ -165,7 +165,7 @@ public:
|
||||
if (getScale() < x.getScale())
|
||||
throw Exception("Decimal result's scale is less then argiment's one", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
|
||||
UInt32 scale_delta = getScale() - x.getScale(); /// scale_delta >= 0
|
||||
return getScaleMultiplier(scale_delta);
|
||||
return T::getScaleMultiplier(scale_delta);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
@ -181,7 +181,6 @@ public:
|
||||
void readText(T & x, ReadBuffer & istr, bool csv = false) const { readText(x, istr, precision, scale, csv); }
|
||||
static void readText(T & x, ReadBuffer & istr, UInt32 precision, UInt32 scale, bool csv = false);
|
||||
static bool tryReadText(T & x, ReadBuffer & istr, UInt32 precision, UInt32 scale);
|
||||
static T getScaleMultiplier(UInt32 scale);
|
||||
|
||||
private:
|
||||
const UInt32 precision;
|
||||
@ -264,12 +263,12 @@ convertDecimals(const typename FromDataType::FieldType & value, UInt32 scale_fro
|
||||
MaxNativeType converted_value;
|
||||
if (scale_to > scale_from)
|
||||
{
|
||||
converted_value = DataTypeDecimal<MaxFieldType>::getScaleMultiplier(scale_to - scale_from);
|
||||
converted_value = MaxFieldType::getScaleMultiplier(scale_to - scale_from);
|
||||
if (common::mulOverflow(static_cast<MaxNativeType>(value), converted_value, converted_value))
|
||||
throw Exception("Decimal convert overflow", ErrorCodes::DECIMAL_OVERFLOW);
|
||||
}
|
||||
else
|
||||
converted_value = value / DataTypeDecimal<MaxFieldType>::getScaleMultiplier(scale_from - scale_to);
|
||||
converted_value = value / MaxFieldType::getScaleMultiplier(scale_from - scale_to);
|
||||
|
||||
if constexpr (sizeof(FromFieldType) > sizeof(ToFieldType))
|
||||
{
|
||||
@ -289,7 +288,7 @@ convertFromDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
|
||||
if constexpr (std::is_floating_point_v<ToFieldType>)
|
||||
return static_cast<ToFieldType>(value) / FromDataType::getScaleMultiplier(scale);
|
||||
return static_cast<ToFieldType>(value) / FromFieldType::getScaleMultiplier(scale);
|
||||
else
|
||||
{
|
||||
FromFieldType converted_value = convertDecimals<FromDataType, FromDataType>(value, scale, 0);
|
||||
@ -320,14 +319,15 @@ inline std::enable_if_t<IsDataTypeNumber<FromDataType> && IsDataTypeDecimal<ToDa
|
||||
convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
|
||||
{
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToNativeType = typename ToDataType::FieldType::NativeType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
using ToNativeType = typename ToFieldType::NativeType;
|
||||
|
||||
if constexpr (std::is_floating_point_v<FromFieldType>)
|
||||
{
|
||||
if (!std::isfinite(value))
|
||||
throw Exception("Decimal convert overflow. Cannot convert infinity or NaN to decimal", ErrorCodes::DECIMAL_OVERFLOW);
|
||||
|
||||
auto out = value * ToDataType::getScaleMultiplier(scale);
|
||||
auto out = value * ToFieldType::getScaleMultiplier(scale);
|
||||
if constexpr (std::is_same_v<ToNativeType, Int128>)
|
||||
{
|
||||
static constexpr __int128 min_int128 = __int128(0x8000000000000000ll) << 64;
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <Common/Exception.h>
|
||||
#include <Common/StringUtils/StringUtils.h>
|
||||
#include <Common/UInt128.h>
|
||||
#include <Common/intExp.h>
|
||||
|
||||
#include <IO/CompressionMethod.h>
|
||||
#include <IO/WriteBuffer.h>
|
||||
@ -764,12 +763,6 @@ inline void writeText(const LocalDateTime & x, WriteBuffer & buf) { writeDateTim
|
||||
inline void writeText(const UUID & x, WriteBuffer & buf) { writeUUIDText(x, buf); }
|
||||
inline void writeText(const UInt128 & x, WriteBuffer & buf) { writeText(UUID(x), buf); }
|
||||
|
||||
template <typename T> inline T decimalScaleMultiplier(UInt32 scale);
|
||||
template <> inline Int32 decimalScaleMultiplier<Int32>(UInt32 scale) { return common::exp10_i32(scale); }
|
||||
template <> inline Int64 decimalScaleMultiplier<Int64>(UInt32 scale) { return common::exp10_i64(scale); }
|
||||
template <> inline Int128 decimalScaleMultiplier<Int128>(UInt32 scale) { return common::exp10_i128(scale); }
|
||||
|
||||
|
||||
template <typename T>
|
||||
void writeText(Decimal<T> value, UInt32 scale, WriteBuffer & ostr)
|
||||
{
|
||||
@ -781,7 +774,7 @@ void writeText(Decimal<T> value, UInt32 scale, WriteBuffer & ostr)
|
||||
|
||||
T whole_part = value;
|
||||
if (scale)
|
||||
whole_part = value / decimalScaleMultiplier<T>(scale);
|
||||
whole_part = value / Decimal<T>::getScaleMultiplier(scale);
|
||||
|
||||
writeIntText(whole_part, ostr);
|
||||
if (scale)
|
||||
|
Loading…
Reference in New Issue
Block a user