summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2014-02-25 16:04:35 +0100
committerSergei Golubchik <sergii@pisem.net>2014-02-25 16:04:35 +0100
commit0b9a0a3517ca2b75655f3af5c372cf333d3d5fe2 (patch)
tree5c67457ff8abbb89b203a7f55cda776b738c385b /sql/item_sum.cc
parent6324c36bd703a0f55dcd49dd721af262f73cf7aa (diff)
parentff2e82f4a175b7b023cd167b2fa6e6fcd1bd192e (diff)
downloadmariadb-git-0b9a0a3517ca2b75655f3af5c372cf333d3d5fe2.tar.gz
5.5 merge
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc71
1 files changed, 47 insertions, 24 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index e539d0b76b4..c824cc70617 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013 Monty Program Ab
+ Copyright (c) 2008, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -261,7 +261,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
List_iterator<Item_field> of(outer_fields);
while ((field= of++))
{
- SELECT_LEX *sel= field->cached_table->select_lex;
+ SELECT_LEX *sel= field->field->table->pos_in_table_list->select_lex;
if (sel->nest_level < aggr_level)
{
if (in_sum_func)
@@ -1110,18 +1110,19 @@ void Aggregator_distinct::endup()
endup_done= TRUE;
}
}
- else
- {
- /*
- We don't have a tree only if 'setup()' hasn't been called;
- this is the case of sql_select.cc:return_zero_rows.
- */
- if (tree)
- table->field[0]->set_notnull();
- }
+ /*
+ We don't have a tree only if 'setup()' hasn't been called;
+ this is the case of sql_executor.cc:return_zero_rows.
+ */
if (tree && !endup_done)
{
+ /*
+ All tree's values are not NULL.
+ Note that value of field is changed as we walk the tree, in
+ Aggregator_distinct::unique_walk_function, but it's always not NULL.
+ */
+ table->field[0]->set_notnull();
/* go over the tree of distinct keys and calculate the aggregate value */
use_distinct_values= TRUE;
tree_walk_action func;
@@ -1417,7 +1418,7 @@ bool Item_sum_sum::add()
{
my_decimal value;
const my_decimal *val= aggr->arg_val_decimal(&value);
- if (!aggr->arg_is_null())
+ if (!aggr->arg_is_null(true))
{
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1),
val, dec_buffs + curr_dec_buff);
@@ -1428,7 +1429,7 @@ bool Item_sum_sum::add()
else
{
sum+= aggr->arg_val_real();
- if (!aggr->arg_is_null())
+ if (!aggr->arg_is_null(true))
null_value= 0;
}
DBUG_RETURN(0);
@@ -1554,9 +1555,27 @@ double Aggregator_simple::arg_val_real()
}
-bool Aggregator_simple::arg_is_null()
+bool Aggregator_simple::arg_is_null(bool use_null_value)
{
- return item_sum->args[0]->null_value;
+ Item **item= item_sum->args;
+ const uint item_count= item_sum->arg_count;
+ if (use_null_value)
+ {
+ for (uint i= 0; i < item_count; i++)
+ {
+ if (item[i]->null_value)
+ return true;
+ }
+ }
+ else
+ {
+ for (uint i= 0; i < item_count; i++)
+ {
+ if (item[i]->maybe_null && item[i]->is_null())
+ return true;
+ }
+ }
+ return false;
}
@@ -1574,10 +1593,17 @@ double Aggregator_distinct::arg_val_real()
}
-bool Aggregator_distinct::arg_is_null()
+bool Aggregator_distinct::arg_is_null(bool use_null_value)
{
- return use_distinct_values ? table->field[0]->is_null() :
- item_sum->args[0]->null_value;
+ if (use_distinct_values)
+ {
+ const bool rc= table->field[0]->is_null();
+ DBUG_ASSERT(!rc); // NULLs are never stored in 'tree'
+ return rc;
+ }
+ return use_null_value ?
+ item_sum->args[0]->null_value :
+ (item_sum->args[0]->maybe_null && item_sum->args[0]->is_null());
}
@@ -1595,11 +1621,8 @@ void Item_sum_count::clear()
bool Item_sum_count::add()
{
- for (uint i=0; i<arg_count; i++)
- {
- if (args[i]->maybe_null && args[i]->is_null())
- return 0;
- }
+ if (aggr->arg_is_null(false))
+ return 0;
count++;
return 0;
}
@@ -1691,7 +1714,7 @@ bool Item_sum_avg::add()
{
if (Item_sum_sum::add())
return TRUE;
- if (!aggr->arg_is_null())
+ if (!aggr->arg_is_null(true))
count++;
return FALSE;
}