提交 5fc6a697 编写于 作者: D dmitry kuzmin

float to decimal overflow fix

上级 87557d21
...@@ -324,22 +324,23 @@ convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale) ...@@ -324,22 +324,23 @@ convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
if constexpr (std::is_floating_point_v<FromFieldType>) if constexpr (std::is_floating_point_v<FromFieldType>)
{ {
ToNativeType min_value; if (!std::isfinite(value))
ToNativeType max_value; throw Exception("Decimal convert overflow. Cannot convert infinity or NaN to decimal", ErrorCodes::DECIMAL_OVERFLOW);
auto out = value * ToDataType::getScaleMultiplier(scale);
if constexpr (std::is_same_v<ToNativeType, Int128>) if constexpr (std::is_same_v<ToNativeType, Int128>)
{ {
min_value = __int128(0x8000000000000000ll) << 64; // min __int128 static constexpr __int128 min_int128 = __int128(0x8000000000000000ll) << 64;
max_value = (__int128(0x7fffffffffffffffll) << 64) + 0xffffffffffffffffll; // max __int128 static constexpr __int128 max_int128 = (__int128(0x7fffffffffffffffll) << 64) + 0xffffffffffffffffll;
if (out < min_int128 || out > max_int128)
throw Exception("Decimal convert overflow. Float is out of Decimal range", ErrorCodes::DECIMAL_OVERFLOW);
} }
else else
{ {
min_value = std::numeric_limits<ToNativeType>::min(); if (out < std::numeric_limits<ToNativeType>::min() || out > std::numeric_limits<ToNativeType>::max())
max_value = std::numeric_limits<ToNativeType>::max(); throw Exception("Decimal convert overflow. Float is out of Decimal range", ErrorCodes::DECIMAL_OVERFLOW);
} }
ToNativeType converted_value = static_cast<ToNativeType>(value * ToDataType::getScaleMultiplier(scale)); return out;
if (converted_value == min_value || converted_value == max_value)
throw Exception("Decimal convert overflow", ErrorCodes::DECIMAL_OVERFLOW);
return converted_value;
} }
else else
{ {
......
...@@ -254,3 +254,7 @@ SELECT CAST(0/0, 'Decimal(38, 5)'); -- { serverError 407 } ...@@ -254,3 +254,7 @@ SELECT CAST(0/0, 'Decimal(38, 5)'); -- { serverError 407 }
select toDecimal32(10000.1, 6); -- { serverError 407 } select toDecimal32(10000.1, 6); -- { serverError 407 }
select toDecimal64(10000.1, 18); -- { serverError 407 } select toDecimal64(10000.1, 18); -- { serverError 407 }
select toDecimal128(1000000000000000000000.1, 18); -- { serverError 407 } select toDecimal128(1000000000000000000000.1, 18); -- { serverError 407 }
select toDecimal32(-10000.1, 6); -- { serverError 407 }
select toDecimal64(-10000.1, 18); -- { serverError 407 }
select toDecimal128(-1000000000000000000000.1, 18); -- { serverError 407 }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册