diff options
author | unknown <kaa@kaamos.(none)> | 2008-03-06 18:19:47 +0300 |
---|---|---|
committer | unknown <kaa@kaamos.(none)> | 2008-03-06 18:19:47 +0300 |
commit | 8270d9875ff44900f3c57c15711c03d0b83cbe5d (patch) | |
tree | 70b4e94747923d70161e799b874a3d59a8c57e66 /sql | |
parent | 64bdb0bdf2821cb4021649797e02a4ed98cf86e7 (diff) | |
download | mariadb-git-8270d9875ff44900f3c57c15711c03d0b83cbe5d.tar.gz |
Fix for bug #34512: CAST( AVG( double ) AS DECIMAL )
returns wrong results
Casting AVG() to DECIMAL led to incorrect results when the arguments
had a non-DECIMAL type, because in this case
Item_sum_avg::val_decimal() performed the division by the number of
arguments twice.
Fixed by changing Item_sum_avg::val_decimal() to not rely on
Item_sum_sum::val_decimal(), i.e. calculate sum and divide using
DECIMAL arithmetics for DECIMAL arguments, and utilize val_real() with
subsequent conversion to DECIMAL otherwise.
mysql-test/r/func_group.result:
Added a test case for bug #34512.
mysql-test/t/func_group.test:
Added a test case for bug #34512.
sql/item_sum.cc:
Do not use Item_sum_sum::val_decimal() in Item_sum_avg::val_decimal()
because the first one, depending on the arguments type, may return
either the sum of the arguments, or the average calculated by the
virtual val_real() method of Item_sum_avg. Instead, do our own
calculation based on the arguments type.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_sum.cc | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 3d6d46ab3f4..f583fc7f988 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1206,7 +1206,15 @@ my_decimal *Item_sum_avg::val_decimal(my_decimal *val) null_value=1; return NULL; } - sum_dec= Item_sum_sum::val_decimal(&sum_buff); + + /* + For non-DECIMAL hybrid_type the division will be done in + Item_sum_avg::val_real(). + */ + if (hybrid_type != DECIMAL_RESULT) + return val_decimal_from_real(val); + + sum_dec= dec_buffs + curr_dec_buff; int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &cnt); my_decimal_div(E_DEC_FATAL_ERROR, val, sum_dec, &cnt, prec_increment); return val; |