diff --git a/mysql-test/r/win.result b/mysql-test/r/win.result index 33640b6842c..f5a23313a10 100644 --- a/mysql-test/r/win.result +++ b/mysql-test/r/win.result @@ -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; diff --git a/mysql-test/t/win.test b/mysql-test/t/win.test index 34920dbc911..fe494b65204 100644 --- a/mysql-test/t/win.test +++ b/mysql-test/t/win.test @@ -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; + diff --git a/sql/item.cc b/sql/item.cc index 4d3a3a6e3e7..65fb00d4757 100644 --- a/sql/item.cc +++ b/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,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); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 819f89d5ac4..009a642a790 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -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();