mirror of
https://github.com/apache/impala.git
synced 2025-12-30 12:02:10 -05:00
When multiplying double and decimal values, we used to cast all doubles to decimals before doing the multiplication. Due to the precision of two decimals being added during multiplication, the effective value range of the resulting decimal type could become very small and overflows could happen. This change switches the behavior to cast to double precision types when at least one of the input operands is of type float or double. In such cases we will not have exact results in general and we assume the user would normally not expect exact results from an inherently inexact datatype. Change-Id: Idd28c5471506c68a860beb0778d98c8d25825f9f Reviewed-on: http://gerrit.cloudera.org:8080/1820 Reviewed-by: Tim Armstrong <tarmstrong@cloudera.com> Reviewed-by: Marcel Kornacker <marcel@cloudera.com> Tested-by: Internal Jenkins
102 lines
2.4 KiB
Plaintext
102 lines
2.4 KiB
Plaintext
====
|
|
---- QUERY
|
|
values(1, 2+1, 1.0, 5.0 + 1.0, 'a')
|
|
---- RESULTS
|
|
1,3,1.0,6.0,'a'
|
|
---- TYPES
|
|
TINYINT, SMALLINT, DECIMAL, DECIMAL, STRING
|
|
====
|
|
---- QUERY
|
|
values(1+1, 2, 5.0, 'a') order by 1 limit 10
|
|
---- RESULTS
|
|
2,2,5.0,'a'
|
|
---- TYPES
|
|
SMALLINT, TINYINT, DECIMAL, STRING
|
|
====
|
|
---- QUERY
|
|
values((1+8, 2, 5.0, 'a'), (2, 3, 6.0, 'b'), (3, 4, 7.0, 'c'))
|
|
---- RESULTS
|
|
9,2,5.0,'a'
|
|
2,3,6.0,'b'
|
|
3,4,7.0,'c'
|
|
---- TYPES
|
|
SMALLINT, TINYINT, DECIMAL, STRING
|
|
====
|
|
---- QUERY
|
|
values((1+8, 2, 5.0, 'a'), (2, 3, 6.0, 'b'), (3, 4, 7.0, 'c')) order by 1 desc limit 2
|
|
---- RESULTS
|
|
9,2,5.0,'a'
|
|
3,4,7.0,'c'
|
|
---- TYPES
|
|
SMALLINT, TINYINT, DECIMAL, STRING
|
|
====
|
|
---- QUERY
|
|
# Test literal casts by inserting into a table that requires a float.
|
|
drop table if exists values_test_float_tbl;
|
|
create table values_test_float_tbl(f float);
|
|
insert overwrite values_test_float_tbl values
|
|
(1), (16), (1024), (65536), (1000000), (1.1), (98.6), (0.07), (33.333);
|
|
select * from values_test_float_tbl;
|
|
---- RESULTS
|
|
1
|
|
16
|
|
1024
|
|
65536
|
|
1000000
|
|
1.100000023841858
|
|
98.59999847412109
|
|
0.07
|
|
33.33300018310547
|
|
---- TYPES
|
|
float
|
|
====
|
|
---- QUERY
|
|
# Test literal casts by inserting into a table that requires a decimal.
|
|
drop table if exists values_test_decimal_tbl;
|
|
create table values_test_decimal_tbl(f decimal(20, 4));
|
|
insert overwrite values_test_decimal_tbl values
|
|
(1), (16), (1024), (65536), (1000000), (1.1), (98.6), (0.07), (33.333);
|
|
select * from values_test_decimal_tbl;
|
|
---- RESULTS
|
|
1.0000
|
|
16.0000
|
|
1024.0000
|
|
65536.0000
|
|
1000000.0000
|
|
1.1000
|
|
98.6000
|
|
0.0700
|
|
33.3330
|
|
---- TYPES
|
|
decimal
|
|
====
|
|
---- QUERY
|
|
# IMPALA-2749: Test that multiplying a DOUBLE and a DECIMAL results in a double
|
|
# value and do not overflow.
|
|
drop table if exists i_2749;
|
|
create table i_2749 (dbl1 double, dec decimal(9,4), dbl2 double);
|
|
insert overwrite table i_2749 values
|
|
(0.0017,90,1.0113),
|
|
(0.0342,90,1.0113),
|
|
(0.0128,90,1.0113),
|
|
(0.0163,90,1.0113);
|
|
====
|
|
---- QUERY
|
|
select dbl1 * dec * dbl2, dbl1 + dec, dbl1 - dec, dbl1 / dec from i_2749;
|
|
---- RESULTS
|
|
0.1547289,90.00170000000000000,-89.99830000000000000,0.00001888888888888
|
|
3.112781400000001,90.03420000000000000,-89.96580000000000000,0.00038000000000000
|
|
1.1650176,90.01280000000000000,-89.98720000000000000,0.00014222222222222
|
|
1.4835771,90.01629999999999999,-89.98370000000000001,0.00018111111111111
|
|
---- TYPES
|
|
DOUBLE,DECIMAL,DECIMAL,DECIMAL
|
|
====
|
|
---- QUERY
|
|
select dbl1 * dbl2 * dec from i_2749;
|
|
---- RESULTS
|
|
0.1547289
|
|
3.112781400000001
|
|
1.1650176
|
|
1.4835771
|
|
====
|