提交 69fee681 编写于 作者: C chertus

variant without catch

上级 cc5fc0a8
......@@ -11,8 +11,8 @@ namespace ErrorCodes
}
template <typename T>
inline void readDigits(ReadBuffer & buf, T & x, unsigned int & digits, int & exponent, bool digits_only = false)
template <bool _throw_on_error, typename T>
inline bool readDigits(ReadBuffer & buf, T & x, unsigned int & digits, int & exponent, bool digits_only = false)
{
x = 0;
exponent = 0;
......@@ -24,7 +24,11 @@ inline void readDigits(ReadBuffer & buf, T & x, unsigned int & digits, int & exp
bool after_point = false;
if (buf.eof())
{
if constexpr (_throw_on_error)
throwReadAfterEOF();
return false;
}
if (!buf.eof())
{
......@@ -75,8 +79,12 @@ inline void readDigits(ReadBuffer & buf, T & x, unsigned int & digits, int & exp
++places; // num zeroes before + current digit
if (digits + places > max_digits)
{
if constexpr (_throw_on_error)
throw Exception("Too many digits (" + std::to_string(digits + places) + " > " + std::to_string(max_digits)
+ ") in decimal value", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
return false;
}
digits += places;
if (after_point)
......@@ -93,7 +101,13 @@ inline void readDigits(ReadBuffer & buf, T & x, unsigned int & digits, int & exp
{
++buf.position();
Int32 addition_exp = 0;
readIntText(addition_exp, buf);
if (!tryReadIntText(addition_exp, buf))
{
if constexpr (_throw_on_error)
throw Exception("Cannot parse exponent while reading decimal", ErrorCodes::CANNOT_PARSE_NUMBER);
else
return false;
}
exponent += addition_exp;
stop = true;
continue;
......@@ -101,7 +115,11 @@ inline void readDigits(ReadBuffer & buf, T & x, unsigned int & digits, int & exp
default:
if (digits_only)
{
if constexpr (_throw_on_error)
throw Exception("Unexpected symbol while reading decimal", ErrorCodes::CANNOT_PARSE_NUMBER);
return false;
}
stop = true;
continue;
}
......@@ -109,6 +127,7 @@ inline void readDigits(ReadBuffer & buf, T & x, unsigned int & digits, int & exp
}
x *= sign;
return true;
}
template <typename T>
......@@ -116,7 +135,7 @@ inline void readDecimalText(ReadBuffer & buf, T & x, unsigned int precision, uns
{
unsigned int digits = precision;
int exponent;
readDigits(buf, x, digits, exponent, digits_only);
readDigits<true>(buf, x, digits, exponent, digits_only);
if (static_cast<int>(digits) + exponent > static_cast<int>(precision - scale))
throw Exception("Decimal value is too big", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
......@@ -132,17 +151,10 @@ inline bool tryReadDecimalText(ReadBuffer & buf, T & x, unsigned int precision,
unsigned int digits = precision;
int exponent;
try
{
readDigits(buf, x, digits, exponent, true);
if (static_cast<int>(digits) + exponent > static_cast<int>(precision - scale) ||
if (!readDigits<false>(buf, x, digits, exponent, true) ||
static_cast<int>(digits) + exponent > static_cast<int>(precision - scale) ||
static_cast<int>(scale) + exponent < 0)
return false;
}
catch (const Exception &)
{
return false;
}
scale += exponent;
return true;
......
SELECT toDecimal32('e', 1); -- { serverError 32 }
SELECT toDecimal64('e', 2); -- { serverError 32 }
SELECT toDecimal128('e', 3); -- { serverError 32 }
SELECT toDecimal32('e', 1); -- { serverError 72 }
SELECT toDecimal64('e', 2); -- { serverError 72 }
SELECT toDecimal128('e', 3); -- { serverError 72 }
SELECT toDecimal32OrNull('e', 1) x, isNull(x);
SELECT toDecimal64OrNull('e', 2) x, isNull(x);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册