Percentile class implemented, most of the functions have the same functionalite as the percentile cont class

This commit is contained in:
Varun Gupta 2017-07-07 17:37:06 +05:30
parent 01d2b6e9d9
commit 275ce39f05
4 changed files with 184 additions and 3 deletions

View file

@ -117,6 +117,12 @@ Item_window_func::fix_fields(THD *thd, Item **ref)
my_error(ER_NO_ORDER_LIST_IN_WINDOW_SPEC, MYF(0), window_func()->func_name());
return true;
}
/*switch(window_spec->order_list->firt->item[0]->type())
{
case INT_TYPE:
default:
break;
}*/
}
/*
@ -215,6 +221,21 @@ void Item_sum_percentile_disc::setup_window_func(THD *thd, Window_spec *window_s
value->store(order_item);
}
void Item_sum_percentile_cont::setup_window_func(THD *thd, Window_spec *window_spec)
{
order_item= window_spec->order_list->first->item[0];
//set_handler_by_cmp_type(order_item->result_type());
if (!(ceil_value= order_item->get_cache(thd)))
return;
ceil_value->setup(thd, order_item);
ceil_value->store(order_item);
if (!(floor_value= order_item->get_cache(thd)))
return;
floor_value->setup(thd, order_item);
floor_value->store(order_item);
}
bool Item_sum_dense_rank::add()
{
if (peer_tracker->check_if_next_group() || first_add)

View file

@ -646,7 +646,7 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
ulonglong get_row_number()
{
return current_row_count_;
return current_row_count_ ;
}
private:
@ -774,10 +774,14 @@ public:
if (first_call)
{
prev_value= arg->val_real();
if (prev_value >1 || prev_value < 0)
{
return true;
}
first_call= false;
}
if(prev_value != arg->val_real() || prev_value >1 || prev_value < 0)
if(prev_value != arg->val_real())
{
// TODO(varun) need to add an error here , check the MDEV-12985 for the information
return true;
@ -841,6 +845,159 @@ private:
Item *order_item;
};
class Item_sum_percentile_cont : public Item_sum_cume_dist,
public Type_handler_hybrid_field_type
{
public:
Item_sum_percentile_cont(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg),
Type_handler_hybrid_field_type(&type_handler_double),
floor_value(NULL), ceil_value(NULL), first_call(TRUE),prev_value(0),
ceil_val_calculated(FALSE), floor_val_calculated(FALSE), order_item(NULL){}
double val_real()
{
if (get_row_count() == 0 || get_arg(0)->is_null())
{
null_value= true;
return 0;
}
null_value= false;
double val= 1 + prev_value * (get_row_count()-1);
/*
Applying the formula to get the value
If (CRN = FRN = RN) then the result is (value of expression from row at RN)
Otherwise the result is
(CRN - RN) * (value of expression for row at FRN) +
(RN - FRN) * (value of expression for row at CRN)
*/
if(ceil(val) == floor(val))
return floor_value->val_real();
double ret_val= ((val - floor(val)) * ceil_value->val_real()) +
((ceil(val) - val) * floor_value->val_real());
return ret_val;
}
longlong val_int()
{
if (get_row_count() == 0 || get_arg(0)->is_null())
{
null_value= true;
return 0;
}
null_value= false;
return 0;
}
my_decimal* val_decimal(my_decimal* dec)
{
if (get_row_count() == 0 || get_arg(0)->is_null())
{
null_value= true;
return 0;
return 0;
}
null_value= false;
return ceil_value->val_decimal(dec);
}
bool add()
{
Item *arg = get_arg(0);
if (arg->is_null())
return true;
if (first_call)
{
first_call= false;
prev_value= arg->val_real();
if (prev_value >1 || prev_value < 0)
{
// TODO(varun) need to add an error here , check the MDEV-12985 for the information
return true;
}
}
if (prev_value != arg->val_real())
{
// TODO(varun) need to add an error here , check the MDEV-12985 for the information
return true;
}
if (!floor_val_calculated)
{
floor_value->store(order_item);
floor_value->cache_value();
if (floor_value->null_value)
return false;
}
if (floor_val_calculated && !ceil_val_calculated)
{
ceil_value->store(order_item);
ceil_value->cache_value();
if (ceil_value->null_value)
return false;
}
Item_sum_cume_dist::add();
double val= 1 + prev_value * (get_row_count()-1);
if (!floor_val_calculated && get_row_number() == floor(val))
floor_val_calculated= true;
if (!ceil_val_calculated && get_row_number() == ceil(val))
ceil_val_calculated= true;
return false;
}
enum Sumfunctype sum_func() const
{
return PERCENTILE_DISC_FUNC;
}
void clear()
{
first_call= true;
floor_value->clear();
ceil_value->clear();
floor_val_calculated= false;
ceil_val_calculated= false;
Item_sum_cume_dist::clear();
}
const char*func_name() const
{
return "percentile_cont";
}
void update_field() {}
void set_type_handler(Window_spec *window_spec);
const Type_handler *type_handler() const
{return Type_handler_hybrid_field_type::type_handler();}
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_cont>(thd, mem_root, this); }
void setup_window_func(THD *thd, Window_spec *window_spec);
void setup_hybrid(THD *thd, Item *item);
private:
Item_cache *floor_value;
Item_cache *ceil_value;
bool first_call;
double prev_value;
bool ceil_val_calculated;
bool floor_val_calculated;
Item *order_item;
};

View file

@ -2540,6 +2540,7 @@ void add_special_frame_cursors(THD *thd, Cursor_manager *cursor_manager,
cursor_manager->add_cursor(fc);
break;
}
case Item_sum::PERCENTILE_CONT_FUNC:
case Item_sum::PERCENTILE_DISC_FUNC:
{
fc= new Frame_unbounded_preceding(thd,

View file

@ -10723,7 +10723,9 @@ inverse_distribution_function:
inverse_distribution_function_def:
PERCENTILE_CONT_SYM '(' expr ')'
{
//Not yet started implementing
$$= new (thd->mem_root) Item_sum_percentile_cont(thd, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| PERCENTILE_DISC_SYM '(' expr ')'
{