Miscellaneous [#CLICKHOUSE-3765]

This commit is contained in:
Alexey Milovidov 2018-08-21 07:31:35 +03:00
parent 15c971a225
commit 7d76c3fd4f
11 changed files with 130 additions and 135 deletions

View File

@ -331,7 +331,7 @@ template class ColumnVector<Int128>;
template class ColumnVector<Float32>;
template class ColumnVector<Float64>;
template class ColumnVector<Dec32>;
template class ColumnVector<Dec64>;
template class ColumnVector<Dec128>;
template class ColumnVector<Decimal32>;
template class ColumnVector<Decimal64>;
template class ColumnVector<Decimal128>;
}

View File

@ -125,24 +125,24 @@ template <> inline UInt64 unionCastToUInt64(Float32 x)
/// PaddedPODArray extended by Decimal scale
template <typename T>
class DecPaddedPODArray : public PaddedPODArray<T>
class DecimalPaddedPODArray : public PaddedPODArray<T>
{
public:
using Base = PaddedPODArray<T>;
using Base::operator[];
using Base::Base;
DecPaddedPODArray(std::initializer_list<T> il)
: DecPaddedPODArray(std::begin(il), std::end(il))
DecimalPaddedPODArray(std::initializer_list<T> il)
: DecimalPaddedPODArray(std::begin(il), std::end(il))
{}
DecPaddedPODArray(DecPaddedPODArray && other)
DecimalPaddedPODArray(DecimalPaddedPODArray && other)
{
this->swap(other);
std::swap(scale, other.scale);
}
DecPaddedPODArray & operator=(DecPaddedPODArray && other)
DecimalPaddedPODArray & operator=(DecimalPaddedPODArray && other)
{
this->swap(other);
std::swap(scale, other.scale);
@ -153,7 +153,7 @@ public:
UInt32 getScale() const { return scale; }
private:
UInt32 scale = DecField::wrongScale();
UInt32 scale = DecimalField::wrongScale();
};
@ -171,7 +171,7 @@ private:
public:
using value_type = T;
using Container = std::conditional_t<decTrait<T>(), DecPaddedPODArray<value_type>, PaddedPODArray<value_type>>;
using Container = std::conditional_t<IsDecimalNumber<T>, DecimalPaddedPODArray<value_type>, PaddedPODArray<value_type>>;
private:
ColumnVector() {}
@ -255,12 +255,12 @@ public:
Field operator[](size_t n) const override
{
if constexpr (decTrait<T>())
if constexpr (IsDecimalNumber<T>)
{
UInt32 scale = data.getScale();
if (scale == DecField::wrongScale())
if (scale == DecimalField::wrongScale())
throw Exception("Extracting Decimal field with unknown scale. Scale is lost.", ErrorCodes::LOGICAL_ERROR);
return DecField(data[n], scale);
return DecimalField(data[n], scale);
}
else
return typename NearestFieldType<T>::Type(data[n]);

View File

@ -273,21 +273,21 @@ namespace DB
}
bool DecField::operator < (const DecField & r) const
bool DecimalField::operator < (const DecimalField & r) const
{
using Comparator = DecimalComparison<Dec128, Dec128, LessOp>;
return Comparator::compare(Dec128(dec), Dec128(r.dec), scale, r.scale);
using Comparator = DecimalComparison<Decimal128, Decimal128, LessOp>;
return Comparator::compare(Decimal128(dec), Decimal128(r.dec), scale, r.scale);
}
bool DecField::operator <= (const DecField & r) const
bool DecimalField::operator <= (const DecimalField & r) const
{
using Comparator = DecimalComparison<Dec128, Dec128, LessOrEqualsOp>;
return Comparator::compare(Dec128(dec), Dec128(r.dec), scale, r.scale);
using Comparator = DecimalComparison<Decimal128, Decimal128, LessOrEqualsOp>;
return Comparator::compare(Decimal128(dec), Decimal128(r.dec), scale, r.scale);
}
bool DecField::operator == (const DecField & r) const
bool DecimalField::operator == (const DecimalField & r) const
{
using Comparator = DecimalComparison<Dec128, Dec128, EqualsOp>;
return Comparator::compare(Dec128(dec), Dec128(r.dec), scale, r.scale);
using Comparator = DecimalComparison<Decimal128, Decimal128, EqualsOp>;
return Comparator::compare(Decimal128(dec), Decimal128(r.dec), scale, r.scale);
}
}

