Skip to content

Commit 29705a4

Browse files
committed
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.
1 parent 91fc90c commit 29705a4

File tree

4 files changed

+63
-8
lines changed

4 files changed

+63
-8
lines changed

mysql-test/r/win.result

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,3 +1812,22 @@ s1 s2 X
18121812
NULL a 2
18131813
NULL NULL 1
18141814
drop table t1;
1815+
#
1816+
# Try window functions that are not directly present in the select list
1817+
#
1818+
create table t1 (a int, b int);
1819+
insert into t1 values
1820+
(1,3),
1821+
(2,2),
1822+
(3,1);
1823+
select
1824+
rank() over (order by a) -
1825+
rank() over (order by b)
1826+
from
1827+
t1;
1828+
rank() over (order by a) -
1829+
rank() over (order by b)
1830+
0
1831+
0
1832+
0
1833+
drop table t1;

mysql-test/t/win.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,3 +1096,20 @@ select *, row_number() over (order by s1, s2) as X from t1 order by X desc;
10961096
select *, row_number() over (order by s1, s2) as X from t1 order by X desc;
10971097
drop table t1;
10981098

1099+
--echo #
1100+
--echo # Try window functions that are not directly present in the select list
1101+
--echo #
1102+
create table t1 (a int, b int);
1103+
insert into t1 values
1104+
(1,3),
1105+
(2,2),
1106+
(3,1);
1107+
1108+
select
1109+
rank() over (order by a) -
1110+
rank() over (order by b)
1111+
from
1112+
t1;
1113+
1114+
drop table t1;
1115+

sql/item.cc

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,14 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
17611761
((Item_sum *) this)->ref_by)
17621762
return;
17631763
}
1764+
else if (type() == WINDOW_FUNC_ITEM)
1765+
{
1766+
/*
1767+
Skip the else part, window functions are very special functions:
1768+
they need to have their own fields in the temp. table, but they
1769+
need to be proceessed differently than regular aggregate functions
1770+
*/
1771+
}
17641772
else
17651773
{
17661774
/* Not a SUM() function */
@@ -1801,7 +1809,7 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
18011809
Exception is Item_direct_view_ref which we need to convert to
18021810
Item_ref to allow fields from view being stored in tmp table.
18031811
*/
1804-
Item_aggregate_ref *item_ref;
1812+
Item_ref *item_ref;
18051813
uint el= fields.elements;
18061814
/*
18071815
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,
18111819
Item *real_itm= real_item();
18121820

18131821
ref_pointer_array[el]= real_itm;
1814-
if (!(item_ref= (new (thd->mem_root)
1815-
Item_aggregate_ref(thd,
1816-
&thd->lex->current_select->context,
1817-
&ref_pointer_array[el], 0, name))))
1818-
return; // fatal_error is set
1822+
if (type() == WINDOW_FUNC_ITEM)
1823+
{
1824+
if (!(item_ref= (new (thd->mem_root)
1825+
Item_direct_ref(thd,
1826+
&thd->lex->current_select->context,
1827+
&ref_pointer_array[el], 0, name))))
1828+
return; // fatal_error is set
1829+
}
1830+
else
1831+
{
1832+
if (!(item_ref= (new (thd->mem_root)
1833+
Item_aggregate_ref(thd,
1834+
&thd->lex->current_select->context,
1835+
&ref_pointer_array[el], 0, name))))
1836+
return; // fatal_error is set
1837+
}
18191838
if (type() == SUM_FUNC_ITEM)
1820-
item_ref->depended_from= ((Item_sum *) this)->depended_from();
1839+
item_ref->depended_from= ((Item_sum *) this)->depended_from();
18211840
fields.push_front(real_itm);
18221841
thd->change_item_tree(ref, item_ref);
18231842
}

sql/sql_base.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7911,7 +7911,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
79117911
Item_window_func::split_sum_func.
79127912
*/
79137913
if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
7914-
sum_func_list) || item->type() == Item::WINDOW_FUNC_ITEM)
7914+
sum_func_list) || item->with_window_func)
79157915
item->split_sum_func(thd, ref_pointer_array, *sum_func_list,
79167916
SPLIT_SUM_SELECT);
79177917
thd->lex->current_select->select_list_tables|= item->used_tables();

0 commit comments

Comments
 (0)