diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_sum.cc | 84 | ||||
-rw-r--r-- | sql/item_sum.h | 16 |
2 files changed, 61 insertions, 39 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 8cd8e1bb222..cf95fc3969f 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1325,27 +1325,11 @@ void Item_sum_sum::fix_length_and_dec() bool Item_sum_sum::add() { DBUG_ENTER("Item_sum_sum::add"); - bool arg_is_null; if (hybrid_type == DECIMAL_RESULT) { - my_decimal value, *val; - if (aggr->use_distinct_values) - { - /* - We are aggregating distinct rows. Get the value from the distinct - table pointer - */ - Aggregator_distinct *daggr= (Aggregator_distinct *)aggr; - val= daggr->table->field[0]->val_decimal (&value); - arg_is_null= daggr->table->field[0]->is_null(); - } - else - { - /* non-distinct aggregation */ - val= args[0]->val_decimal(&value); - arg_is_null= args[0]->null_value; - } - if (!arg_is_null) + my_decimal value; + const my_decimal *val= aggr->arg_val_decimal(&value); + if (!aggr->arg_is_null()) { my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1), val, dec_buffs + curr_dec_buff); @@ -1355,25 +1339,8 @@ bool Item_sum_sum::add() } else { - double val; - if (aggr->use_distinct_values) - { - /* - We are aggregating distinct rows. Get the value from the distinct - table pointer - */ - Aggregator_distinct *daggr= (Aggregator_distinct *)aggr; - val= daggr->table->field[0]->val_real (); - arg_is_null= daggr->table->field[0]->is_null(); - } - else - { - /* non-distinct aggregation */ - val= args[0]->val_real(); - arg_is_null= args[0]->null_value; - } - sum+= val; - if (!arg_is_null) + sum+= aggr->arg_val_real(); + if (!aggr->arg_is_null()) null_value= 0; } DBUG_RETURN(0); @@ -1471,6 +1438,45 @@ Aggregator_distinct::~Aggregator_distinct() } +my_decimal *Aggregator_simple::arg_val_decimal(my_decimal *value) +{ + return item_sum->args[0]->val_decimal(value); +} + + +double Aggregator_simple::arg_val_real() +{ + return item_sum->args[0]->val_real(); +} + + +bool Aggregator_simple::arg_is_null() +{ + return item_sum->args[0]->null_value; +} + + +my_decimal *Aggregator_distinct::arg_val_decimal(my_decimal * value) +{ + return use_distinct_values ? table->field[0]->val_decimal(value) : + item_sum->args[0]->val_decimal(value); +} + + +double Aggregator_distinct::arg_val_real() +{ + return use_distinct_values ? table->field[0]->val_real() : + item_sum->args[0]->val_real(); +} + + +bool Aggregator_distinct::arg_is_null() +{ + return use_distinct_values ? table->field[0]->is_null() : + item_sum->args[0]->null_value; +} + + Item *Item_sum_count::copy_or_same(THD* thd) { return new (thd->mem_root) Item_sum_count(thd, this); @@ -1576,7 +1582,7 @@ bool Item_sum_avg::add() { if (Item_sum_sum::add()) return TRUE; - if (!args[0]->null_value) + if (!aggr->arg_is_null()) count++; return FALSE; } diff --git a/sql/item_sum.h b/sql/item_sum.h index 06a8c2c58a4..c7159568c40 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -101,6 +101,15 @@ public: */ virtual void endup() = 0; + /** Decimal value of being-aggregated argument */ + virtual my_decimal *arg_val_decimal(my_decimal * value) = 0; + /** Floating point value of being-aggregated argument */ + virtual double arg_val_real() = 0; + /** + NULLness of being-aggregated argument; can be called only after + arg_val_decimal() or arg_val_real(). + */ + virtual bool arg_is_null() = 0; }; @@ -304,6 +313,7 @@ class st_select_lex; class Item_sum :public Item_result_field { friend class Aggregator_distinct; + friend class Aggregator_simple; protected: /** @@ -600,6 +610,9 @@ public: void clear(); bool add(); void endup(); + virtual my_decimal *arg_val_decimal(my_decimal * value); + virtual double arg_val_real(); + virtual bool arg_is_null(); bool unique_walk_function(void *element); static int composite_key_cmp(void* arg, uchar* key1, uchar* key2); @@ -623,6 +636,9 @@ public: void clear() { item_sum->clear(); } bool add() { return item_sum->add(); } void endup() {}; + virtual my_decimal *arg_val_decimal(my_decimal * value); + virtual double arg_val_real(); + virtual bool arg_is_null(); }; |