Commit a0c06ba1 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

Preliminary implementation for the aggregate sum function as a window function

This implementation does not deal with the case where removal of
elements from the window frame causes the item to turn to a null value.
parent ce8a0d8e
create table t1 (
pk int primary key,
a int,
b int,
c real
);
insert into t1 values
(101 , 0, 10, 1.1),
(102 , 0, 10, 2.1),
(103 , 1, 10, 3.1),
(104 , 1, 10, 4.1),
(108 , 2, 10, 5.1),
(105 , 2, 20, 6.1),
(106 , 2, 20, 7.1),
(107 , 2, 20, 8.15),
(109 , 4, 20, 9.15),
(110 , 4, 20, 10.15),
(111 , 5, NULL, 11.15),
(112 , 5, 1, 12.25),
(113 , 5, NULL, 13.35),
(114 , 5, NULL, 14.50),
(115 , 5, NULL, 15.65);
select pk, a, b, sum(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
sum(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
from t1;
pk a b sum(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) sum(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
101 0 10 20 3.2
102 0 10 20 3.2
103 1 10 20 7.199999999999999
104 1 10 20 7.199999999999999
105 2 20 40 13.2
106 2 20 60 21.35
107 2 20 50 20.35
108 2 10 30 13.250000000000002
109 4 20 40 19.3
110 4 20 40 19.3
111 5 NULL 1 23.4
112 5 1 1 36.75
113 5 NULL 1 40.1
114 5 NULL 0 43.5
115 5 NULL 0 30.15
drop table t1;
create table t1 (
pk int primary key,
a int,
b int,
c real
);
insert into t1 values
(101 , 0, 10, 1.1),
(102 , 0, 10, 2.1),
(103 , 1, 10, 3.1),
(104 , 1, 10, 4.1),
(108 , 2, 10, 5.1),
(105 , 2, 20, 6.1),
(106 , 2, 20, 7.1),
(107 , 2, 20, 8.15),
(109 , 4, 20, 9.15),
(110 , 4, 20, 10.15),
(111 , 5, NULL, 11.15),
(112 , 5, 1, 12.25),
(113 , 5, NULL, 13.35),
(114 , 5, NULL, 14.50),
(115 , 5, NULL, 15.65);
--sorted_result
select pk, a, b, sum(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
sum(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
from t1;
drop table t1;
...@@ -1318,25 +1318,39 @@ void Item_sum_sum::fix_length_and_dec() ...@@ -1318,25 +1318,39 @@ void Item_sum_sum::fix_length_and_dec()
bool Item_sum_sum::add() bool Item_sum_sum::add()
{ {
DBUG_ENTER("Item_sum_sum::add"); DBUG_ENTER("Item_sum_sum::add");
add_helper(false);
DBUG_RETURN(0);
}
void Item_sum_sum::add_helper(bool perform_removal)
{
DBUG_ENTER("Item_sum_sum::add_helper");
if (Item_sum_sum::result_type() == DECIMAL_RESULT) if (Item_sum_sum::result_type() == DECIMAL_RESULT)
{ {
my_decimal value; my_decimal value;
const my_decimal *val= aggr->arg_val_decimal(&value); const my_decimal *val= aggr->arg_val_decimal(&value);
if (!aggr->arg_is_null(true)) if (!aggr->arg_is_null(true))
{ {
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1), if (perform_removal)
val, dec_buffs + curr_dec_buff); my_decimal_sub(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
dec_buffs + curr_dec_buff, val);
else
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
val, dec_buffs + curr_dec_buff);
curr_dec_buff^= 1; curr_dec_buff^= 1;
null_value= 0; null_value= 0;
} }
} }
else else
{ {
sum+= aggr->arg_val_real(); if (perform_removal)
sum-= aggr->arg_val_real();
else
sum+= aggr->arg_val_real();
if (!aggr->arg_is_null(true)) if (!aggr->arg_is_null(true))
null_value= 0; null_value= 0;
} }
DBUG_RETURN(0); DBUG_VOID_RETURN;
} }
...@@ -1386,6 +1400,13 @@ my_decimal *Item_sum_sum::val_decimal(my_decimal *val) ...@@ -1386,6 +1400,13 @@ my_decimal *Item_sum_sum::val_decimal(my_decimal *val)
return val_decimal_from_real(val); return val_decimal_from_real(val);
} }
void Item_sum_sum::remove()
{
DBUG_ENTER("Item_sum_sum::remove");
add_helper(true);
DBUG_VOID_RETURN;
}
/** /**
Aggregate a distinct row from the distinct hash table. Aggregate a distinct row from the distinct hash table.
......
...@@ -773,6 +773,10 @@ class Item_sum_sum :public Item_sum_num, ...@@ -773,6 +773,10 @@ class Item_sum_sum :public Item_sum_num,
return has_with_distinct() ? "sum(distinct " : "sum("; return has_with_distinct() ? "sum(distinct " : "sum(";
} }
Item *copy_or_same(THD* thd); Item *copy_or_same(THD* thd);
void remove();
private:
void add_helper(bool perform_removal);
}; };
......
...@@ -1584,6 +1584,7 @@ bool JOIN::process_window_functions(List<Item> *curr_fields_list) ...@@ -1584,6 +1584,7 @@ bool JOIN::process_window_functions(List<Item> *curr_fields_list)
} }
case Item_sum::COUNT_FUNC: case Item_sum::COUNT_FUNC:
case Item_sum::SUM_BIT_FUNC: case Item_sum::SUM_BIT_FUNC:
case Item_sum::SUM_FUNC:
{ {
/* /*
Frame-aware window function computation. It does one pass, but Frame-aware window function computation. It does one pass, but
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment