From 738fef71f497d2297c36606f90ab838e9d0f2efb Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 15 Apr 2020 06:32:33 +0300 Subject: [PATCH] Allow to parse +inf #1839 --- src/IO/readFloatText.h | 27 +++++++++++++++++-- .../0_stateless/01198_plus_inf.reference | 3 +++ tests/queries/0_stateless/01198_plus_inf.sql | 3 +++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/queries/0_stateless/01198_plus_inf.reference create mode 100644 tests/queries/0_stateless/01198_plus_inf.sql diff --git a/src/IO/readFloatText.h b/src/IO/readFloatText.h index fc3ffc43a91..4e0825222a7 100644 --- a/src/IO/readFloatText.h +++ b/src/IO/readFloatText.h @@ -156,6 +156,9 @@ ReturnType readFloatTextPreciseImpl(T & x, ReadBuffer & buf) { switch (*buf.position()) { + case '+': + continue; + case '-': { negative = true; @@ -335,6 +338,7 @@ ReturnType readFloatTextFastImpl(T & x, ReadBuffer & in) ++in.position(); } + auto count_after_sign = in.count(); constexpr int significant_digits = std::numeric_limits::digits10; @@ -380,7 +384,7 @@ ReturnType readFloatTextFastImpl(T & x, ReadBuffer & in) if (in.eof()) { if constexpr (throw_exception) - throw Exception("Cannot read floating point value", ErrorCodes::CANNOT_PARSE_NUMBER); + throw Exception("Cannot read floating point value: nothing after exponent", ErrorCodes::CANNOT_PARSE_NUMBER); else return false; } @@ -418,11 +422,30 @@ ReturnType readFloatTextFastImpl(T & x, ReadBuffer & in) if (in.eof()) { if constexpr (throw_exception) - throw Exception("Cannot read floating point value", ErrorCodes::CANNOT_PARSE_NUMBER); + throw Exception("Cannot read floating point value: no digits read", ErrorCodes::CANNOT_PARSE_NUMBER); else return false; } + if (*in.position() == '+') + { + ++in.position(); + if (in.eof()) + { + if constexpr (throw_exception) + throw Exception("Cannot read floating point value: nothing after plus sign", ErrorCodes::CANNOT_PARSE_NUMBER); + else + return false; + } + else if (negative) + { + if constexpr (throw_exception) + throw Exception("Cannot read floating point value: plus after minus sign", ErrorCodes::CANNOT_PARSE_NUMBER); + else + return false; + } + } + if (*in.position() == 'i' || *in.position() == 'I') { if (assertOrParseInfinity(in)) diff --git a/tests/queries/0_stateless/01198_plus_inf.reference b/tests/queries/0_stateless/01198_plus_inf.reference new file mode 100644 index 00000000000..f726b8429b6 --- /dev/null +++ b/tests/queries/0_stateless/01198_plus_inf.reference @@ -0,0 +1,3 @@ +inf +-inf +inf diff --git a/tests/queries/0_stateless/01198_plus_inf.sql b/tests/queries/0_stateless/01198_plus_inf.sql new file mode 100644 index 00000000000..e06faa2fd21 --- /dev/null +++ b/tests/queries/0_stateless/01198_plus_inf.sql @@ -0,0 +1,3 @@ +SELECT DISTINCT toFloat64(arrayJoin(['+inf', '+Inf', '+INF', '+infinity', '+Infinity'])); +SELECT DISTINCT toFloat64(arrayJoin(['-inf', '-Inf', '-INF', '-infinity', '-Infinity'])); +SELECT DISTINCT toFloat64(arrayJoin(['inf', 'Inf', 'INF', 'infinity', 'Infinity']));