diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 04bd686c9fc..9212bf6665c 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -491,13 +491,13 @@ public: : Item_func_or_sum(thd, (Item *) win_func), window_name(win_name), window_spec(NULL), force_return_blank(true), - read_value_from_result_field(false) {} + read_value_from_result_field(false) {} Item_window_func(THD *thd, Item_sum *win_func, Window_spec *win_spec) : Item_func_or_sum(thd, (Item *) win_func), window_name(NULL), window_spec(win_spec), force_return_blank(true), - read_value_from_result_field(false) {} + read_value_from_result_field(false) {} Item_sum *window_func() { return (Item_sum *) args[0]; } @@ -544,7 +544,8 @@ public: return ((Item_sum *) args[0])->field_type(); } enum Item::Type type() const { return Item::WINDOW_FUNC_ITEM; } - + +private: /* Window functions are very special functions, so val_() methods have special meaning for them: @@ -584,11 +585,6 @@ public: read_value_from_result_field= true; } - void set_read_value_from_result_field() - { - read_value_from_result_field= true; - } - double val_real() { double res; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ff6c4c2578d..42a9858d549 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -25898,7 +25898,7 @@ AGGR_OP::end_send() // Update ref array join_tab->join->set_items_ref_array(*join_tab->ref_array); - join->process_window_functions(&join->fields_list); // location #2 + join->process_window_functions(&join->select_lex->window_funcs); table->reginfo.lock_type= TL_UNLOCK; bool in_first_read= true; diff --git a/sql/sql_select.h b/sql/sql_select.h index de06ae48645..502e28d2dbd 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1494,7 +1494,7 @@ public: int init_execution(); void exec(); - bool process_window_functions(List *curr_fields_list); + bool process_window_functions(List *window_funcs); void exec_inner(); bool prepare_result(List **columns_list); diff --git a/sql/sql_window.cc b/sql/sql_window.cc index 83e64cc692b..63872334c47 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -1579,102 +1579,97 @@ bool compute_two_pass_window_functions(Item_window_func *item_win, true Error */ -bool JOIN::process_window_functions(List *curr_fields_list) +bool JOIN::process_window_functions(List *window_funcs) { - List_iterator_fast it(*curr_fields_list); - Item *item; + List_iterator_fast it(*window_funcs); + Item_window_func *item_win; + while ((item_win= it++)) { - while ((item= it++)) - { - if (item->type() == Item::WINDOW_FUNC_ITEM) - { - Item_window_func *item_win = (Item_window_func *) item; - item_win->set_phase_to_computation(); - Window_spec *spec = item_win->window_spec; - /* - The sorting criteria should be - (spec->partition_list, spec->order_list) + item_win->set_phase_to_computation(); + Window_spec *spec = item_win->window_spec; + /* + The sorting criteria should be + (spec->partition_list, spec->order_list) - Connect the two lists for the duration of add_sorting_to_table() - call. - */ - DBUG_ASSERT(spec->partition_list->next[0] == NULL); - *(spec->partition_list->next)= spec->order_list->first; + Connect the two lists for the duration of add_sorting_to_table() + call. + */ + DBUG_ASSERT(spec->partition_list->next[0] == NULL); + *(spec->partition_list->next)= spec->order_list->first; - /* - join_tab[top_join_tab_count].table is the temp. table where join - output was stored. - */ - add_sorting_to_table(&join_tab[top_join_tab_count], - spec->partition_list->first); - join_tab[top_join_tab_count].used_for_window_func= true; + /* + join_tab[top_join_tab_count].table is the temp. table where join + output was stored. + */ + // CAUTION: The sorting criteria list is not yet connected + add_sorting_to_table(&join_tab[top_join_tab_count], + spec->partition_list->first); + join_tab[top_join_tab_count].used_for_window_func= true; - create_sort_index(this->thd, this, &join_tab[top_join_tab_count]); - /* Disconnect order_list from partition_list */ - *(spec->partition_list->next)= NULL; - - /* - Go through the sorted array and compute the window function - */ - READ_RECORD info; - TABLE *tbl= join_tab[top_join_tab_count].table; - if (init_read_record(&info, thd, tbl, select, 0, 1, FALSE)) - return true; - bool is_error= false; - - item_win->setup_partition_border_check(thd); - - Item_sum::Sumfunctype type= item_win->window_func()->sum_func(); - switch (type) { - case Item_sum::ROW_NUMBER_FUNC: - case Item_sum::RANK_FUNC: - case Item_sum::DENSE_RANK_FUNC: - { - /* - One-pass window function computation, walk through the rows and - assign values. - */ - if (compute_window_func_values(item_win, tbl, &info)) - is_error= true; - break; - } - case Item_sum::PERCENT_RANK_FUNC: - case Item_sum::CUME_DIST_FUNC: - { - if (compute_two_pass_window_functions(item_win, tbl, &info)) - is_error= true; - break; - } - case Item_sum::COUNT_FUNC: - case Item_sum::SUM_BIT_FUNC: - case Item_sum::SUM_FUNC: - case Item_sum::AVG_FUNC: - { - /* - Frame-aware window function computation. It does one pass, but - uses three cursors -frame_start, current_row, and frame_end. - */ - if (compute_window_func_with_frames(item_win, tbl, &info)) - is_error= true; - break; - } - default: - DBUG_ASSERT(0); + create_sort_index(this->thd, this, &join_tab[top_join_tab_count]); + /* Disconnect order_list from partition_list */ + *(spec->partition_list->next)= NULL; + + /* + Go through the sorted array and compute the window function + */ + READ_RECORD info; + TABLE *tbl= join_tab[top_join_tab_count].table; + if (init_read_record(&info, thd, tbl, select, 0, 1, FALSE)) + return true; + bool is_error= false; + + item_win->setup_partition_border_check(thd); + + Item_sum::Sumfunctype type= item_win->window_func()->sum_func(); + switch (type) { + case Item_sum::ROW_NUMBER_FUNC: + case Item_sum::RANK_FUNC: + case Item_sum::DENSE_RANK_FUNC: + { + /* + One-pass window function computation, walk through the rows and + assign values. + */ + if (compute_window_func_values(item_win, tbl, &info)) + is_error= true; + break; } - - item_win->set_phase_to_retrieval(); - /* This calls filesort_free_buffers(): */ - end_read_record(&info); - - delete join_tab[top_join_tab_count].filesort; - join_tab[top_join_tab_count].filesort= NULL; - free_io_cache(tbl); - - if (is_error) - return true; + case Item_sum::PERCENT_RANK_FUNC: + case Item_sum::CUME_DIST_FUNC: + { + if (compute_two_pass_window_functions(item_win, tbl, &info)) + is_error= true; + break; + } + case Item_sum::COUNT_FUNC: + case Item_sum::SUM_BIT_FUNC: + case Item_sum::SUM_FUNC: + case Item_sum::AVG_FUNC: + { + /* + Frame-aware window function computation. It does one pass, but + uses three cursors -frame_start, current_row, and frame_end. + */ + if (compute_window_func_with_frames(item_win, tbl, &info)) + is_error= true; + break; } + default: + DBUG_ASSERT(0); } + + item_win->set_phase_to_retrieval(); + /* This calls filesort_free_buffers(): */ + end_read_record(&info); + + delete join_tab[top_join_tab_count].filesort; + join_tab[top_join_tab_count].filesort= NULL; + free_io_cache(tbl); + + if (is_error) + return true; } return false; }