summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2016-09-09 18:53:01 +0300
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2016-09-09 18:53:01 +0300
commitbe2b833c426b420073c50564125049e2b4a95e8b (patch)
tree7d039878d9608833a0ef396fa42e5fc1c09b0fbb /sql/item_sum.cc
parenta37f24b903b282e7fb63261f3b258c6874606e43 (diff)
downloadmariadb-git-be2b833c426b420073c50564125049e2b4a95e8b.tar.gz
It is now possible to remove values multiple times from window functions
This can happen with degenerate frame definitions that are always empty.
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc32
1 files changed, 21 insertions, 11 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index c656d6678fc..83378c2e994 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1352,10 +1352,14 @@ void Item_sum_sum::add_helper(bool perform_removal)
{
if (perform_removal)
{
- DBUG_ASSERT(count > 0);
- my_decimal_sub(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
- dec_buffs + curr_dec_buff, val);
- count--;
+ if (count > 0)
+ {
+ my_decimal_sub(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
+ dec_buffs + curr_dec_buff, val);
+ count--;
+ }
+ else
+ DBUG_VOID_RETURN;
}
else
{
@@ -1369,7 +1373,7 @@ void Item_sum_sum::add_helper(bool perform_removal)
}
else
{
- if (perform_removal)
+ if (perform_removal && count > 0)
sum-= aggr->arg_val_real();
else
sum+= aggr->arg_val_real();
@@ -1377,8 +1381,10 @@ void Item_sum_sum::add_helper(bool perform_removal)
{
if (perform_removal)
{
- DBUG_ASSERT(count > 0);
- count--;
+ if (count > 0)
+ {
+ count--;
+ }
}
else
count++;
@@ -1598,7 +1604,8 @@ void Item_sum_count::remove()
DBUG_ASSERT(aggr->Aggrtype() == Aggregator::SIMPLE_AGGREGATOR);
if (aggr->arg_is_null(false))
return;
- count--;
+ if (count > 0)
+ count--;
}
longlong Item_sum_count::val_int()
@@ -1702,8 +1709,8 @@ void Item_sum_avg::remove()
Item_sum_sum::remove();
if (!aggr->arg_is_null(true))
{
- DBUG_ASSERT(count > 0);
- count--;
+ if (count > 0)
+ count--;
}
}
@@ -2190,6 +2197,9 @@ bool Item_sum_bit::clear_as_window()
bool Item_sum_bit::remove_as_window(ulonglong value)
{
DBUG_ASSERT(as_window_function);
+ if (num_values_added == 0)
+ return 0; // Nothing to remove.
+
for (int i= 0; i < NUM_BIT_COUNTERS; i++)
{
if (!bit_counters[i])
@@ -2200,7 +2210,7 @@ bool Item_sum_bit::remove_as_window(ulonglong value)
}
bit_counters[i]-= (value & (1 << i)) ? 1 : 0;
}
- DBUG_ASSERT(num_values_added > 0);
+
// Prevent overflow;
num_values_added = std::min(num_values_added, num_values_added - 1);
set_bits_from_counters();