mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
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.
This commit is contained in:
42
mysql-test/r/win_sum.result
Normal file
42
mysql-test/r/win_sum.result
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
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;
|
32
mysql-test/t/win_sum.test
Normal file
32
mysql-test/t/win_sum.test
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
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()
|
|||||||
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)
|
|||||||
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 @@ public:
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
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
|
||||||
|
Reference in New Issue
Block a user