提交 a70637ab 编写于 作者: A Alexey Milovidov

Fixed UBSan; added a test

上级 d1464a44
......@@ -2,15 +2,20 @@
// Moved Decimal-related functions out from Core/Types.h to reduce compilation time.
#include <Core/Types.h>
#include <Common/intExp.h>
#include <Common/Exception.h>
#include <common/arithmeticOverflow.h>
#include <limits>
class DateLUTImpl;
namespace DB
{
namespace ErrorCodes
{
extern const int DECIMAL_OVERFLOW;
}
namespace DecimalUtils
{
......@@ -37,22 +42,26 @@ struct DecimalComponents
};
/** Make a decimal value from whole and fractional components with given scale multiplier.
* where scale_multiplier = scaleMultiplier<T>(scale)
* this is to reduce number of calls to scaleMultiplier when scale is known.
*
* Sign of `whole` controls sign of result: negative whole => negative result, positive whole => positive result.
* Sign of `fractional` is expected to be positive, otherwise result is undefined.
* If `scale` is to big (scale > maxPrecision<DecimalType::NativeType>), result is undefined.
*/
* where scale_multiplier = scaleMultiplier<T>(scale)
* this is to reduce number of calls to scaleMultiplier when scale is known.
*
* Sign of `whole` controls sign of result: negative whole => negative result, positive whole => positive result.
* Sign of `fractional` is expected to be positive, otherwise result is undefined.
* If `scale` is to big (scale > maxPrecision<DecimalType::NativeType>), result is undefined.
*/
template <typename DecimalType>
DecimalType decimalFromComponentsWithMultiplier(const typename DecimalType::NativeType & whole,
const typename DecimalType::NativeType & fractional,
typename DecimalType::NativeType scale_multiplier)
const typename DecimalType::NativeType & fractional,
typename DecimalType::NativeType scale_multiplier)
{
using T = typename DecimalType::NativeType;
const auto fractional_sign = whole < 0 ? -1 : 1;
const T value = whole * scale_multiplier + fractional_sign * (fractional % scale_multiplier);
T whole_scaled = 0;
if (common::mulOverflow(whole, scale_multiplier, whole_scaled))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
const T value = whole_scaled + fractional_sign * (fractional % scale_multiplier);
return DecimalType(value);
}
......@@ -61,7 +70,8 @@ DecimalType decimalFromComponentsWithMultiplier(const typename DecimalType::Nati
* @see `decimalFromComponentsWithMultiplier` for details.
*/
template <typename DecimalType>
DecimalType decimalFromComponents(const typename DecimalType::NativeType & whole, const typename DecimalType::NativeType & fractional, UInt32 scale)
DecimalType decimalFromComponents(
const typename DecimalType::NativeType & whole, const typename DecimalType::NativeType & fractional, UInt32 scale)
{
using T = typename DecimalType::NativeType;
......@@ -72,7 +82,8 @@ DecimalType decimalFromComponents(const typename DecimalType::NativeType & whole
* @see `decimalFromComponentsWithMultiplier` for details.
*/
template <typename DecimalType>
DecimalType decimalFromComponents(const DecimalComponents<typename DecimalType::NativeType> & components, UInt32 scale)
DecimalType decimalFromComponents(
const DecimalComponents<typename DecimalType::NativeType> & components, UInt32 scale)
{
return decimalFromComponents<DecimalType>(components.whole, components.fractional, scale);
}
......@@ -81,7 +92,8 @@ DecimalType decimalFromComponents(const DecimalComponents<typename DecimalType::
* This is an optimization to reduce number of calls to scaleMultiplier on known scale.
*/
template <typename DecimalType>
DecimalComponents<typename DecimalType::NativeType> splitWithScaleMultiplier(const DecimalType & decimal, typename DecimalType::NativeType scale_multiplier)
DecimalComponents<typename DecimalType::NativeType> splitWithScaleMultiplier(
const DecimalType & decimal, typename DecimalType::NativeType scale_multiplier)
{
using T = typename DecimalType::NativeType;
const auto whole = decimal.value / scale_multiplier;
......
select now64(10); -- { serverError 407 }
select length(toString(now64(9)));
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册