Merge pull request #19960 from ClickHouse/json-extract-inaccurate-conversion-from-double-to-float

Allow inaccurate conversion from double to float in function JSONExtract beacuse the users want that
This commit is contained in:
alexey-milovidov 2021-02-02 15:15:37 +03:00 committed by GitHub
commit 695e28079d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 1 deletions

View File

@ -25,6 +25,7 @@
#include <DataTypes/DataTypeTuple.h>
#include <Interpreters/Context.h>
#include <ext/range.h>
#include <type_traits>
#include <boost/tti/has_member_function.hpp>
#if !defined(ARCADIA_BUILD)
@ -507,11 +508,20 @@ public:
}
else if (element.isDouble())
{
if (!accurate::convertNumeric(element.getDouble(), value))
if constexpr (std::is_floating_point_v<NumberType>)
{
/// We permit inaccurate conversion of double to float.
/// Example: double 0.1 from JSON is not representable in float.
/// But it will be more convenient for user to perform conversion.
value = element.getDouble();
}
else if (!accurate::convertNumeric(element.getDouble(), value))
return false;
}
else if (element.isBool() && is_integer_v<NumberType> && convert_bool_to_integer)
{
value = static_cast<NumberType>(element.getBool());
}
else
return false;

View File

@ -0,0 +1,10 @@
1.1 1.1 1.1 1.1
0.01 0.01 0.01 0.01
0
\N
-1e300
-inf
0
0
0
0

View File

@ -0,0 +1,24 @@
WITH '{ "v":1.1}' AS raw
SELECT
JSONExtract(raw, 'v', 'float') AS float32_1,
JSONExtract(raw, 'v', 'Float32') AS float32_2,
JSONExtractFloat(raw, 'v') AS float64_1,
JSONExtract(raw, 'v', 'double') AS float64_2;
WITH '{ "v":1E-2}' AS raw
SELECT
JSONExtract(raw, 'v', 'float') AS float32_1,
JSONExtract(raw, 'v', 'Float32') AS float32_2,
JSONExtractFloat(raw, 'v') AS float64_1,
JSONExtract(raw, 'v', 'double') AS float64_2;
SELECT JSONExtract('{"v":1.1}', 'v', 'UInt64');
SELECT JSONExtract('{"v":1.1}', 'v', 'Nullable(UInt64)');
SELECT JSONExtract('{"v":-1e300}', 'v', 'Float64');
SELECT JSONExtract('{"v":-1e300}', 'v', 'Float32');
SELECT JSONExtract('{"v":-1e300}', 'v', 'UInt64');
SELECT JSONExtract('{"v":-1e300}', 'v', 'Int64');
SELECT JSONExtract('{"v":-1e300}', 'v', 'UInt8');
SELECT JSONExtract('{"v":-1e300}', 'v', 'Int8');