mirror of
https://github.com/apache/impala.git
synced 2026-01-02 03:00:32 -05:00
Suppose we have a large decimal number, which is greater than INT_MAX. We want to calculate the modulo of this number by 3: BIG_DECIMAL % 3 The result of this calculation can be 0, 1, or 2. This can fit into a decimal with precision 1. The in-memory representation of such small decimals are stored in int32_t in the backend. Let's call this int32_t the result type. The backend had the invalid assumption that it can do the calculation as well using the result type. This assumption is true for multiplying or adding numbers, but not for modulo. Now the backend selects the biggest type of ['return type', '1st operand type', '2nd operand type'] to do the calculation. Change-Id: I2b06c8acd5aa490943e84013faf2eaac7c26ceb4 Reviewed-on: http://gerrit.cloudera.org:8080/8574 Reviewed-by: Tim Armstrong <tarmstrong@cloudera.com> Tested-by: Impala Public Jenkins
316 lines
9.4 KiB
Plaintext
316 lines
9.4 KiB
Plaintext
====
|
|
---- QUERY
|
|
# Test DECIMAL V1 divide result type
|
|
set decimal_v2=false;
|
|
select d1 / d2, d2 / d1, d3 / d4, d5 / d3, d3 / d5 from decimal_tbl;
|
|
---- RESULTS
|
|
0.55535553555,1.8006482982,NULL,10000.0891810008,0.000099999108197945064
|
|
21.12612612612,0.0473347547,NULL,0.2544210023,3.930493123209169054441
|
|
37.07207207207,0.0269744835,NULL,0.0000810000,12345.678900000000000000000
|
|
37.07207207207,0.0269744835,NULL,0.0908820008,11.003278877005347593582
|
|
398.92492492492,0.0025067373,NULL,0.0000630900,15850.349728459731155875669
|
|
---- TYPES
|
|
DECIMAL, DECIMAL, DECIMAL, DECIMAL, DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Verify DECIMAL V2. Differences with V1:
|
|
# * d3/d4 does not overflow
|
|
# * d5/d3 has more scale
|
|
set decimal_v2=true;
|
|
select d1 / d2, d2 / d1, d3 / d4, d5 / d3, d3 / d5 from decimal_tbl;
|
|
---- RESULTS
|
|
0.55535553555,1.8006482982,10.000000,10000.08918100081154710738508,0.000099999108197945065
|
|
21.12612612613,0.0473347548,100.000000,0.25442100231523112106860,3.930493123209169054441
|
|
37.07207207207,0.0269744836,1000.000000,0.09088200082702620752594,11.003278877005347593583
|
|
37.07207207207,0.0269744836,10000.000000,0.00008100000073710000671,12345.678900000000000000000
|
|
398.92492492492,0.0025067373,100000.000000,0.00006309009057411982422,15850.349728459731155875669
|
|
---- TYPES
|
|
DECIMAL, DECIMAL, DECIMAL, DECIMAL, DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test DECIMAL V1 division by zero.
|
|
set decimal_v2=false;
|
|
select d1 / cast(0 as decimal(7, 2)), d1 / 0, 10.0 / 0 from decimal_tbl;
|
|
---- RESULTS
|
|
NULL,NULL,Infinity
|
|
NULL,NULL,Infinity
|
|
NULL,NULL,Infinity
|
|
NULL,NULL,Infinity
|
|
NULL,NULL,Infinity
|
|
---- TYPES
|
|
DECIMAL,DECIMAL,DOUBLE
|
|
====
|
|
---- QUERY
|
|
# Test DECIMAL V2 division by zero. Verify that Impala throws an error.
|
|
set decimal_v2=true;
|
|
select d1 / cast(0 as decimal(7, 2)) from decimal_tbl;
|
|
---- CATCH
|
|
UDF ERROR: Cannot divide decimal by zero
|
|
====
|
|
---- QUERY
|
|
set decimal_v2=true;
|
|
select d1 / 0 from decimal_tbl;
|
|
---- CATCH
|
|
UDF ERROR: Cannot divide decimal by zero
|
|
====
|
|
---- QUERY
|
|
set decimal_v2=true;
|
|
select 10.0 / 0;
|
|
---- CATCH
|
|
UDF ERROR: Cannot divide decimal by zero
|
|
====
|
|
---- QUERY
|
|
# Test DECIMAL V1 modulo zero.
|
|
set decimal_v2=false;
|
|
select d1 % cast(0 as decimal(7, 2)), d1 % 0, 10.0 % 0 from decimal_tbl;
|
|
---- RESULTS
|
|
NULL,NULL,NULL
|
|
NULL,NULL,NULL
|
|
NULL,NULL,NULL
|
|
NULL,NULL,NULL
|
|
NULL,NULL,NULL
|
|
---- TYPES
|
|
DECIMAL,DECIMAL,DOUBLE
|
|
====
|
|
---- QUERY
|
|
# Test DECIMAL V2 modulo zero. Verify that Impala throws an error.
|
|
set decimal_v2=true;
|
|
select d1 % cast(0 as decimal(7, 2)) from decimal_tbl;
|
|
---- CATCH
|
|
UDF ERROR: Cannot divide decimal by zero
|
|
====
|
|
---- QUERY
|
|
# Test DECIMAL V2 modulo zero. Verify that Impala throws an error.
|
|
set decimal_v2=true;
|
|
select d1 % 0 from decimal_tbl;
|
|
---- CATCH
|
|
UDF ERROR: Cannot divide decimal by zero
|
|
====
|
|
---- QUERY
|
|
# Test DECIMAL V2 modulo zero. Verify that Impala throws an error.
|
|
set decimal_v2=true;
|
|
select 10.0 % 0 from decimal_tbl;
|
|
---- CATCH
|
|
UDF ERROR: Cannot divide decimal by zero
|
|
====
|
|
---- QUERY
|
|
# Test casting behavior without decimal_v2 query option set.
|
|
set decimal_v2=false;
|
|
select cast(d3 as decimal(20, 3)) from decimal_tbl;
|
|
---- RESULTS
|
|
1.234
|
|
12.345
|
|
123.456
|
|
1234.567
|
|
12345.678
|
|
---- TYPES
|
|
DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test casting behavior with decimal_v2 query option set.
|
|
set decimal_v2=true;
|
|
select cast(d3 as decimal(20, 3)) from decimal_tbl;
|
|
---- RESULTS
|
|
1.235
|
|
12.346
|
|
123.457
|
|
1234.568
|
|
12345.679
|
|
---- TYPES
|
|
DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test casting behavior without decimal_v2 query option set.
|
|
set decimal_v2=false;
|
|
select sum(cast(d3 as DECIMAL(20,2)) + cast(d5 as DECIMAL(20,4))) from decimal_tbl;
|
|
---- RESULTS
|
|
26078.2788
|
|
---- TYPES
|
|
DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test casting behavior with decimal_v2 query option set.
|
|
set decimal_v2=true;
|
|
select sum(cast(d3 as DECIMAL(20,2)) + cast(d5 as DECIMAL(20,4))) from decimal_tbl;
|
|
---- RESULTS
|
|
26078.3189
|
|
---- TYPES
|
|
DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test AVG() with DECIMAL_V1
|
|
set decimal_v2=false;
|
|
select avg(d1), avg(d2), avg(d3), avg(d4), avg(d5), avg(d6) from decimal_tbl;
|
|
---- RESULTS
|
|
32222,666,2743.4567651580,0.12345678900000000000000000000000000000,2472.20577,1
|
|
---- TYPES
|
|
DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test AVG() with DECIMAL_V2
|
|
set decimal_v2=true;
|
|
select avg(d1), avg(d2), avg(d3), avg(d4), avg(d5), avg(d6) from decimal_tbl;
|
|
---- RESULTS
|
|
32222.200000,666.400000,2743.4567651580,0.12345678900000000000000000000000000000,2472.205778,1.000000
|
|
---- TYPES
|
|
DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test AVG() with DECIMAL_V1
|
|
set decimal_v2=false;
|
|
select l_tax, avg(cast(l_extendedprice as decimal(38,10))), avg(l_extendedprice)
|
|
from tpch_parquet.lineitem group by l_tax order by 1;
|
|
---- RESULTS
|
|
0.00,38241.5984613546,38241.59
|
|
0.01,38283.5417664599,38283.54
|
|
0.02,38250.4873094187,38250.48
|
|
0.03,38259.2810374789,38259.28
|
|
0.04,38247.1967454731,38247.19
|
|
0.05,38234.8480874721,38234.84
|
|
0.06,38246.4342924027,38246.43
|
|
0.07,38281.1963710003,38281.19
|
|
0.08,38251.6233675941,38251.62
|
|
---- TYPES
|
|
DECIMAL,DECIMAL,DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test AVG() with DECIMAL_V2
|
|
set decimal_v2=true;
|
|
select l_tax, avg(cast(l_extendedprice as decimal(38,10))), avg(l_extendedprice)
|
|
from tpch_parquet.lineitem group by l_tax order by 1;
|
|
---- RESULTS
|
|
0.00,38241.5984613546,38241.598461
|
|
0.01,38283.5417664600,38283.541766
|
|
0.02,38250.4873094187,38250.487309
|
|
0.03,38259.2810374789,38259.281037
|
|
0.04,38247.1967454731,38247.196745
|
|
0.05,38234.8480874721,38234.848087
|
|
0.06,38246.4342924027,38246.434292
|
|
0.07,38281.1963710004,38281.196371
|
|
0.08,38251.6233675942,38251.623368
|
|
---- TYPES
|
|
DECIMAL,DECIMAL,DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test AVG() with DECIMAL_V1
|
|
set decimal_v2=false;
|
|
select avg(l_extendedprice) as a from tpch_parquet.lineitem
|
|
group by l_tax having a > 38247.190 order by 1;
|
|
---- RESULTS
|
|
38250.48
|
|
38251.62
|
|
38259.28
|
|
38281.19
|
|
38283.54
|
|
---- TYPES
|
|
DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test AVG() with DECIMAL_V2
|
|
set decimal_v2=true;
|
|
select avg(l_extendedprice) as a from tpch_parquet.lineitem
|
|
group by l_tax having a > 38247.190 order by 1;
|
|
---- RESULTS
|
|
38247.196745
|
|
38250.487309
|
|
38251.623368
|
|
38259.281037
|
|
38281.196371
|
|
38283.541766
|
|
---- TYPES
|
|
DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test sum() and avg() analytic fns with start bounds (tests Remove() for decimal)
|
|
# with DECIMAL_V1
|
|
set decimal_v2=false;
|
|
select
|
|
sum(c1) over (order by c1 rows between 5 preceding and current row),
|
|
sum(c2) over (order by c1 rows between 5 preceding and 5 following),
|
|
sum(c3) over (order by c1 rows between 5 preceding and 2 preceding),
|
|
avg(c1) over (order by c1 rows between 5 preceding and current row),
|
|
avg(c2) over (order by c1 rows between 5 preceding and 5 following),
|
|
avg(c3) over (order by c1 rows between 5 preceding and 2 preceding)
|
|
from decimal_tiny where c2 < 112
|
|
---- RESULTS: VERIFY_IS_EQUAL_SORTED
|
|
0.0000,618.33330,NULL,0.0000,103.05555,NULL
|
|
0.1111,725.66662,NULL,0.0555,103.66666,NULL
|
|
0.3333,834.22216,0.0,0.1111,104.27777,0.0
|
|
0.6666,943.99992,0.1,0.1666,104.88888,0.0
|
|
1.1110,1054.99990,0.3,0.2222,105.49999,0.1
|
|
1.6665,1054.99990,0.6,0.2777,105.49999,0.1
|
|
2.3331,954.99990,1.0,0.3888,106.11110,0.2
|
|
2.9997,853.77768,1.4,0.4999,106.72221,0.3
|
|
3.6663,751.33324,1.8,0.6110,107.33332,0.4
|
|
4.3329,647.66658,2.2,0.7221,107.94443,0.5
|
|
---- TYPES
|
|
DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL
|
|
====
|
|
---- QUERY
|
|
# Test sum() and avg() analytic fns with start bounds (tests Remove() for decimal)
|
|
# with DECIMAL_V2
|
|
set decimal_v2=true;
|
|
select
|
|
sum(c1) over (order by c1 rows between 5 preceding and current row),
|
|
sum(c2) over (order by c1 rows between 5 preceding and 5 following),
|
|
sum(c3) over (order by c1 rows between 5 preceding and 2 preceding),
|
|
avg(c1) over (order by c1 rows between 5 preceding and current row),
|
|
avg(c2) over (order by c1 rows between 5 preceding and 5 following),
|
|
avg(c3) over (order by c1 rows between 5 preceding and 2 preceding)
|
|
from decimal_tiny where c2 < 112
|
|
---- RESULTS: VERIFY_IS_EQUAL_SORTED
|
|
0.0000,618.33330,NULL,0.000000,103.055550,NULL
|
|
0.1111,725.66662,NULL,0.055550,103.666660,NULL
|
|
0.3333,834.22216,0.0,0.111100,104.277770,0.000000
|
|
0.6666,943.99992,0.1,0.166650,104.888880,0.050000
|
|
1.1110,1054.99990,0.3,0.222200,105.499990,0.100000
|
|
1.6665,1054.99990,0.6,0.277750,105.499990,0.150000
|
|
2.3331,954.99990,1.0,0.388850,106.111100,0.250000
|
|
2.9997,853.77768,1.4,0.499950,106.722210,0.350000
|
|
3.6663,751.33324,1.8,0.611050,107.333320,0.450000
|
|
4.3329,647.66658,2.2,0.722150,107.944430,0.550000
|
|
---- 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
|
|
====
|
|
---- QUERY
|
|
# IMPALA-5936: big decimal numbers with % operator
|
|
set decimal_v2=true;
|
|
select
|
|
cast(42607032167 as decimal(18, 0)) % 3,
|
|
cast(42606774111 as decimal(18, 0)) % 3,
|
|
cast(42363009429 as decimal(18, 0)) % 3,
|
|
cast(42603003271 as decimal(18, 0)) % 3,
|
|
cast(42606961501 as decimal(18, 0)) % 3,
|
|
cast(42608445511 as decimal(18, 0)) % 3
|
|
---- RESULTS
|
|
2,0,0,1,1,1
|
|
---- TYPES
|
|
DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL
|
|
====
|