diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-10-08 19:19:21 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-10-08 19:19:21 +0400 |
commit | 7091b7852d27e6c8a1875b2acc0d1adbfb29984f (patch) | |
tree | f21b02377c02ecda4bde859d843a72d36e072f70 /sql/item_sum.cc | |
parent | 174a0b9eb70d33965677d375472db0694f6047fd (diff) | |
download | mariadb-git-7091b7852d27e6c8a1875b2acc0d1adbfb29984f.tar.gz |
MDEV-8918 Wrong result for CAST(AVG(bigint_column) AS SIGNED)
- Moving Item_xxx_field declarations after Item_sum_xxx declarations,
so Item_xxx_field constructors can be defined directly in item_sum.h
rather than item_sum.cc. This removes some duplicate code, e.g.
initialization of the following members at constructor time:
name, decimals, max_length, unsigned_flag, field, maybe_null.
- Adding Item_sum_field as a common parent for Item_avg_field and
Item_variance_field
- Deriving Item_sum_field directly from Item rather that Item_result_field,
as Item_sum_field descendants do not need anything from Item_result_field.
- Removing hybrid infrastructure from Item_avg_field,
adding Item_avg_field_decimal and Item_avg_field_double instead,
as desired result type is already known at constructor time
(not only at fix_fields time). This simplifies the code.
- Changing Item_avg_field_decimal::val_int() to call val_int_from_decimal()
instead of doing { return (longlong) rint(val_real()); }
This is the fix itself.
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r-- | sql/item_sum.cc | 69 |
1 files changed, 6 insertions, 63 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 8836b7638f3..5d471557892 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2502,7 +2502,10 @@ void Item_sum_avg::update_field() Item *Item_sum_avg::result_item(THD *thd, Field *field) { - return new (thd->mem_root) Item_avg_field(thd, hybrid_type, this); + return + hybrid_type == DECIMAL_RESULT ? + (Item_avg_field*) new (thd->mem_root) Item_avg_field_decimal(thd, this) : + (Item_avg_field*) new (thd->mem_root) Item_avg_field_double(thd, this); } @@ -2620,36 +2623,13 @@ Item_sum_hybrid::min_max_update_decimal_field() } -Item_avg_field::Item_avg_field(THD *thd, Item_result res_type, - Item_sum_avg *item): - Item_result_field(thd) -{ - name=item->name; - decimals=item->decimals; - max_length= item->max_length; - unsigned_flag= item->unsigned_flag; - field=item->result_field; - maybe_null=1; - hybrid_type= res_type; - prec_increment= item->prec_increment; - if (hybrid_type == DECIMAL_RESULT) - { - f_scale= item->f_scale; - f_precision= item->f_precision; - dec_bin_size= item->dec_bin_size; - } -} - -double Item_avg_field::val_real() +double Item_avg_field_double::val_real() { // fix_fields() never calls for this Item double nr; longlong count; uchar *res; - if (hybrid_type == DECIMAL_RESULT) - return val_real_from_decimal(); - float8get(nr,field->ptr); res= (field->ptr+sizeof(double)); count= sint8korr(res); @@ -2660,18 +2640,9 @@ double Item_avg_field::val_real() } -longlong Item_avg_field::val_int() -{ - return (longlong) rint(val_real()); -} - - -my_decimal *Item_avg_field::val_decimal(my_decimal *dec_buf) +my_decimal *Item_avg_field_decimal::val_decimal(my_decimal *dec_buf) { // fix_fields() never calls for this Item - if (hybrid_type == REAL_RESULT) - return val_decimal_from_real(dec_buf); - longlong count= sint8korr(field->ptr + dec_bin_size); if ((null_value= !count)) return 0; @@ -2686,21 +2657,6 @@ my_decimal *Item_avg_field::val_decimal(my_decimal *dec_buf) } -String *Item_avg_field::val_str(String *str) -{ - // fix_fields() never calls for this Item - if (hybrid_type == DECIMAL_RESULT) - return val_string_from_decimal(str); - return val_string_from_real(str); -} - - -Item_std_field::Item_std_field(THD *thd, Item_sum_std *item): - Item_variance_field(thd, item) -{ -} - - double Item_std_field::val_real() { double nr; @@ -2711,19 +2667,6 @@ double Item_std_field::val_real() } -Item_variance_field::Item_variance_field(THD *thd, Item_sum_variance *item): - Item_result_field(thd) -{ - name=item->name; - decimals=item->decimals; - max_length=item->max_length; - unsigned_flag= item->unsigned_flag; - field=item->result_field; - maybe_null=1; - sample= item->sample; -} - - double Item_variance_field::val_real() { // fix_fields() never calls for this Item |