mirror of
https://github.com/MariaDB/server.git
synced 2025-05-08 15:01:49 +03:00
Window functions: handle window functions as arguments to other functions
Window functions need to have their own column in the work (temp) table, like aggregate functions do. They don't need val_int() -> val_int_result() conversion though, so they should be wrapped with Item_direct_ref, not Item_aggregate_ref.
This commit is contained in:
parent
91fc90c372
commit
29705a4d38
@ -1812,3 +1812,22 @@ s1 s2 X
|
||||
NULL a 2
|
||||
NULL NULL 1
|
||||
drop table t1;
|
||||
#
|
||||
# Try window functions that are not directly present in the select list
|
||||
#
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values
|
||||
(1,3),
|
||||
(2,2),
|
||||
(3,1);
|
||||
select
|
||||
rank() over (order by a) -
|
||||
rank() over (order by b)
|
||||
from
|
||||
t1;
|
||||
rank() over (order by a) -
|
||||
rank() over (order by b)
|
||||
0
|
||||
0
|
||||
0
|
||||
drop table t1;
|
||||
|
@ -1096,3 +1096,20 @@ select *, row_number() over (order by s1, s2) as X from t1 order by X desc;
|
||||
select *, row_number() over (order by s1, s2) as X from t1 order by X desc;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # Try window functions that are not directly present in the select list
|
||||
--echo #
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values
|
||||
(1,3),
|
||||
(2,2),
|
||||
(3,1);
|
||||
|
||||
select
|
||||
rank() over (order by a) -
|
||||
rank() over (order by b)
|
||||
from
|
||||
t1;
|
||||
|
||||
drop table t1;
|
||||
|
||||
|
21
sql/item.cc
21
sql/item.cc
@ -1761,6 +1761,14 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
((Item_sum *) this)->ref_by)
|
||||
return;
|
||||
}
|
||||
else if (type() == WINDOW_FUNC_ITEM)
|
||||
{
|
||||
/*
|
||||
Skip the else part, window functions are very special functions:
|
||||
they need to have their own fields in the temp. table, but they
|
||||
need to be proceessed differently than regular aggregate functions
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not a SUM() function */
|
||||
@ -1801,7 +1809,7 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
Exception is Item_direct_view_ref which we need to convert to
|
||||
Item_ref to allow fields from view being stored in tmp table.
|
||||
*/
|
||||
Item_aggregate_ref *item_ref;
|
||||
Item_ref *item_ref;
|
||||
uint el= fields.elements;
|
||||
/*
|
||||
If this is an item_ref, get the original item
|
||||
@ -1811,11 +1819,22 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
Item *real_itm= real_item();
|
||||
|
||||
ref_pointer_array[el]= real_itm;
|
||||
if (type() == WINDOW_FUNC_ITEM)
|
||||
{
|
||||
if (!(item_ref= (new (thd->mem_root)
|
||||
Item_direct_ref(thd,
|
||||
&thd->lex->current_select->context,
|
||||
&ref_pointer_array[el], 0, name))))
|
||||
return; // fatal_error is set
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(item_ref= (new (thd->mem_root)
|
||||
Item_aggregate_ref(thd,
|
||||
&thd->lex->current_select->context,
|
||||
&ref_pointer_array[el], 0, name))))
|
||||
return; // fatal_error is set
|
||||
}
|
||||
if (type() == SUM_FUNC_ITEM)
|
||||
item_ref->depended_from= ((Item_sum *) this)->depended_from();
|
||||
fields.push_front(real_itm);
|
||||
|
@ -7911,7 +7911,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
Item_window_func::split_sum_func.
|
||||
*/
|
||||
if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
|
||||
sum_func_list) || item->type() == Item::WINDOW_FUNC_ITEM)
|
||||
sum_func_list) || item->with_window_func)
|
||||
item->split_sum_func(thd, ref_pointer_array, *sum_func_list,
|
||||
SPLIT_SUM_SELECT);
|
||||
thd->lex->current_select->select_list_tables|= item->used_tables();
|
||||
|
Loading…
x
Reference in New Issue
Block a user