Commit 280945bf authored by Varun Gupta's avatar Varun Gupta

MDEV-12985: support percentile and median window functions

Finalised the synatax and have started implementing the class for the PERCENTILE_DISC
parent fadfe447
...@@ -354,7 +354,8 @@ class Item_sum :public Item_func_or_sum ...@@ -354,7 +354,8 @@ class Item_sum :public Item_func_or_sum
VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC, VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC,
ROW_NUMBER_FUNC, RANK_FUNC, DENSE_RANK_FUNC, PERCENT_RANK_FUNC, ROW_NUMBER_FUNC, RANK_FUNC, DENSE_RANK_FUNC, PERCENT_RANK_FUNC,
CUME_DIST_FUNC, NTILE_FUNC, FIRST_VALUE_FUNC, LAST_VALUE_FUNC, CUME_DIST_FUNC, NTILE_FUNC, FIRST_VALUE_FUNC, LAST_VALUE_FUNC,
NTH_VALUE_FUNC, LEAD_FUNC, LAG_FUNC NTH_VALUE_FUNC, LEAD_FUNC, LAG_FUNC, PERCENTILE_CONT_FUNC,
PERCENTILE_DISC_FUNC
}; };
Item **ref_by; /* pointer to a ref to the object used to register it */ Item **ref_by; /* pointer to a ref to the object used to register it */
......
...@@ -572,6 +572,9 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count ...@@ -572,6 +572,9 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
Item_sum_cume_dist(THD *thd) : Item_sum_window_with_row_count(thd), Item_sum_cume_dist(THD *thd) : Item_sum_window_with_row_count(thd),
current_row_count_(0) {} current_row_count_(0) {}
Item_sum_cume_dist(THD *thd, Item *arg) : Item_sum_window_with_row_count(thd,arg),
current_row_count_(0) {}
double val_real() double val_real()
{ {
if (get_row_count() == 0) if (get_row_count() == 0)
...@@ -618,6 +621,11 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count ...@@ -618,6 +621,11 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
Item *get_copy(THD *thd, MEM_ROOT *mem_root) Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_cume_dist>(thd, mem_root, this); } { return get_item_copy<Item_sum_cume_dist>(thd, mem_root, this); }
ulonglong get_row_number()
{
return current_row_count_;
}
private: private:
ulonglong current_row_count_; ulonglong current_row_count_;
}; };
...@@ -693,6 +701,61 @@ class Item_sum_ntile : public Item_sum_window_with_row_count ...@@ -693,6 +701,61 @@ class Item_sum_ntile : public Item_sum_window_with_row_count
ulong current_row_count_; ulong current_row_count_;
}; };
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)
{}
double val_real()
{
if (get_row_count() == 0 || get_arg(0)->is_null())
{
null_value= true;
return 0;
}
null_value= false;
return 0;
}
bool add()
{
Item *arg = get_arg(0);
if (arg->is_null())
return true;
/*implementation to be done*/
return false;
}
enum Sumfunctype sum_func() const
{
return PERCENTILE_DISC_FUNC;
}
void clear()
{
//need to implement
}
const char*func_name() const
{
return "percentile_disc";
}
void update_field() {}
const Type_handler *type_handler() const { return &type_handler_double; }
void fix_length_and_dec()
{
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
// requires.
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_percentile_disc>(thd, mem_root, this); }
};
class Item_window_func : public Item_func_or_sum class Item_window_func : public Item_func_or_sum
{ {
...@@ -747,6 +810,8 @@ class Item_window_func : public Item_func_or_sum ...@@ -747,6 +810,8 @@ class Item_window_func : public Item_func_or_sum
case Item_sum::PERCENT_RANK_FUNC: case Item_sum::PERCENT_RANK_FUNC:
case Item_sum::CUME_DIST_FUNC: case Item_sum::CUME_DIST_FUNC:
case Item_sum::NTILE_FUNC: case Item_sum::NTILE_FUNC:
case Item_sum::PERCENTILE_CONT_FUNC:
case Item_sum::PERCENTILE_DISC_FUNC:
return true; return true;
default: default:
return false; return false;
...@@ -773,6 +838,8 @@ class Item_window_func : public Item_func_or_sum ...@@ -773,6 +838,8 @@ class Item_window_func : public Item_func_or_sum
case Item_sum::PERCENT_RANK_FUNC: case Item_sum::PERCENT_RANK_FUNC:
case Item_sum::CUME_DIST_FUNC: case Item_sum::CUME_DIST_FUNC:
case Item_sum::NTILE_FUNC: case Item_sum::NTILE_FUNC:
case Item_sum::PERCENTILE_CONT_FUNC:
case Item_sum::PERCENTILE_DISC_FUNC:
return true; return true;
default: default:
return false; return false;
...@@ -796,6 +863,8 @@ class Item_window_func : public Item_func_or_sum ...@@ -796,6 +863,8 @@ class Item_window_func : public Item_func_or_sum
case Item_sum::DENSE_RANK_FUNC: case Item_sum::DENSE_RANK_FUNC:
case Item_sum::PERCENT_RANK_FUNC: case Item_sum::PERCENT_RANK_FUNC:
case Item_sum::CUME_DIST_FUNC: case Item_sum::CUME_DIST_FUNC:
case Item_sum::PERCENTILE_CONT_FUNC:
case Item_sum::PERCENTILE_DISC_FUNC:
return true; return true;
default: default:
return false; return false;
......
...@@ -2490,6 +2490,20 @@ void add_special_frame_cursors(THD *thd, Cursor_manager *cursor_manager, ...@@ -2490,6 +2490,20 @@ void add_special_frame_cursors(THD *thd, Cursor_manager *cursor_manager,
cursor_manager->add_cursor(fc); cursor_manager->add_cursor(fc);
break; break;
} }
case Item_sum::PERCENTILE_DISC_FUNC:
{
fc= new Frame_unbounded_preceding(thd,
spec->partition_list,
spec->order_list);
fc->add_sum_func(item_sum);
cursor_manager->add_cursor(fc);
fc= new Frame_unbounded_following(thd,
spec->partition_list,
spec->order_list);
fc->add_sum_func(item_sum);
cursor_manager->add_cursor(fc);
break;
}
default: default:
fc= new Frame_unbounded_preceding( fc= new Frame_unbounded_preceding(
thd, spec->partition_list, spec->order_list); thd, spec->partition_list, spec->order_list);
...@@ -2514,6 +2528,8 @@ static bool is_computed_with_remove(Item_sum::Sumfunctype sum_func) ...@@ -2514,6 +2528,8 @@ static bool is_computed_with_remove(Item_sum::Sumfunctype sum_func)
case Item_sum::NTILE_FUNC: case Item_sum::NTILE_FUNC:
case Item_sum::FIRST_VALUE_FUNC: case Item_sum::FIRST_VALUE_FUNC:
case Item_sum::LAST_VALUE_FUNC: case Item_sum::LAST_VALUE_FUNC:
case Item_sum::PERCENTILE_CONT_FUNC:
case Item_sum::PERCENTILE_DISC_FUNC:
return false; return false;
default: default:
return true; return true;
......
...@@ -1737,6 +1737,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -1737,6 +1737,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
window_func window_func
simple_window_func simple_window_func
inverse_distribution_function inverse_distribution_function
inverse_distribution_function_def
function_call_keyword function_call_keyword
function_call_nonkeyword function_call_nonkeyword
function_call_generic function_call_generic
...@@ -10697,23 +10698,43 @@ simple_window_func: ...@@ -10697,23 +10698,43 @@ simple_window_func:
} }
; ;
inverse_distribution_function: inverse_distribution_function:
inverse_distribution_function_type '(' expr ')' WITHIN GROUP_SYM inverse_distribution_function_def WITHIN GROUP_SYM
'(' order_by_single_element_list ')' OVER_SYM '(' opt_window_ref opt_window_partition_clause ')' '('
{ { Select->prepare_add_window_spec(thd); }
my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0))); order_by_single_element_list ')' OVER_SYM
}; '(' opt_window_ref opt_window_partition_clause ')'
{
inverse_distribution_function_type: LEX *lex= Lex;
PERCENTILE_CONT_SYM if (Select->add_window_spec(thd, lex->win_ref,
{} Select->group_list,
|PERCENTILE_DISC_SYM Select->order_list,
{} NULL))
; MYSQL_YYABORT;
$$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1,
thd->lex->win_spec);
if ($$ == NULL)
MYSQL_YYABORT;
if (Select->add_window_func((Item_window_func *) $$))
MYSQL_YYABORT;
}
;
inverse_distribution_function_def:
PERCENTILE_CONT_SYM '(' expr ')'
{
//Not yet started implementing
}
| PERCENTILE_DISC_SYM '(' expr ')'
{
$$= new (thd->mem_root) Item_sum_percentile_disc(thd, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
;
order_by_single_element_list: order_by_single_element_list:
ORDER_SYM BY order_ident order_dir ORDER_SYM BY order_list
; ;
window_name: window_name:
......
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