#pragma once #include #include #include #include namespace DB { namespace ErrorCodes { extern const int CANNOT_CONVERT_TYPE; } /** Converts numeric value of any type to specified type. */ template class FieldVisitorConvertToNumber : public StaticVisitor { public: T operator() (const Null &) const { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert NULL to {}", demangle(typeid(T).name())); } T operator() (const String &) const { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert String to {}", demangle(typeid(T).name())); } T operator() (const Array &) const { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert Array to {}", demangle(typeid(T).name())); } T operator() (const Tuple &) const { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert Tuple to {}", demangle(typeid(T).name())); } T operator() (const Map &) const { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert Map to {}", demangle(typeid(T).name())); } T operator() (const Object &) const { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert Object to {}", demangle(typeid(T).name())); } T operator() (const UInt64 & x) const { return T(x); } T operator() (const Int64 & x) const { return T(x); } T operator() (const UUID & x) const { return T(x.toUnderType()); } T operator() (const IPv4 & x) const { return T(x.toUnderType()); } T operator() (const IPv6 & x) const { return T(x.toUnderType()); } T operator() (const Float64 & x) const { if constexpr (!std::is_floating_point_v) { if (!isFinite(x)) { /// When converting to bool it's ok (non-zero converts to true, NaN including). if (std::is_same_v) return true; /// Conversion of infinite values to integer is undefined. throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert infinite value to integer type"); } if (x > Float64(std::numeric_limits::max()) || x < Float64(std::numeric_limits::lowest())) { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert out of range floating point value to integer type"); } } if constexpr (std::is_same_v) { return Int256(x); } else { return T(x); } } template T operator() (const DecimalField & x) const { if constexpr (std::is_floating_point_v) return x.getValue().template convertTo() / x.getScaleMultiplier().template convertTo(); else return (x.getValue() / x.getScaleMultiplier()).template convertTo(); } T operator() (const AggregateFunctionStateData &) const { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert AggregateFunctionStateData to {}", demangle(typeid(T).name())); } T operator() (const CustomType &) const { throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert CustomType to {}", demangle(typeid(T).name())); } template requires is_big_int_v T operator() (const U & x) const { if constexpr (is_decimal) return static_cast(static_cast(x)); else return static_cast(x); } T operator() (const bool & x) const { return T(x); } }; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; extern template class FieldVisitorConvertToNumber; }