Commit 01d2b6e9 authored by Varun Gupta's avatar Varun Gupta

Implemented the implementation of percentile functions using Item_cache instead of Cache_Item

parent d2214da4
...@@ -5322,10 +5322,7 @@ class Cached_item_item : public Cached_item ...@@ -5322,10 +5322,7 @@ class Cached_item_item : public Cached_item
cmp(); cmp();
item= save; item= save;
} }
Item* get_item()
{
return item;
}
void clear() void clear()
{ {
null_value= false; null_value= false;
......
...@@ -111,7 +111,7 @@ Item_window_func::fix_fields(THD *thd, Item **ref) ...@@ -111,7 +111,7 @@ Item_window_func::fix_fields(THD *thd, Item **ref)
if (only_single_element_order_list()) 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) if (window_spec->order_list->elements != 1)
{ {
my_error(ER_NO_ORDER_LIST_IN_WINDOW_SPEC, MYF(0), window_func()->func_name()); 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) ...@@ -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) void Item_sum_percentile_disc::setup_window_func(THD *thd, Window_spec *window_spec)
{ {
setup_percentile_func(thd, window_spec->order_list); 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)))
void Item_sum_percentile_disc::set_type_handler(Window_spec *window_spec) return;
{ value->setup(thd, order_item);
type_handler()->get_handler_by_cmp_type(window_spec->order_list->first->item[0]->result_type()); value->store(order_item);
} }
bool Item_sum_dense_rank::add() bool Item_sum_dense_rank::add()
......
...@@ -42,6 +42,12 @@ class Group_bound_tracker ...@@ -42,6 +42,12 @@ class Group_bound_tracker
} }
} }
Group_bound_tracker(THD *thd, Item *item)
{
Cached_item *tmp= new_Cached_item(thd, item, FALSE);
group_fields.push_back(tmp);
}
void init() void init()
{ {
first_check= true; first_check= true;
...@@ -117,7 +123,6 @@ class Group_bound_tracker ...@@ -117,7 +123,6 @@ class Group_bound_tracker
bool first_check; bool first_check;
}; };
/* /*
ROW_NUMBER() OVER (...) ROW_NUMBER() OVER (...)
...@@ -725,7 +730,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, ...@@ -725,7 +730,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist,
public: public:
Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg), Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg),
Type_handler_hybrid_field_type(&type_handler_longlong), 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() double val_real()
{ {
...@@ -735,7 +740,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, ...@@ -735,7 +740,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist,
return 0; return 0;
} }
null_value= false; null_value= false;
return ((Cached_item_real*) result_value)->get_value(); return value->val_real();
} }
longlong val_int() longlong val_int()
...@@ -746,7 +751,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, ...@@ -746,7 +751,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist,
return 0; return 0;
} }
null_value= false; null_value= false;
return ((Cached_item_int*) result_value)->get_value(); return value->val_int();
} }
my_decimal* val_decimal(my_decimal* dec) my_decimal* val_decimal(my_decimal* dec)
...@@ -757,7 +762,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, ...@@ -757,7 +762,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist,
return 0; return 0;
} }
null_value= false; null_value= false;
return ((Cached_item_decimal*) result_value)->get_value(); return value->val_decimal(dec);
} }
bool add() bool add()
...@@ -765,31 +770,32 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, ...@@ -765,31 +770,32 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist,
Item *arg = get_arg(0); Item *arg = get_arg(0);
if (arg->is_null()) if (arg->is_null())
return true; 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 if (first_call)
the CUME_DIST */ {
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; return false;
Item_sum_cume_dist::add(); value->store(order_item);
double val1= Item_sum_cume_dist::val_real(); value->cache_value();
/* need to check type and return value accordingly*/ if (value->null_value)
double val2 =arg->val_real_from_decimal(); 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; val_calculated= true;
result_value->cmp();
return false;
}
return false; return false;
} }
...@@ -801,8 +807,8 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, ...@@ -801,8 +807,8 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist,
void clear() void clear()
{ {
val_calculated= false; val_calculated= false;
first_call= true;
value->clear(); value->clear();
result_value->clear();
Item_sum_cume_dist::clear(); Item_sum_cume_dist::clear();
} }
...@@ -825,33 +831,19 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, ...@@ -825,33 +831,19 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist,
Item *get_copy(THD *thd, MEM_ROOT *mem_root) Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_percentile_disc>(thd, mem_root, this); } { return get_item_copy<Item_sum_percentile_disc>(thd, mem_root, this); }
void setup_window_func(THD *thd, Window_spec *window_spec); void setup_window_func(THD *thd, Window_spec *window_spec);
void setup_percentile_func(THD *thd, SQL_I_List<ORDER> *list) void setup_hybrid(THD *thd, Item *item);
{
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();
}
private: private:
Cached_item *value; Item_cache *value;
Cached_item *result_value;
bool val_calculated; bool val_calculated;
bool first_call;
double prev_value;
Item *order_item;
}; };
class Item_window_func : public Item_func_or_sum class Item_window_func : public Item_func_or_sum
{ {
/* Window function parameters as we've got them from the parser */ /* Window function parameters as we've got them from the parser */
......
...@@ -319,10 +319,6 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, ...@@ -319,10 +319,6 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
while ((win_func_item= li++)) while ((win_func_item= li++))
{ {
win_func_item->update_used_tables(); 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); DBUG_RETURN(0);
...@@ -908,14 +904,13 @@ class Table_read_cursor : public Rowid_seq_cursor ...@@ -908,14 +904,13 @@ class Table_read_cursor : public Rowid_seq_cursor
class Partition_read_cursor : public Table_read_cursor class Partition_read_cursor : public Table_read_cursor
{ {
public: public:
Partition_read_cursor(THD *thd, SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list) : Partition_read_cursor(THD *thd, SQL_I_List<ORDER> *partition_list) :
bound_tracker(thd, partition_list), order_tracker(thd, order_list) {} bound_tracker(thd, partition_list){}
void init(READ_RECORD *info) void init(READ_RECORD *info)
{ {
Table_read_cursor::init(info); Table_read_cursor::init(info);
bound_tracker.init(); bound_tracker.init();
order_tracker.init();
end_of_partition= false; end_of_partition= false;
} }
...@@ -967,42 +962,18 @@ class Partition_read_cursor : public Table_read_cursor ...@@ -967,42 +962,18 @@ class Partition_read_cursor : public Table_read_cursor
} }
return 0; return 0;
} }
bool next_func(ha_rows *counter) bool check_for_end_of_partition()
{
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()
{ {
if (!end_of_partition) return end_of_partition;
{
if (order_tracker.compare_with_cache_for_null_values())
return true;
}
return false;
} }
private: private:
Group_bound_tracker bound_tracker; Group_bound_tracker bound_tracker;
Group_bound_tracker order_tracker;
bool end_of_partition; bool end_of_partition;
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/* /*
...@@ -1178,7 +1149,7 @@ class Cursor_manager ...@@ -1178,7 +1149,7 @@ class Cursor_manager
Frame_cursor *cursor; Frame_cursor *cursor;
while ((cursor= iter++)) while ((cursor= iter++))
cursor->pre_next_row(); cursor->pre_next_row();
iter.rewind(); iter.rewind();
while ((cursor= iter++)) while ((cursor= iter++))
cursor->next_row(); cursor->next_row();
...@@ -1231,7 +1202,7 @@ class Frame_range_n_top : public Frame_cursor ...@@ -1231,7 +1202,7 @@ class Frame_range_n_top : public Frame_cursor
SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *partition_list,
SQL_I_List<ORDER> *order_list, SQL_I_List<ORDER> *order_list,
bool is_preceding_arg, Item *n_val_arg) : 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) is_preceding(is_preceding_arg)
{ {
DBUG_ASSERT(order_list->elements == 1); DBUG_ASSERT(order_list->elements == 1);
...@@ -1370,7 +1341,7 @@ class Frame_range_n_bottom: public Frame_cursor ...@@ -1370,7 +1341,7 @@ class Frame_range_n_bottom: public Frame_cursor
SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *partition_list,
SQL_I_List<ORDER> *order_list, SQL_I_List<ORDER> *order_list,
bool is_preceding_arg, Item *n_val_arg) : 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) is_preceding(is_preceding_arg), added_values(false)
{ {
DBUG_ASSERT(order_list->elements == 1); DBUG_ASSERT(order_list->elements == 1);
...@@ -1500,7 +1471,7 @@ class Frame_range_current_row_bottom: public Frame_cursor ...@@ -1500,7 +1471,7 @@ class Frame_range_current_row_bottom: public Frame_cursor
Frame_range_current_row_bottom(THD *thd, Frame_range_current_row_bottom(THD *thd,
SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *partition_list,
SQL_I_List<ORDER> *order_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 @@ class Frame_unbounded_following : public Frame_cursor ...@@ -1715,7 +1686,7 @@ class Frame_unbounded_following : public Frame_cursor
Frame_unbounded_following(THD *thd, Frame_unbounded_following(THD *thd,
SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *partition_list,
SQL_I_List<ORDER> *order_list) : SQL_I_List<ORDER> *order_list) :
cursor(thd, partition_list, order_list){} cursor(thd, partition_list){}
void init(READ_RECORD *info) void init(READ_RECORD *info)
{ {
...@@ -1758,7 +1729,7 @@ class Frame_unbounded_following_set_count : public Frame_unbounded_following ...@@ -1758,7 +1729,7 @@ class Frame_unbounded_following_set_count : public Frame_unbounded_following
Frame_unbounded_following_set_count( Frame_unbounded_following_set_count(
THD *thd, THD *thd,
SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *order_list) : 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) void next_partition(ha_rows rownum)
{ {
...@@ -1769,7 +1740,9 @@ class Frame_unbounded_following_set_count : public Frame_unbounded_following ...@@ -1769,7 +1740,9 @@ class Frame_unbounded_following_set_count : public Frame_unbounded_following
/* Walk to the end of the partition, find how many rows there are. */ /* Walk to the end of the partition, find how many rows there are. */
while (!cursor.next()) while (!cursor.next())
{
num_rows_in_partition++; num_rows_in_partition++;
}
List_iterator_fast<Item_sum> it(sum_functions); List_iterator_fast<Item_sum> it(sum_functions);
Item_sum* item; Item_sum* item;
...@@ -1787,23 +1760,29 @@ class Frame_unbounded_following_set_count : public Frame_unbounded_following ...@@ -1787,23 +1760,29 @@ class Frame_unbounded_following_set_count : public Frame_unbounded_following
} }
}; };
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) void next_partition(ha_rows rownum)
{ {
ha_rows num_rows_in_partition= 0; ha_rows num_rows_in_partition= 0;
if (cursor.fetch_func(&num_rows_in_partition)) if (cursor.fetch())
return; return;
/* Walk to the end of the partition, find how many rows there are. */ /* 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); List_iterator_fast<Item_sum> it(sum_functions);
Item_sum* item; Item_sum* item;
...@@ -1814,6 +1793,13 @@ class Frame_unbounded_following_set_count_special : public Frame_unbounded_follo ...@@ -1814,6 +1793,13 @@ class Frame_unbounded_following_set_count_special : public Frame_unbounded_follo
item_with_row_count->set_row_count(num_rows_in_partition); 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 @@ class Frame_n_rows_following : public Frame_cursor ...@@ -2013,7 +1999,7 @@ class Frame_n_rows_following : public Frame_cursor
SQL_I_List<ORDER> *order_list, SQL_I_List<ORDER> *order_list,
bool is_top_bound_arg, ha_rows n_rows_arg) : bool is_top_bound_arg, ha_rows n_rows_arg) :
is_top_bound(is_top_bound_arg), n_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( ...@@ -2628,7 +2614,7 @@ void get_window_functions_required_cursors(
{ {
fc= new Frame_unbounded_following_set_count_special(thd, fc= new Frame_unbounded_following_set_count_special(thd,
item_win_func->window_spec->partition_list, 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 else
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment