summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2016-09-22 14:21:18 +0200
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2016-09-24 15:12:34 +0200
commit3dd3a5da0e9fbd8a24a178b2b295b5a385beba5e (patch)
tree37deca84f2ffe304421f72b5c3a41daf6cb2948e /sql
parente992464f27c12abca621f420dc9650189173ab86 (diff)
downloadmariadb-git-3dd3a5da0e9fbd8a24a178b2b295b5a385beba5e.tar.gz
MDEV-9935: Window functions: assertion failure with empty OVER () clause
Make window functions work with an empty over clause by forcing a sort on the first column of the current join_tab. This is a temporary fix until we get window functions to work with big tables.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_window.cc26
-rw-r--r--sql/sql_window.h3
2 files changed, 26 insertions, 3 deletions
diff --git a/sql/sql_window.cc b/sql/sql_window.cc
index 5d929101e10..15045924e83 100644
--- a/sql/sql_window.cc
+++ b/sql/sql_window.cc
@@ -2509,7 +2509,8 @@ bool Window_funcs_sort::exec(JOIN *join)
bool Window_funcs_sort::setup(THD *thd, SQL_SELECT *sel,
- List_iterator<Item_window_func> &it)
+ List_iterator<Item_window_func> &it,
+ JOIN_TAB *join_tab)
{
Window_spec *spec;
Item_window_func *win_func= it.peek();
@@ -2547,6 +2548,27 @@ bool Window_funcs_sort::setup(THD *thd, SQL_SELECT *sel,
ORDER* sort_order= concat_order_lists(thd->mem_root,
spec->partition_list->first,
spec->order_list->first);
+ if (sort_order == NULL) // No partition or order by clause.
+ {
+ /* TODO(cvicentiu) This is used as a way to allow an empty OVER ()
+ clause for window functions. However, a better approach is
+ to not call Filesort at all in this case and just read whatever order
+ the temporary table has.
+ Due to cursors not working for out_of_memory cases (yet!), we have to run
+ filesort to generate a sort buffer of the results.
+ In this case we sort by the first field of the temporary table.
+ We should have this field available, even if it is a window_function
+ field. We don't care of the particular sorting result in this case.
+ */
+ ORDER *order= (ORDER *)alloc_root(thd->mem_root, sizeof(ORDER));
+ memset(order, 0, sizeof(*order));
+ Item *item= new (thd->mem_root) Item_field(thd, join_tab->table->field[0]);
+ order->item= (Item **)alloc_root(thd->mem_root, 2 * sizeof(Item *));
+ order->item[1]= NULL;
+ order->item[0]= item;
+ order->field= join_tab->table->field[0];
+ sort_order= order;
+ }
filesort= new (thd->mem_root) Filesort(sort_order, HA_POS_ERROR, true, NULL);
/* Apply the same condition that the subsequent sort has. */
@@ -2574,7 +2596,7 @@ bool Window_funcs_computation::setup(THD *thd,
while (iter.peek())
{
if (!(srt= new Window_funcs_sort()) ||
- srt->setup(thd, sel, iter))
+ srt->setup(thd, sel, iter, tab))
{
return true;
}
diff --git a/sql/sql_window.h b/sql/sql_window.h
index c3847240e9a..b94a1fc6dc4 100644
--- a/sql/sql_window.h
+++ b/sql/sql_window.h
@@ -186,7 +186,8 @@ private:
class Window_funcs_sort : public Sql_alloc
{
public:
- bool setup(THD *thd, SQL_SELECT *sel, List_iterator<Item_window_func> &it);
+ bool setup(THD *thd, SQL_SELECT *sel, List_iterator<Item_window_func> &it,
+ st_join_table *join_tab);
bool exec(JOIN *join);
void cleanup() { delete filesort; }