summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2013-03-27 19:17:32 -0700
committerIgor Babaev <igor@askmonty.org>2013-03-27 19:17:32 -0700
commit323fdd7ac6e6541a6cc3ab7c48e330805c67d4f3 (patch)
tree6e66f251d147e7daa6a78ce88a8e41d8bf1d871c /sql/item_sum.cc
parent495fd27c0e3781013904666f302a3d3e4f011e50 (diff)
downloadmariadb-git-323fdd7ac6e6541a6cc3ab7c48e330805c67d4f3.tar.gz
Fixed bug mdev-4311 (bug #68749).
This bug was introduced by the patch for WL#3220. If the memory allocated for the tree to store unique elements to be counted is not big enough to include all of them then an external file is used to store the elements. The unique elements are guaranteed not to be nulls. So, when reading them from the file we don't have to care about the null flags of the read values. However, we should remove the flag at the very beginning of the process. If we don't do it and if the last value written into the record buffer for the field whose distinct values needs to be counted happens to be null, then all values read from the file are considered to be nulls and are not counted in. The fix does not remove a possible null flag for the read values. Rather it just counts the values in the same way it was done before WL #3220.
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc31
1 files changed, 30 insertions, 1 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 72e0e637d38..3bd00ee828d 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -719,6 +719,14 @@ static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
}
+static int item_sum_distinct_walk_for_count(void *element,
+ element_count num_of_dups,
+ void *item)
+{
+ return ((Aggregator_distinct*) (item))->unique_walk_function_for_count(element);
+}
+
+
static int item_sum_distinct_walk(void *element, element_count num_of_dups,
void *item)
{
@@ -1089,7 +1097,12 @@ void Aggregator_distinct::endup()
{
/* go over the tree of distinct keys and calculate the aggregate value */
use_distinct_values= TRUE;
- tree->walk(table, item_sum_distinct_walk, (void*) this);
+ tree_walk_action func;
+ if (item_sum->sum_func() == Item_sum::COUNT_DISTINCT_FUNC)
+ func= item_sum_distinct_walk_for_count;
+ else
+ func= item_sum_distinct_walk;
+ tree->walk(table, func, (void*) this);
use_distinct_values= FALSE;
}
/* prevent consecutive recalculations */
@@ -1466,6 +1479,22 @@ bool Aggregator_distinct::unique_walk_function(void *element)
}
+/*
+ A variant of unique_walk_function() that is to be used with Item_sum_count.
+
+ COUNT is a special aggregate function: it doesn't need the values, it only
+ needs to count them. COUNT needs to know the values are not NULLs, but NULL
+ values are not put into the Unique, so we don't need to check for NULLs here.
+*/
+
+bool Aggregator_distinct::unique_walk_function_for_count(void *element)
+{
+ Item_sum_count *sum= (Item_sum_count *)item_sum;
+ sum->count++;
+ return 0;
+}
+
+
Aggregator_distinct::~Aggregator_distinct()
{
if (tree)