diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2016-09-09 18:53:01 +0300 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2016-09-09 18:53:01 +0300 |
commit | be2b833c426b420073c50564125049e2b4a95e8b (patch) | |
tree | 7d039878d9608833a0ef396fa42e5fc1c09b0fbb /sql/item_sum.cc | |
parent | a37f24b903b282e7fb63261f3b258c6874606e43 (diff) | |
download | mariadb-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.cc | 32 |
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(); |