diff options
-rw-r--r-- | sql/item.h | 5 | ||||
-rw-r--r-- | sql/item_windowfunc.cc | 14 | ||||
-rw-r--r-- | sql/item_windowfunc.h | 82 | ||||
-rw-r--r-- | sql/sql_window.cc | 90 |
4 files changed, 83 insertions, 108 deletions
diff --git a/sql/item.h b/sql/item.h index 0e7582a9ac4..067deba8b58 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5322,10 +5322,7 @@ public: cmp(); item= save; } - Item* get_item() - { - return item; - } + void clear() { null_value= false; diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index 5e77132ad38..8a35cd34e82 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -111,7 +111,7 @@ Item_window_func::fix_fields(THD *thd, Item **ref) if (only_single_element_order_list()) { - // need to change the error, the error should say that we have more than one element in the order list + //TODO (varun): need to change the error, the error should say that we have more than one element in the order list if (window_spec->order_list->elements != 1) { my_error(ER_NO_ORDER_LIST_IN_WINDOW_SPEC, MYF(0), window_func()->func_name()); @@ -207,12 +207,12 @@ void Item_sum_dense_rank::setup_window_func(THD *thd, Window_spec *window_spec) void Item_sum_percentile_disc::setup_window_func(THD *thd, Window_spec *window_spec) { - setup_percentile_func(thd, window_spec->order_list); -} - -void Item_sum_percentile_disc::set_type_handler(Window_spec *window_spec) -{ - type_handler()->get_handler_by_cmp_type(window_spec->order_list->first->item[0]->result_type()); + order_item= window_spec->order_list->first->item[0]; + set_handler_by_cmp_type(order_item->result_type()); + if (!(value= order_item->get_cache(thd))) + return; + value->setup(thd, order_item); + value->store(order_item); } bool Item_sum_dense_rank::add() diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 3178bdeb54b..7c6c3c87025 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -42,6 +42,12 @@ public: } } + Group_bound_tracker(THD *thd, Item *item) + { + Cached_item *tmp= new_Cached_item(thd, item, FALSE); + group_fields.push_back(tmp); + } + void init() { first_check= true; @@ -117,7 +123,6 @@ private: bool first_check; }; - /* ROW_NUMBER() OVER (...) @@ -725,7 +730,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, public: Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg), Type_handler_hybrid_field_type(&type_handler_longlong), - value(NULL), result_value(NULL), val_calculated(FALSE) {} + value(NULL), val_calculated(FALSE), first_call(TRUE),prev_value(0), order_item(NULL){} double val_real() { @@ -735,7 +740,7 @@ public: return 0; } null_value= false; - return ((Cached_item_real*) result_value)->get_value(); + return value->val_real(); } longlong val_int() @@ -746,7 +751,7 @@ public: return 0; } null_value= false; - return ((Cached_item_int*) result_value)->get_value(); + return value->val_int(); } my_decimal* val_decimal(my_decimal* dec) @@ -757,7 +762,7 @@ public: return 0; } null_value= false; - return ((Cached_item_decimal*) result_value)->get_value(); + return value->val_decimal(dec); } bool add() @@ -765,31 +770,32 @@ public: Item *arg = get_arg(0); if (arg->is_null()) return true; - /* - need to ensure that the Item arg is constant across the entire partition - and its value ranges between [0,1] - */ - value->cmp(); - /* for the null values of the row, we dont count take those rows in account for calculating - the CUME_DIST */ + if (first_call) + { + prev_value= arg->val_real(); + first_call= false; + } - if(value->null_value) + if(prev_value != arg->val_real() || prev_value >1 || prev_value < 0) + { + // TODO(varun) need to add an error here , check the MDEV-12985 for the information + return true; + } + + if (val_calculated) return false; - Item_sum_cume_dist::add(); - double val1= Item_sum_cume_dist::val_real(); - /* need to check type and return value accordingly*/ - double val2 =arg->val_real_from_decimal(); + value->store(order_item); + value->cache_value(); + if (value->null_value) + return false; - /* use Cached_item to do the comparision using cmp_read_only() */ + Item_sum_cume_dist::add(); + double val= Item_sum_cume_dist::val_real(); - if( val1 >= val2 && !val_calculated) - { + if(val >= prev_value && !val_calculated) val_calculated= true; - result_value->cmp(); - return false; - } return false; } @@ -801,8 +807,8 @@ public: void clear() { val_calculated= false; + first_call= true; value->clear(); - result_value->clear(); Item_sum_cume_dist::clear(); } @@ -825,33 +831,19 @@ public: Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_sum_percentile_disc>(thd, mem_root, this); } void setup_window_func(THD *thd, Window_spec *window_spec); - void setup_percentile_func(THD *thd, SQL_I_List<ORDER> *list) - { - value= new_Cached_item(thd, list->first->item[0], FALSE); - result_value= new_Cached_item(thd, list->first->item[0], FALSE); - } - void cleanup() - { - if (value) - { - delete value; - value= NULL; - } - if(result_value) - { - delete result_value; - result_value= NULL; - } - Item_sum_num::cleanup(); - } + void setup_hybrid(THD *thd, Item *item); private: - Cached_item *value; - Cached_item *result_value; + Item_cache *value; bool val_calculated; + bool first_call; + double prev_value; + Item *order_item; }; + + class Item_window_func : public Item_func_or_sum { /* Window function parameters as we've got them from the parser */ diff --git a/sql/sql_window.cc b/sql/sql_window.cc index e8925d5f45d..bb7742b029a 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -319,10 +319,6 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, while ((win_func_item= li++)) { win_func_item->update_used_tables(); - if (win_func_item->only_single_element_order_list()) - { - ((Item_sum_percentile_disc*)win_func_item)->set_type_handler(win_func_item->window_spec); - } } DBUG_RETURN(0); @@ -908,14 +904,13 @@ private: class Partition_read_cursor : public Table_read_cursor { public: - Partition_read_cursor(THD *thd, SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list) : - bound_tracker(thd, partition_list), order_tracker(thd, order_list) {} + Partition_read_cursor(THD *thd, SQL_I_List<ORDER> *partition_list) : + bound_tracker(thd, partition_list){} void init(READ_RECORD *info) { Table_read_cursor::init(info); bound_tracker.init(); - order_tracker.init(); end_of_partition= false; } @@ -967,42 +962,18 @@ public: } return 0; } - bool next_func(ha_rows *counter) - { - if (next()) - return true; - if (!check_for_null_row()) - { - (*counter)++; - } - return false; - } - bool fetch_func(ha_rows *counter) - { - if (fetch()) - return true; - if (!check_for_null_row()) - { - (*counter)++; - } - return false; - } - bool check_for_null_row() + bool check_for_end_of_partition() { - if (!end_of_partition) - { - if (order_tracker.compare_with_cache_for_null_values()) - return true; - } - return false; + return end_of_partition; } private: Group_bound_tracker bound_tracker; - Group_bound_tracker order_tracker; bool end_of_partition; }; + + ///////////////////////////////////////////////////////////////////////////// /* @@ -1178,7 +1149,7 @@ public: Frame_cursor *cursor; while ((cursor= iter++)) cursor->pre_next_row(); - + iter.rewind(); while ((cursor= iter++)) cursor->next_row(); @@ -1231,7 +1202,7 @@ public: SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list, bool is_preceding_arg, Item *n_val_arg) : - cursor(thd, partition_list, NULL), n_val(n_val_arg), item_add(NULL), + cursor(thd, partition_list), n_val(n_val_arg), item_add(NULL), is_preceding(is_preceding_arg) { DBUG_ASSERT(order_list->elements == 1); @@ -1370,7 +1341,7 @@ public: SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list, bool is_preceding_arg, Item *n_val_arg) : - cursor(thd, partition_list, NULL), n_val(n_val_arg), item_add(NULL), + cursor(thd, partition_list), n_val(n_val_arg), item_add(NULL), is_preceding(is_preceding_arg), added_values(false) { DBUG_ASSERT(order_list->elements == 1); @@ -1500,7 +1471,7 @@ public: Frame_range_current_row_bottom(THD *thd, SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list) : - cursor(thd, partition_list, NULL), peer_tracker(thd, order_list) + cursor(thd, partition_list), peer_tracker(thd, order_list) { } @@ -1715,7 +1686,7 @@ public: Frame_unbounded_following(THD *thd, SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list) : - cursor(thd, partition_list, order_list){} + cursor(thd, partition_list){} void init(READ_RECORD *info) { @@ -1758,7 +1729,7 @@ public: Frame_unbounded_following_set_count( THD *thd, SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list) : - Frame_unbounded_following(thd, partition_list, order_list) {} + Frame_unbounded_following(thd, partition_list, order_list){} void next_partition(ha_rows rownum) { @@ -1769,7 +1740,9 @@ public: /* Walk to the end of the partition, find how many rows there are. */ while (!cursor.next()) + { num_rows_in_partition++; + } List_iterator_fast<Item_sum> it(sum_functions); Item_sum* item; @@ -1787,23 +1760,29 @@ public: } }; -class Frame_unbounded_following_set_count_special : public Frame_unbounded_following_set_count +class Frame_unbounded_following_set_count_special: public Frame_unbounded_following_set_count { -public: - Frame_unbounded_following_set_count_special( - THD *thd, - SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list) : - Frame_unbounded_following_set_count(thd, partition_list, order_list) - {} +public: + Frame_unbounded_following_set_count_special(THD *thd, + SQL_I_List<ORDER> *partition_list, + SQL_I_List<ORDER> *order_list, Item* arg) : + Frame_unbounded_following_set_count(thd,partition_list, order_list) + { + order_item= order_list->first->item[0]; + } void next_partition(ha_rows rownum) { ha_rows num_rows_in_partition= 0; - if (cursor.fetch_func(&num_rows_in_partition)) + if (cursor.fetch()) return; /* Walk to the end of the partition, find how many rows there are. */ - while (!cursor.next_func(&num_rows_in_partition)); + do + { + if (!order_item->is_null()) + num_rows_in_partition++; + }while (!cursor.next()); List_iterator_fast<Item_sum> it(sum_functions); Item_sum* item; @@ -1814,6 +1793,13 @@ public: item_with_row_count->set_row_count(num_rows_in_partition); } } + + ha_rows get_curr_rownum() const + { + return cursor.get_rownum(); + } +private: + Item* order_item; }; ///////////////////////////////////////////////////////////////////////////// @@ -2013,7 +1999,7 @@ public: SQL_I_List<ORDER> *order_list, bool is_top_bound_arg, ha_rows n_rows_arg) : is_top_bound(is_top_bound_arg), n_rows(n_rows_arg), - cursor(thd, partition_list, NULL) + cursor(thd, partition_list) { } @@ -2628,7 +2614,7 @@ void get_window_functions_required_cursors( { fc= new Frame_unbounded_following_set_count_special(thd, item_win_func->window_spec->partition_list, - item_win_func->window_spec->order_list); + item_win_func->window_spec->order_list, item_win_func->window_func()->get_arg(0)); } else { |