View File

@ -28,29 +28,29 @@ using TupleBackend = std::vector<Field>;
STRONG_TYPEDEF(TupleBackend, Tuple) /// Array and Tuple are different types with equal representation inside Field.
class DecField
class DecimalField
{
public:
static constexpr UInt32 wrongScale() { return std::numeric_limits<UInt32>::max(); }
DecField(Int128 value, UInt32 scale_ = wrongScale())
DecimalField(Int128 value, UInt32 scale_ = wrongScale())
: dec(value),
scale(scale_)
{}
operator Dec32() const { return dec; }
operator Dec64() const { return dec; }
operator Dec128() const { return dec; }
operator Decimal32() const { return dec; }
operator Decimal64() const { return dec; }
operator Decimal128() const { return dec; }
UInt32 getScale() const { return scale; }
bool operator < (const DecField & r) const;
bool operator <= (const DecField & r) const;
bool operator == (const DecField & r) const;
bool operator < (const DecimalField & r) const;
bool operator <= (const DecimalField & r) const;
bool operator == (const DecimalField & r) const;
bool operator > (const DecField & r) const { return r < *this; }
bool operator >= (const DecField & r) const { return r <= * this; }
bool operator != (const DecField & r) const { return !(*this == r); }
bool operator > (const DecimalField & r) const { return r < *this; }
bool operator >= (const DecimalField & r) const { return r <= * this; }
bool operator != (const DecimalField & r) const { return !(*this == r); }
private:
Int128 dec;
@ -294,7 +294,7 @@ public:
case Types::String: return get<String>() < rhs.get<String>();
case Types::Array: return get<Array>() < rhs.get<Array>();
case Types::Tuple: return get<Tuple>() < rhs.get<Tuple>();
case Types::Decimal: return get<DecField>() < rhs.get<DecField>();
case Types::Decimal: return get<DecimalField>() < rhs.get<DecimalField>();
}
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
@ -323,7 +323,7 @@ public:
case Types::String: return get<String>() <= rhs.get<String>();
case Types::Array: return get<Array>() <= rhs.get<Array>();
case Types::Tuple: return get<Tuple>() <= rhs.get<Tuple>();
case Types::Decimal: return get<DecField>() <= rhs.get<DecField>();
case Types::Decimal: return get<DecimalField>() <= rhs.get<DecimalField>();
}
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
@ -350,7 +350,7 @@ public:
case Types::Tuple: return get<Tuple>() == rhs.get<Tuple>();
case Types::UInt128: return get<UInt128>() == rhs.get<UInt128>();
case Types::Int128: return get<Int128>() == rhs.get<Int128>();
case Types::Decimal: return get<DecField>() == rhs.get<DecField>();
case Types::Decimal: return get<DecimalField>() == rhs.get<DecimalField>();
}
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
@ -363,7 +363,7 @@ public:
private:
std::aligned_union_t<DBMS_MIN_FIELD_SIZE - sizeof(Types::Which),
Null, UInt64, UInt128, Int64, Int128, Float64, String, Array, Tuple, DecField
Null, UInt64, UInt128, Int64, Int128, Float64, String, Array, Tuple, DecimalField
> storage;
Types::Which which;
@ -412,7 +412,7 @@ private:
case Types::String: f(field.template get<String>()); return;
case Types::Array: f(field.template get<Array>()); return;
case Types::Tuple: f(field.template get<Tuple>()); return;
case Types::Decimal: f(field.template get<DecField>()); return;
case Types::Decimal: f(field.template get<DecimalField>()); return;
default:
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
@ -496,7 +496,7 @@ template <> struct Field::TypeToEnum<Float64> { static const Types::Which value
template <> struct Field::TypeToEnum<String> { static const Types::Which value = Types::String; };
template <> struct Field::TypeToEnum<Array> { static const Types::Which value = Types::Array; };
template <> struct Field::TypeToEnum<Tuple> { static const Types::Which value = Types::Tuple; };
template <> struct Field::TypeToEnum<DecField>{ static const Types::Which value = Types::Decimal; };
template <> struct Field::TypeToEnum<DecimalField>{ static const Types::Which value = Types::Decimal; };
template <> struct Field::EnumToType<Field::Types::Null> { using Type = Null; };
template <> struct Field::EnumToType<Field::Types::UInt64> { using Type = UInt64; };
@ -507,7 +507,7 @@ template <> struct Field::EnumToType<Field::Types::Float64> { using Type = Float
template <> struct Field::EnumToType<Field::Types::String> { using Type = String; };
template <> struct Field::EnumToType<Field::Types::Array> { using Type = Array; };
template <> struct Field::EnumToType<Field::Types::Tuple> { using Type = Tuple; };
template <> struct Field::EnumToType<Field::Types::Decimal> { using Type = DecField; };
template <> struct Field::EnumToType<Field::Types::Decimal> { using Type = DecimalField; };
template <typename T>
@ -551,9 +551,9 @@ template <> struct NearestFieldType<Int16> { using Type = Int64; };
template <> struct NearestFieldType<Int32> { using Type = Int64; };
template <> struct NearestFieldType<Int64> { using Type = Int64; };
template <> struct NearestFieldType<Int128> { using Type = Int128; };
template <> struct NearestFieldType<Dec32> { using Type = DecField; };
template <> struct NearestFieldType<Dec64> { using Type = DecField; };
template <> struct NearestFieldType<Dec128> { using Type = DecField; };
template <> struct NearestFieldType<Decimal32> { using Type = DecimalField; };
template <> struct NearestFieldType<Decimal64> { using Type = DecimalField; };
template <> struct NearestFieldType<Decimal128> { using Type = DecimalField; };
template <> struct NearestFieldType<Float32> { using Type = Float64; };
template <> struct NearestFieldType<Float64> { using Type = Float64; };
template <> struct NearestFieldType<String> { using Type = String; };

View File

@ -118,60 +118,55 @@ template <> struct is_arithmetic<__int128>
namespace DB
{
/// Own FieldType for Decimal
/// Own FieldType for Decimal.
/// It is only a "storage" for decimal. To perform operations, you also have to provide a scale (number of digits after point).
template <typename T>
struct Dec
struct Decimal
{
using NativeType = T;
Dec() = default;
Dec(Dec<T> &&) = default;
Dec(const Dec<T> &) = default;
Decimal() = default;
Decimal(Decimal<T> &&) = default;
Decimal(const Decimal<T> &) = default;
Dec(const T & value_)
Decimal(const T & value_)
: value(value_)
{}
template <typename U>
Dec(const Dec<U> & x)
Decimal(const Decimal<U> & x)
: value(x)
{}
constexpr Dec<T> & operator = (Dec<T> &&) = default;
constexpr Dec<T> & operator = (const Dec<T> &) = default;
constexpr Decimal<T> & operator = (Decimal<T> &&) = default;
constexpr Decimal<T> & operator = (const Decimal<T> &) = default;
operator T () const { return value; }
const Dec<T> & operator += (const T & x) { value += x; return *this; }
const Dec<T> & operator -= (const T & x) { value -= x; return *this; }
const Dec<T> & operator *= (const T & x) { value *= x; return *this; }
const Dec<T> & operator /= (const T & x) { value /= x; return *this; }
const Dec<T> & operator %= (const T & x) { value %= x; return *this; }
const Decimal<T> & operator += (const T & x) { value += x; return *this; }
const Decimal<T> & operator -= (const T & x) { value -= x; return *this; }
const Decimal<T> & operator *= (const T & x) { value *= x; return *this; }
const Decimal<T> & operator /= (const T & x) { value /= x; return *this; }
const Decimal<T> & operator %= (const T & x) { value %= x; return *this; }
T value;
};
using Dec32 = Dec<Int32>;
using Dec64 = Dec<Int64>;
using Dec128 = Dec<Int128>;
using Decimal32 = Decimal<Int32>;
using Decimal64 = Decimal<Int64>;
using Decimal128 = Decimal<Int128>;
template <> struct TypeName<Dec32> { static const char * get() { return "Dec32"; } };
template <> struct TypeName<Dec64> { static const char * get() { return "Dec64"; } };
template <> struct TypeName<Dec128> { static const char * get() { return "Dec128"; } };
template <> struct TypeName<Decimal32> { static const char * get() { return "Decimal32"; } };
template <> struct TypeName<Decimal64> { static const char * get() { return "Decimal64"; } };
template <> struct TypeName<Decimal128> { static const char * get() { return "Decimal128"; } };
template <> struct TypeId<Dec32> { static constexpr const size_t value = 16; };
template <> struct TypeId<Dec64> { static constexpr const size_t value = 17; };
template <> struct TypeId<Dec128> { static constexpr const size_t value = 18; };
template <> struct TypeId<Decimal32> { static constexpr const size_t value = 16; };
template <> struct TypeId<Decimal64> { static constexpr const size_t value = 17; };
template <> struct TypeId<Decimal128> { static constexpr const size_t value = 18; };
template <typename T>
inline constexpr bool decTrait() { return false; }
template <> constexpr bool decTrait<Dec32>() { return true; }
template <> constexpr bool decTrait<Dec64>() { return true; }
template <> constexpr bool decTrait<Dec128>() { return true; }
template <typename T>
inline constexpr bool decBaseTrait() { return false; }
template <> constexpr bool decBaseTrait<Int32>() { return true; }
template <> constexpr bool decBaseTrait<Int64>() { return true; }
template <> constexpr bool decBaseTrait<Int128>() { return true; }
constexpr bool IsDecimalNumber = false;
template <> constexpr bool IsDecimalNumber<Decimal32> = true;
template <> constexpr bool IsDecimalNumber<Decimal64> = true;
template <> constexpr bool IsDecimalNumber<Decimal128> = true;
}

View File

@ -86,7 +86,7 @@ T DataTypeDecimal<T>::parseFromString(const String & str) const
template <typename T>
void DataTypeDecimal<T>::serializeBinary(const Field & field, WriteBuffer & ostr) const
{
FieldType x = get<DecField>(field);
FieldType x = get<DecimalField>(field);
writeBinary(x, ostr);
}
@ -116,7 +116,7 @@ void DataTypeDecimal<T>::deserializeBinary(Field & field, ReadBuffer & istr) con
{
typename FieldType::NativeType x;
readBinary(x, istr);
field = DecField(T(x), scale);
field = DecimalField(T(x), scale);
}
template <typename T>
@ -141,7 +141,7 @@ void DataTypeDecimal<T>::deserializeBinaryBulk(IColumn & column, ReadBuffer & is
template <typename T>
Field DataTypeDecimal<T>::getDefault() const
{
return DecField(T(0), scale);
return DecimalField(T(0), scale);
}
@ -172,17 +172,17 @@ static DataTypePtr create(const ASTPtr & arguments)
UInt64 precision_value = precision->value.get<UInt64>();
Int64 scale_value = scale->value.get<Int64>();
if (precision_value < minDecimalPrecision() || precision_value > maxDecimalPrecision<Dec128>())
if (precision_value < minDecimalPrecision() || precision_value > maxDecimalPrecision<Decimal128>())
throw Exception("Wrong precision", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
if (scale_value < 0 || static_cast<UInt64>(scale_value) > precision_value)
throw Exception("Negative scales and scales larger than presicion are not supported", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
if (precision_value <= maxDecimalPrecision<Dec32>())
return std::make_shared<DataTypeDecimal<Dec32>>(precision_value, scale_value);
else if (precision_value <= maxDecimalPrecision<Dec64>())
return std::make_shared<DataTypeDecimal<Dec64>>(precision_value, scale_value);
return std::make_shared<DataTypeDecimal<Dec128>>(precision_value, scale_value);
if (precision_value <= maxDecimalPrecision<Decimal32>())
return std::make_shared<DataTypeDecimal<Decimal32>>(precision_value, scale_value);
else if (precision_value <= maxDecimalPrecision<Decimal64>())
return std::make_shared<DataTypeDecimal<Decimal64>>(precision_value, scale_value);
return std::make_shared<DataTypeDecimal<Decimal128>>(precision_value, scale_value);
}
@ -194,27 +194,27 @@ void registerDataTypeDecimal(DataTypeFactory & factory)
template <>
Dec32 DataTypeDecimal<Dec32>::getScaleMultiplier(UInt32 scale_)
Decimal32 DataTypeDecimal<Decimal32>::getScaleMultiplier(UInt32 scale_)
{
return common::exp10_i32(scale_);
}
template <>
Dec64 DataTypeDecimal<Dec64>::getScaleMultiplier(UInt32 scale_)
Decimal64 DataTypeDecimal<Decimal64>::getScaleMultiplier(UInt32 scale_)
{
return common::exp10_i64(scale_);
}
template <>
Dec128 DataTypeDecimal<Dec128>::getScaleMultiplier(UInt32 scale_)
Decimal128 DataTypeDecimal<Decimal128>::getScaleMultiplier(UInt32 scale_)
{
return common::exp10_i128(scale_);
}
/// Explicit template instantiations.
template class DataTypeDecimal<Dec32>;
template class DataTypeDecimal<Dec64>;
template class DataTypeDecimal<Dec128>;
template class DataTypeDecimal<Decimal32>;
template class DataTypeDecimal<Decimal64>;
template class DataTypeDecimal<Decimal128>;
}

View File

@ -64,9 +64,9 @@ class DataTypeSimpleSerialization : public IDataType
static constexpr size_t minDecimalPrecision() { return 1; }
template <typename T> static constexpr size_t maxDecimalPrecision() { return 0; }
template <> constexpr size_t maxDecimalPrecision<Dec32>() { return 9; }
template <> constexpr size_t maxDecimalPrecision<Dec64>() { return 18; }
template <> constexpr size_t maxDecimalPrecision<Dec128>() { return 38; }
template <> constexpr size_t maxDecimalPrecision<Decimal32>() { return 9; }
template <> constexpr size_t maxDecimalPrecision<Decimal64>() { return 18; }
template <> constexpr size_t maxDecimalPrecision<Decimal128>() { return 38; }
/// Implements Decimal(P, S), where P is precision, S is scale.
@ -244,11 +244,11 @@ inline const DataTypeDecimal<T> * checkDecimal(const IDataType & data_type)
inline bool isDecimal(const IDataType & data_type)
{
if (typeid_cast<const DataTypeDecimal<Dec32> *>(&data_type))
if (typeid_cast<const DataTypeDecimal<Decimal32> *>(&data_type))
return true;
if (typeid_cast<const DataTypeDecimal<Dec64> *>(&data_type))
if (typeid_cast<const DataTypeDecimal<Decimal64> *>(&data_type))
return true;
if (typeid_cast<const DataTypeDecimal<Dec128> *>(&data_type))
if (typeid_cast<const DataTypeDecimal<Decimal128> *>(&data_type))
return true;
return false;
}

View File

@ -206,9 +206,9 @@ bool callByTypeAndNumber(UInt8 number, F && f)
case TypeId<Int64>::value: f(T(), Int64()); break;
case TypeId<Int128>::value: f(T(), Int128()); break;
case TypeId<Dec32>::value: f(T(), Dec32()); break;
case TypeId<Dec64>::value: f(T(), Dec64()); break;
case TypeId<Dec128>::value: f(T(), Dec128()); break;
case TypeId<Decimal32>::value: f(T(), Decimal32()); break;
case TypeId<Decimal64>::value: f(T(), Decimal64()); break;
case TypeId<Decimal128>::value: f(T(), Decimal128()); break;
default:
return false;
}
@ -234,9 +234,9 @@ inline bool callByNumbers(UInt8 type_num1, UInt8 type_num2, F && f)
case TypeId<Int64>::value: return callByTypeAndNumber<Int64>(type_num2, std::forward<F>(f));
case TypeId<Int128>::value: return callByTypeAndNumber<Int128>(type_num2, std::forward<F>(f));
case TypeId<Dec32>::value: return callByTypeAndNumber<Dec32>(type_num2, std::forward<F>(f));
case TypeId<Dec64>::value: return callByTypeAndNumber<Dec64>(type_num2, std::forward<F>(f));
case TypeId<Dec128>::value: return callByTypeAndNumber<Dec128>(type_num2, std::forward<F>(f));
case TypeId<Decimal32>::value: return callByTypeAndNumber<Decimal32>(type_num2, std::forward<F>(f));
case TypeId<Decimal64>::value: return callByTypeAndNumber<Decimal64>(type_num2, std::forward<F>(f));
case TypeId<Decimal128>::value: return callByTypeAndNumber<Decimal128>(type_num2, std::forward<F>(f));
default:
break;

View File

@ -577,7 +577,7 @@ using GreatestImpl = std::conditional_t<!NumberTraits::LeastGreatestSpecialCase<
template <typename A>
struct NegateImpl
{
using ResultType = std::conditional_t<decTrait<A>(), A, typename NumberTraits::ResultOfNegate<A>::Type>;
using ResultType = std::conditional_t<IsDecimalNumber<A>, A, typename NumberTraits::ResultOfNegate<A>::Type>;
static inline ResultType apply(A a)
{
@ -619,11 +619,11 @@ struct BitNotImpl
template <typename A>
struct AbsImpl
{
using ResultType = std::conditional_t<decTrait<A>(), A, typename NumberTraits::ResultOfAbs<A>::Type>;
using ResultType = std::conditional_t<IsDecimalNumber<A>, A, typename NumberTraits::ResultOfAbs<A>::Type>;
static inline ResultType apply(A a)
{
if constexpr (decTrait<A>())
if constexpr (IsDecimalNumber<A>)
return a < 0 ? A(-a) : a;
else if constexpr (std::is_integral_v<A> && std::is_signed_v<A>)
return a < 0 ? static_cast<ResultType>(~a) + 1 : a;
@ -717,9 +717,9 @@ struct IntExp10Impl
template <typename T> struct NativeType { using Type = T; };
template <> struct NativeType<Dec32> { using Type = Int32; };
template <> struct NativeType<Dec64> { using Type = Int64; };
template <> struct NativeType<Dec128> { using Type = Int128; };
template <> struct NativeType<Decimal32> { using Type = Int32; };
template <> struct NativeType<Decimal64> { using Type = Int64; };
template <> struct NativeType<Decimal128> { using Type = Int128; };
/// Binary operations for Decimals need scale args
/// +|- scale one of args (which scale factor is not 1). ScaleR = oneof(Scale1, Scale2);
@ -763,7 +763,7 @@ struct DecimalBinaryOperation
return;
}
}
else if constexpr (is_division && decTrait<B>())
else if constexpr (is_division && IsDecimalNumber<B>)
{
for (size_t i = 0; i < size; ++i)
c[i] = applyScaledDiv(a[i], b[i], scale_a);
@ -794,7 +794,7 @@ struct DecimalBinaryOperation
return;
}
}
else if constexpr (is_division && decTrait<B>())
else if constexpr (is_division && IsDecimalNumber<B>)
{
for (size_t i = 0; i < size; ++i)
c[i] = applyScaledDiv(a[i], b, scale_a);
@ -825,7 +825,7 @@ struct DecimalBinaryOperation
return;
}
}
else if constexpr (is_division && decTrait<B>())
else if constexpr (is_division && IsDecimalNumber<B>)
{
for (size_t i = 0; i < size; ++i)
c[i] = applyScaledDiv(a, b[i], scale_a);
@ -846,7 +846,7 @@ struct DecimalBinaryOperation
else if (scale_b != 1)
return applyScaled<false>(a, b, scale_b);
}
else if constexpr (is_division && decTrait<B>())
else if constexpr (is_division && IsDecimalNumber<B>)
return applyScaledDiv(a, b, scale_a);
return apply(a, b);
}
@ -896,7 +896,7 @@ private:
if constexpr (is_division)
{
bool overflow = false;
if constexpr (!decTrait<A>())
if constexpr (!IsDecimalNumber<A>)
overflow |= common::mulOverflow(scale, scale, scale);
overflow |= common::mulOverflow(a, scale, a);
if (overflow)
@ -931,14 +931,14 @@ template <> constexpr bool IsDateOrDateTime<DataTypeDate> = true;
template <> constexpr bool IsDateOrDateTime<DataTypeDateTime> = true;
template <typename DataType> constexpr bool IsDecimal = false;
template <> constexpr bool IsDecimal<DataTypeDecimal<Dec32>> = true;
template <> constexpr bool IsDecimal<DataTypeDecimal<Dec64>> = true;
template <> constexpr bool IsDecimal<DataTypeDecimal<Dec128>> = true;
template <> constexpr bool IsDecimal<DataTypeDecimal<Decimal32>> = true;
template <> constexpr bool IsDecimal<DataTypeDecimal<Decimal64>> = true;
template <> constexpr bool IsDecimal<DataTypeDecimal<Decimal128>> = true;
template <typename T0, typename T1> constexpr bool UseLeftDecimal = false;
template <> constexpr bool UseLeftDecimal<DataTypeDecimal<Dec128>, DataTypeDecimal<Dec32>> = true;
template <> constexpr bool UseLeftDecimal<DataTypeDecimal<Dec128>, DataTypeDecimal<Dec64>> = true;
template <> constexpr bool UseLeftDecimal<DataTypeDecimal<Dec64>, DataTypeDecimal<Dec32>> = true;
template <> constexpr bool UseLeftDecimal<DataTypeDecimal<Decimal128>, DataTypeDecimal<Decimal32>> = true;
template <> constexpr bool UseLeftDecimal<DataTypeDecimal<Decimal128>, DataTypeDecimal<Decimal64>> = true;
template <> constexpr bool UseLeftDecimal<DataTypeDecimal<Decimal64>, DataTypeDecimal<Decimal32>> = true;
template <typename T> using DataTypeFromFieldType = std::conditional_t<std::is_same_v<T, NumberTraits::Error>, InvalidType, DataTypeNumber<T>>;
@ -1020,9 +1020,9 @@ class FunctionBinaryArithmetic : public IFunction
DataTypeFloat64,
DataTypeDate,
DataTypeDateTime,
DataTypeDecimal<Dec32>,
DataTypeDecimal<Dec64>,
DataTypeDecimal<Dec128>
DataTypeDecimal<Decimal32>,
DataTypeDecimal<Decimal64>,
DataTypeDecimal<Decimal128>
>(type, std::forward<F>(f));
}
@ -1345,9 +1345,9 @@ class FunctionUnaryArithmetic : public IFunction
DataTypeInt64,
DataTypeFloat32,
DataTypeFloat64,
DataTypeDecimal<Dec32>,
DataTypeDecimal<Dec64>,
DataTypeDecimal<Dec128>
DataTypeDecimal<Decimal32>,
DataTypeDecimal<Decimal64>,
DataTypeDecimal<Decimal128>
>(type, std::forward<F>(f));
}

