Commit 29705a4d authored by Sergei Petrunia's avatar Sergei Petrunia

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.
parent 91fc90c3
......@@ -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;
......@@ -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,13 +1819,24 @@ 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 (!(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() == 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();
item_ref->depended_from= ((Item_sum *) this)->depended_from();
fields.push_front(real_itm);
thd->change_item_tree(ref, item_ref);
}
......
......@@ -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();
......
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