Fix assert when decimal has too large negative exponent

This commit is contained in:
Alexey Milovidov 2020-08-02 05:35:44 +03:00
parent 18b21511a9
commit c8ed684a72
3 changed files with 31 additions and 6 deletions

View File

@ -159,14 +159,23 @@ inline void readDecimalText(ReadBuffer & buf, T & x, uint32_t precision, uint32_
digits, x, exponent, scale, precision), ErrorCodes::ARGUMENT_OUT_OF_BOUND);
if (static_cast<int32_t>(scale) + exponent < 0)
{
if (-exponent >= std::numeric_limits<typename T::NativeType>::digits10)
{
/// Too big negative exponent
x.value = 0;
scale = 0;
return;
}
else
{
/// Too many digits after point. Just cut off excessive digits.
auto divisor = intExp10OfSize<T>(-exponent - static_cast<int32_t>(scale));
assert(divisor > 0); /// This is for Clang Static Analyzer. It is not smart enough to infer it automatically.
x.value /= divisor;
scale = 0;
return;
}
}
scale += exponent;
}

View File

@ -0,0 +1,6 @@
1E-9 0
1E-8 0
1E-7 0
1e-7 0
1E-9 0.000000001
1E-10 0.000000000

View File

@ -0,0 +1,10 @@
SELECT '-1E9-1E9-1E9-1E9' AS x, toDecimal32(x, 0); -- { serverError 6 }
SELECT '-1E9' AS x, toDecimal32(x, 0); -- { serverError 69 }
SELECT '1E-9' AS x, toDecimal32(x, 0);
SELECT '1E-8' AS x, toDecimal32(x, 0);
SELECT '1E-7' AS x, toDecimal32(x, 0);
SELECT '1e-7' AS x, toDecimal32(x, 0);
SELECT '1E-9' AS x, toDecimal32(x, 9);
SELECT '1E-9' AS x, toDecimal32(x, 10); -- { serverError 69 }
SELECT '1E-10' AS x, toDecimal32(x, 10); -- { serverError 69 }
SELECT '1E-10' AS x, toDecimal32(x, 9);