summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_sum.cc84
-rw-r--r--sql/item_sum.h16
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();
};