summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-10-08 19:19:21 +0400
committerAlexander Barkov <bar@mariadb.org>2015-10-08 19:19:21 +0400
commit7091b7852d27e6c8a1875b2acc0d1adbfb29984f (patch)
treef21b02377c02ecda4bde859d843a72d36e072f70 /sql/item_sum.cc
parent174a0b9eb70d33965677d375472db0694f6047fd (diff)
downloadmariadb-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.cc69
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