View File

@ -215,13 +215,13 @@ template <> struct ConstructDecInt<16> { using Type = Int128; };
template <typename T, typename U>
struct DecCompareInt
{
using Type = typename ConstructDecInt<(!decTrait<U>() || sizeof(T) > sizeof(U)) ? sizeof(T) : sizeof(U)>::Type;
using Type = typename ConstructDecInt<(!IsDecimalNumber<U> || sizeof(T) > sizeof(U)) ? sizeof(T) : sizeof(U)>::Type;
using TypeA = Type;
using TypeB = Type;
};
///
template <typename A, typename B, template <typename, typename> typename Operation, bool _actual = decTrait<A>() || decTrait<B>()>
template <typename A, typename B, template <typename, typename> typename Operation, bool _actual = IsDecimalNumber<A> || IsDecimalNumber<B>>
class DecimalComparison
{
public:
@ -257,7 +257,7 @@ public:
static bool compare(A a, B b, UInt32 scale_a, UInt32 scale_b)
{
static const UInt32 max_scale = maxDecimalPrecision<Dec128>();
static const UInt32 max_scale = maxDecimalPrecision<Decimal128>();
if (scale_a > max_scale || scale_b > max_scale)
throw Exception("Bad scale of decimal field", ErrorCodes::DECIMAL_OVERFLOW);
@ -292,7 +292,7 @@ private:
}
template <typename T, typename U>
static std::enable_if_t<decTrait<T>() && decTrait<U>(), Shift>
static std::enable_if_t<IsDecimalNumber<T> && IsDecimalNumber<U>, Shift>
getScales(const DataTypePtr & left_type, const DataTypePtr & right_type)
{
const DataTypeDecimal<T> * decimal0 = checkDecimal<T>(*left_type);
@ -314,7 +314,7 @@ private:
}
template <typename T, typename U>
static std::enable_if_t<decTrait<T>() && !decTrait<U>(), Shift>
static std::enable_if_t<IsDecimalNumber<T> && !IsDecimalNumber<U>, Shift>
getScales(const DataTypePtr & left_type, const DataTypePtr &)
{
Shift shift;
@ -325,7 +325,7 @@ private:
}
template <typename T, typename U>
static std::enable_if_t<!decTrait<T>() && decTrait<U>(), Shift>
static std::enable_if_t<!IsDecimalNumber<T> && IsDecimalNumber<U>, Shift>
getScales(const DataTypePtr &, const DataTypePtr & right_type)
{
Shift shift;

View File

@ -165,9 +165,9 @@ Field convertFieldToTypeImpl(const Field & src, const IDataType & type)
if (typeid_cast<const DataTypeInt64 *>(&type)) return convertNumericType<Int64>(src, type);
if (typeid_cast<const DataTypeFloat32 *>(&type)) return convertNumericType<Float32>(src, type);
if (typeid_cast<const DataTypeFloat64 *>(&type)) return convertNumericType<Float64>(src, type);
if (auto * ptype = typeid_cast<const DataTypeDecimal<Dec32> *>(&type)) return convertDecimalType(src, *ptype);
if (auto * ptype = typeid_cast<const DataTypeDecimal<Dec64> *>(&type)) return convertDecimalType(src, *ptype);
if (auto * ptype = typeid_cast<const DataTypeDecimal<Dec128> *>(&type)) return convertDecimalType(src, *ptype);
if (auto * ptype = typeid_cast<const DataTypeDecimal<Decimal32> *>(&type)) return convertDecimalType(src, *ptype);
if (auto * ptype = typeid_cast<const DataTypeDecimal<Decimal64> *>(&type)) return convertDecimalType(src, *ptype);
if (auto * ptype = typeid_cast<const DataTypeDecimal<Decimal128> *>(&type)) return convertDecimalType(src, *ptype);
const bool is_date = typeid_cast<const DataTypeDate *>(&type);
bool is_datetime = false;