mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Merge pull request #60089 from ClickHouse/settings-avoid-overflow
Avoid overflow in settings
This commit is contained in:
commit
b8b6150374
@ -152,7 +152,7 @@ bool notEqualsOp(A a, B b)
|
||||
}
|
||||
|
||||
/// Converts numeric to an equal numeric of other type.
|
||||
/// When `strict` is `true` check that result exactly same as input, otherwise just check overflow
|
||||
/// When `strict` is `true` check that result exactly the same as input, otherwise just check overflow
|
||||
template <typename From, typename To, bool strict = true>
|
||||
inline bool NO_SANITIZE_UNDEFINED convertNumeric(From value, To & result)
|
||||
{
|
||||
|
@ -1,8 +1,7 @@
|
||||
#include <Core/SettingsFields.h>
|
||||
|
||||
#include <Core/Field.h>
|
||||
#include <Core/AccurateComparison.h>
|
||||
#include <Common/getNumberOfPhysicalCPUCores.h>
|
||||
#include <Common/FieldVisitorConvertToNumber.h>
|
||||
#include <Common/logger_useful.h>
|
||||
#include <DataTypes/DataTypeMap.h>
|
||||
#include <DataTypes/DataTypeString.h>
|
||||
@ -13,6 +12,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
@ -20,6 +20,7 @@ namespace ErrorCodes
|
||||
extern const int SIZE_OF_FIXED_STRING_DOESNT_MATCH;
|
||||
extern const int CANNOT_PARSE_BOOL;
|
||||
extern const int CANNOT_PARSE_NUMBER;
|
||||
extern const int CANNOT_CONVERT_TYPE;
|
||||
}
|
||||
|
||||
|
||||
@ -48,9 +49,51 @@ namespace
|
||||
T fieldToNumber(const Field & f)
|
||||
{
|
||||
if (f.getType() == Field::Types::String)
|
||||
{
|
||||
return stringToNumber<T>(f.get<const String &>());
|
||||
}
|
||||
else if (f.getType() == Field::Types::UInt64)
|
||||
{
|
||||
T result;
|
||||
if (!accurate::convertNumeric(f.get<UInt64>(), result))
|
||||
throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Field value {} is out of range of {} type", f, demangle(typeid(T).name()));
|
||||
return result;
|
||||
}
|
||||
else if (f.getType() == Field::Types::Int64)
|
||||
{
|
||||
T result;
|
||||
if (!accurate::convertNumeric(f.get<Int64>(), result))
|
||||
throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Field value {} is out of range of {} type", f, demangle(typeid(T).name()));
|
||||
return result;
|
||||
}
|
||||
else if (f.getType() == Field::Types::Bool)
|
||||
{
|
||||
return T(f.get<bool>());
|
||||
}
|
||||
else if (f.getType() == Field::Types::Float64)
|
||||
{
|
||||
Float64 x = f.get<Float64>();
|
||||
if constexpr (std::is_floating_point_v<T>)
|
||||
{
|
||||
return T(x);
|
||||
}
|
||||
else
|
||||
return applyVisitor(FieldVisitorConvertToNumber<T>(), f);
|
||||
{
|
||||
if (!isFinite(x))
|
||||
{
|
||||
/// Conversion of infinite values to integer is undefined.
|
||||
throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert infinite value to integer type");
|
||||
}
|
||||
else if (x > Float64(std::numeric_limits<T>::max()) || x < Float64(std::numeric_limits<T>::lowest()))
|
||||
{
|
||||
throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert out of range floating point value to integer type");
|
||||
}
|
||||
else
|
||||
return T(x);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Invalid value {} of the setting, which needs {}", f, demangle(typeid(T).name()));
|
||||
}
|
||||
|
||||
Map stringToMap(const String & str)
|
||||
@ -174,7 +217,7 @@ namespace
|
||||
if (f.getType() == Field::Types::String)
|
||||
return stringToMaxThreads(f.get<const String &>());
|
||||
else
|
||||
return applyVisitor(FieldVisitorConvertToNumber<UInt64>(), f);
|
||||
return fieldToNumber<UInt64>(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include <Interpreters/TreeRewriter.h>
|
||||
#include <Interpreters/Context.h>
|
||||
#include <Interpreters/convertFieldToType.h>
|
||||
#include <Interpreters/ExpressionActions.h>
|
||||
#include <Interpreters/castColumn.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
#include <Parsers/ASTExpressionList.h>
|
||||
@ -28,7 +27,6 @@
|
||||
#include <Processors/Formats/Impl/ConstantExpressionTemplate.h>
|
||||
#include <Parsers/ExpressionElementParsers.h>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <base/sort.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
|
@ -1 +1 @@
|
||||
SET max_threads = nan; -- { serverError 70 }
|
||||
SET max_threads = nan; -- { serverError CANNOT_CONVERT_TYPE }
|
||||
|
1
tests/queries/0_stateless/02992_settings_overflow.sql
Normal file
1
tests/queries/0_stateless/02992_settings_overflow.sql
Normal file
@ -0,0 +1 @@
|
||||
SET max_threads = -1; -- { serverError CANNOT_CONVERT_TYPE }
|
Loading…
Reference in New Issue
Block a user