diff --git a/dbms/src/DataTypes/DataTypesDecimal.h b/dbms/src/DataTypes/DataTypesDecimal.h index d127d5034619ff6d6e6df18d2e1c9b128e740a0f..4065180d8a5f81504ce0d86975f9937457b10487 100644 --- a/dbms/src/DataTypes/DataTypesDecimal.h +++ b/dbms/src/DataTypes/DataTypesDecimal.h @@ -1,4 +1,6 @@ #pragma once +#include + #include #include #include @@ -319,7 +321,11 @@ convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale) using FromFieldType = typename FromDataType::FieldType; if constexpr (std::is_floating_point_v) + { + if (!std::isfinite(value)) + throw Exception("Decimal convert overflow. Cannot convert infinity or NaN to decimal", ErrorCodes::DECIMAL_OVERFLOW); return value * ToDataType::getScaleMultiplier(scale); + } else { if constexpr (std::is_same_v) diff --git a/dbms/tests/queries/0_stateless/00700_decimal_casts.sql b/dbms/tests/queries/0_stateless/00700_decimal_casts.sql index 242a244a7fa5e1ee40c4c3741936e1352b19e14c..db43ea84592698c8144300e18e0d0ca7fbaa2335 100644 --- a/dbms/tests/queries/0_stateless/00700_decimal_casts.sql +++ b/dbms/tests/queries/0_stateless/00700_decimal_casts.sql @@ -240,3 +240,13 @@ SELECT toUInt64('9223372036854775809') AS x, toDecimal64(x, 0); -- { serverError SELECT toDecimal32(0, rowNumberInBlock()); -- { serverError 44 } SELECT toDecimal64(0, rowNumberInBlock()); -- { serverError 44 } SELECT toDecimal128(0, rowNumberInBlock()); -- { serverError 44 } + +SELECT toDecimal32(1/0, 0); -- { serverError 407 } +SELECT toDecimal64(1/0, 1); -- { serverError 407 } +SELECT toDecimal128(0/0, 2); -- { serverError 407 } +SELECT CAST(1/0, 'Decimal(9, 0)'); -- { serverError 407 } +SELECT CAST(1/0, 'Decimal(18, 1)'); -- { serverError 407 } +SELECT CAST(1/0, 'Decimal(38, 2)'); -- { serverError 407 } +SELECT CAST(0/0, 'Decimal(9, 3)'); -- { serverError 407 } +SELECT CAST(0/0, 'Decimal(18, 4)'); -- { serverError 407 } +SELECT CAST(0/0, 'Decimal(38, 5)'); -- { serverError 407 }