Merge pull request #55861 from bigo-sg/ch_55858

Throw exception when parsing illegal string as float if precise_float_parsing is true
This commit is contained in:
Kruglov Pavel 2023-10-27 14:24:55 +02:00 committed by GitHub
commit f1f1846572
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 6 deletions

View File

@ -148,11 +148,11 @@ ReturnType readFloatTextPreciseImpl(T & x, ReadBuffer & buf)
static_assert('a' > '.' && 'A' > '.' && '\n' < '.' && '\t' < '.' && '\'' < '.' && '"' < '.', "Layout of char is not like ASCII");
static constexpr bool throw_exception = std::is_same_v<ReturnType, void>;
/// Fast path (avoid copying) if the buffer have at least MAX_LENGTH bytes.
static constexpr int MAX_LENGTH = 316;
if (likely(!buf.eof() && buf.position() + MAX_LENGTH <= buf.buffer().end()))
ReadBufferFromMemory * buf_from_memory = dynamic_cast<ReadBufferFromMemory *>(&buf);
/// Fast path (avoid copying) if the buffer have at least MAX_LENGTH bytes or buf is ReadBufferFromMemory
if (likely(!buf.eof() && (buf_from_memory || buf.position() + MAX_LENGTH <= buf.buffer().end())))
{
auto * initial_position = buf.position();
auto res = fast_float::from_chars(initial_position, buf.buffer().end(), x);
@ -160,7 +160,10 @@ ReturnType readFloatTextPreciseImpl(T & x, ReadBuffer & buf)
if (unlikely(res.ec != std::errc()))
{
if constexpr (throw_exception)
throw ParsingException(ErrorCodes::CANNOT_PARSE_NUMBER, "Cannot read floating point value");
throw ParsingException(
ErrorCodes::CANNOT_PARSE_NUMBER,
"Cannot read floating point value here: {}",
String(initial_position, buf.buffer().end() - initial_position));
else
return ReturnType(false);
}
@ -247,10 +250,11 @@ ReturnType readFloatTextPreciseImpl(T & x, ReadBuffer & buf)
res = fast_float::from_chars(tmp_buf, tmp_buf + num_copied_chars, x64);
x = static_cast<T>(x64);
}
if (unlikely(res.ec != std::errc()))
if (unlikely(res.ec != std::errc() || res.ptr - tmp_buf != num_copied_chars))
{
if constexpr (throw_exception)
throw ParsingException(ErrorCodes::CANNOT_PARSE_NUMBER, "Cannot read floating point value");
throw ParsingException(
ErrorCodes::CANNOT_PARSE_NUMBER, "Cannot read floating point value here: {}", String(tmp_buf, num_copied_chars));
else
return ReturnType(false);
}

View File

@ -0,0 +1,4 @@
0
0
\N
\N

View File

@ -0,0 +1,10 @@
set precise_float_parsing = 1;
select cast('2023-01-01' as Float64); -- { serverError 6 }
select cast('2023-01-01' as Float32); -- { serverError 6 }
select toFloat32('2023-01-01'); -- { serverError 6 }
select toFloat64('2023-01-01'); -- { serverError 6 }
select toFloat32OrZero('2023-01-01');
select toFloat64OrZero('2023-01-01');
select toFloat32OrNull('2023-01-01');
select toFloat64OrNull('2023-01-01');