Skip to content

Commit a0c06ba

Browse files
committed
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.
1 parent ce8a0d8 commit a0c06ba

File tree

5 files changed

+104
-4
lines changed

5 files changed

+104
-4
lines changed

mysql-test/r/win_sum.result

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
create table t1 (
2+
pk int primary key,
3+
a int,
4+
b int,
5+
c real
6+
);
7+
insert into t1 values
8+
(101 , 0, 10, 1.1),
9+
(102 , 0, 10, 2.1),
10+
(103 , 1, 10, 3.1),
11+
(104 , 1, 10, 4.1),
12+
(108 , 2, 10, 5.1),
13+
(105 , 2, 20, 6.1),
14+
(106 , 2, 20, 7.1),
15+
(107 , 2, 20, 8.15),
16+
(109 , 4, 20, 9.15),
17+
(110 , 4, 20, 10.15),
18+
(111 , 5, NULL, 11.15),
19+
(112 , 5, 1, 12.25),
20+
(113 , 5, NULL, 13.35),
21+
(114 , 5, NULL, 14.50),
22+
(115 , 5, NULL, 15.65);
23+
select pk, a, b, sum(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
24+
sum(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
25+
from t1;
26+
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)
27+
101 0 10 20 3.2
28+
102 0 10 20 3.2
29+
103 1 10 20 7.199999999999999
30+
104 1 10 20 7.199999999999999
31+
105 2 20 40 13.2
32+
106 2 20 60 21.35
33+
107 2 20 50 20.35
34+
108 2 10 30 13.250000000000002
35+
109 4 20 40 19.3
36+
110 4 20 40 19.3
37+
111 5 NULL 1 23.4
38+
112 5 1 1 36.75
39+
113 5 NULL 1 40.1
40+
114 5 NULL 0 43.5
41+
115 5 NULL 0 30.15
42+
drop table t1;

mysql-test/t/win_sum.test

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
create table t1 (
2+
pk int primary key,
3+
a int,
4+
b int,
5+
c real
6+
);
7+
8+
9+
insert into t1 values
10+
(101 , 0, 10, 1.1),
11+
(102 , 0, 10, 2.1),
12+
(103 , 1, 10, 3.1),
13+
(104 , 1, 10, 4.1),
14+
(108 , 2, 10, 5.1),
15+
(105 , 2, 20, 6.1),
16+
(106 , 2, 20, 7.1),
17+
(107 , 2, 20, 8.15),
18+
(109 , 4, 20, 9.15),
19+
(110 , 4, 20, 10.15),
20+
(111 , 5, NULL, 11.15),
21+
(112 , 5, 1, 12.25),
22+
(113 , 5, NULL, 13.35),
23+
(114 , 5, NULL, 14.50),
24+
(115 , 5, NULL, 15.65);
25+
26+
--sorted_result
27+
select pk, a, b, sum(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
28+
sum(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
29+
30+
from t1;
31+
32+
drop table t1;

sql/item_sum.cc

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,25 +1318,39 @@ void Item_sum_sum::fix_length_and_dec()
13181318
bool Item_sum_sum::add()
13191319
{
13201320
DBUG_ENTER("Item_sum_sum::add");
1321+
add_helper(false);
1322+
DBUG_RETURN(0);
1323+
}
1324+
1325+
void Item_sum_sum::add_helper(bool perform_removal)
1326+
{
1327+
DBUG_ENTER("Item_sum_sum::add_helper");
13211328
if (Item_sum_sum::result_type() == DECIMAL_RESULT)
13221329
{
13231330
my_decimal value;
13241331
const my_decimal *val= aggr->arg_val_decimal(&value);
13251332
if (!aggr->arg_is_null(true))
13261333
{
1327-
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1),
1328-
val, dec_buffs + curr_dec_buff);
1334+
if (perform_removal)
1335+
my_decimal_sub(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
1336+
dec_buffs + curr_dec_buff, val);
1337+
else
1338+
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff ^ 1),
1339+
val, dec_buffs + curr_dec_buff);
13291340
curr_dec_buff^= 1;
13301341
null_value= 0;
13311342
}
13321343
}
13331344
else
13341345
{
1335-
sum+= aggr->arg_val_real();
1346+
if (perform_removal)
1347+
sum-= aggr->arg_val_real();
1348+
else
1349+
sum+= aggr->arg_val_real();
13361350
if (!aggr->arg_is_null(true))
13371351
null_value= 0;
13381352
}
1339-
DBUG_RETURN(0);
1353+
DBUG_VOID_RETURN;
13401354
}
13411355

13421356

@@ -1386,6 +1400,13 @@ my_decimal *Item_sum_sum::val_decimal(my_decimal *val)
13861400
return val_decimal_from_real(val);
13871401
}
13881402

1403+
void Item_sum_sum::remove()
1404+
{
1405+
DBUG_ENTER("Item_sum_sum::remove");
1406+
add_helper(true);
1407+
DBUG_VOID_RETURN;
1408+
}
1409+
13891410
/**
13901411
Aggregate a distinct row from the distinct hash table.
13911412

sql/item_sum.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,10 @@ class Item_sum_sum :public Item_sum_num,
773773
return has_with_distinct() ? "sum(distinct " : "sum(";
774774
}
775775
Item *copy_or_same(THD* thd);
776+
void remove();
777+
778+
private:
779+
void add_helper(bool perform_removal);
776780
};
777781

778782

sql/sql_window.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,7 @@ bool JOIN::process_window_functions(List<Item> *curr_fields_list)
15841584
}
15851585
case Item_sum::COUNT_FUNC:
15861586
case Item_sum::SUM_BIT_FUNC:
1587+
case Item_sum::SUM_FUNC:
15871588
{
15881589
/*
15891590
Frame-aware window function computation. It does one pass, but

0 commit comments

Comments
 (0)