IMPALA-6183: Fix Decimal to Double conversion When converting a decimal to a double, we incorrectly used the powf() function in the backend, which returns a float instead of a double. This caused us to lose precision.
We fix the problem by replacing the powf() function with a pow() function, which returns a double. Testing: - Added an EE test. Change-Id: I9bf81d039e5037f22c64a32b328832235aafe9e3 Reviewed-on: http://gerrit.cloudera.org:8080/8547 Reviewed-by: Alex Behm <[email protected]> Tested-by: Impala Public Jenkins Project: http://git-wip-us.apache.org/repos/asf/incubator-impala/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-impala/commit/d1b92c8b Tree: http://git-wip-us.apache.org/repos/asf/incubator-impala/tree/d1b92c8b Diff: http://git-wip-us.apache.org/repos/asf/incubator-impala/diff/d1b92c8b Branch: refs/heads/master Commit: d1b92c8b525e73fd9dbc91d5e0a1d73a5d402b82 Parents: a0be00a Author: Taras Bobrovytsky <[email protected]> Authored: Tue Nov 14 12:54:19 2017 -0800 Committer: Impala Public Jenkins <[email protected]> Committed: Wed Nov 15 02:54:53 2017 +0000 ---------------------------------------------------------------------- be/src/runtime/decimal-value.inline.h | 2 +- .../queries/QueryTest/decimal-exprs.test | 26 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/d1b92c8b/be/src/runtime/decimal-value.inline.h ---------------------------------------------------------------------- diff --git a/be/src/runtime/decimal-value.inline.h b/be/src/runtime/decimal-value.inline.h index 20a7b66..93b7311 100644 --- a/be/src/runtime/decimal-value.inline.h +++ b/be/src/runtime/decimal-value.inline.h @@ -505,7 +505,7 @@ inline std::string DecimalValue<T>::ToString(int precision, int scale) const { template<typename T> inline double DecimalValue<T>::ToDouble(int scale) const { - return static_cast<double>(value_) / powf(10.0, scale); + return static_cast<double>(value_) / pow(10.0, scale); } template<typename T> http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/d1b92c8b/testdata/workloads/functional-query/queries/QueryTest/decimal-exprs.test ---------------------------------------------------------------------- diff --git a/testdata/workloads/functional-query/queries/QueryTest/decimal-exprs.test b/testdata/workloads/functional-query/queries/QueryTest/decimal-exprs.test index ef707f2..9ffd78a 100644 --- a/testdata/workloads/functional-query/queries/QueryTest/decimal-exprs.test +++ b/testdata/workloads/functional-query/queries/QueryTest/decimal-exprs.test @@ -272,3 +272,29 @@ from decimal_tiny where c2 < 112 ---- TYPES DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL ==== +---- QUERY +# IMPALA-6183: Make sure precision is not lost when converting decimal to double +# with DECIMAL_V1 +set decimal_v2=false; +select + cast(cast(1.01234567890123456789 as decimal(21,20)) as double), + cast(cast(1.01234567890123456789 as decimal(38,37)) as double), + cast(cast(1.01234567890123456789 as decimal(11,10)) as double) +---- RESULTS +1.0123456789012345,1.0123456789012345,1.0123456789 +---- TYPES +DOUBLE,DOUBLE,DOUBLE +==== +---- QUERY +# IMPALA-6183: Make sure precision is not lost when converting decimal to double +# with DECIMAL_V2 +set decimal_v2=true; +select + cast(cast(1.01234567890123456789 as decimal(21,20)) as double), + cast(cast(1.01234567890123456789 as decimal(38,37)) as double), + cast(cast(1.01234567890123456789 as decimal(11,10)) as double) +---- RESULTS +1.0123456789012345,1.0123456789012345,1.0123456789 +---- TYPES +DOUBLE,DOUBLE,DOUBLE +====
