summaryrefslogtreecommitdiff
path: root/sql/item_windowfunc.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_windowfunc.h')
-rw-r--r--sql/item_windowfunc.h175
1 files changed, 107 insertions, 68 deletions
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index 8b53b2012e7..f38209e4bb5 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2016,2017 MariaDB
+ Copyright (c) 2016,2019 MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -445,28 +445,38 @@ class Item_sum_lag : public Item_sum_hybrid_simple
{ return get_item_copy<Item_sum_lag>(thd, this); }
};
-/*
- A base window function (aggregate) that also holds a counter for the number
- of rows.
-*/
-class Item_sum_window_with_row_count : public Item_sum_num
-{
- public:
- Item_sum_window_with_row_count(THD *thd) : Item_sum_num(thd),
- partition_row_count_(0) {}
-
- Item_sum_window_with_row_count(THD *thd, Item *arg) :
- Item_sum_num(thd, arg), partition_row_count_(0) {};
-
- void set_row_count(ulonglong count) { partition_row_count_ = count; }
- void reset_field() { DBUG_ASSERT(0); }
- protected:
+class Partition_row_count
+{
+public:
+ Partition_row_count() :partition_row_count_(0) { }
+ void set_partition_row_count(ulonglong count)
+ {
+ partition_row_count_ = count;
+ }
+ double calc_val_real(bool *null_value,
+ ulonglong current_row_count)
+ {
+ if ((*null_value= (partition_row_count_ == 0)))
+ return 0;
+ return static_cast<double>(current_row_count) / partition_row_count_;
+ }
+protected:
longlong get_row_count() { return partition_row_count_; }
- private:
ulonglong partition_row_count_;
};
+
+class Current_row_count
+{
+public:
+ Current_row_count() :current_row_count_(0) { }
+protected:
+ ulonglong get_row_number() { return current_row_count_ ; }
+ ulonglong current_row_count_;
+};
+
+
/*
@detail
"The relative rank of a row R is defined as (RK-1)/(NR-1), where RK is
@@ -478,11 +488,12 @@ class Item_sum_window_with_row_count : public Item_sum_num
This is held within the row_count context.
- Second pass to compute rank of current row and the value of the function
*/
-class Item_sum_percent_rank: public Item_sum_window_with_row_count
+class Item_sum_percent_rank: public Item_sum_double,
+ public Partition_row_count
{
public:
Item_sum_percent_rank(THD *thd)
- : Item_sum_window_with_row_count(thd), cur_rank(1), peer_tracker(NULL) {}
+ : Item_sum_double(thd), cur_rank(1), peer_tracker(NULL) {}
longlong val_int()
{
@@ -535,6 +546,14 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
}
void setup_window_func(THD *thd, Window_spec *window_spec);
+
+ void reset_field() { DBUG_ASSERT(0); }
+
+ void set_partition_row_count(ulonglong count)
+ {
+ Partition_row_count::set_partition_row_count(count);
+ }
+
Item *get_copy(THD *thd)
{ return get_item_copy<Item_sum_percent_rank>(thd, this); }
@@ -569,25 +588,17 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
two passes.
*/
-class Item_sum_cume_dist: public Item_sum_window_with_row_count
+class Item_sum_cume_dist: public Item_sum_double,
+ public Partition_row_count,
+ public Current_row_count
{
public:
- Item_sum_cume_dist(THD *thd) : Item_sum_window_with_row_count(thd),
- current_row_count_(0) {}
-
- Item_sum_cume_dist(THD *thd, Item *arg) : Item_sum_window_with_row_count(thd,arg),
- current_row_count_(0) {}
+ Item_sum_cume_dist(THD *thd) :Item_sum_double(thd) { }
+ Item_sum_cume_dist(THD *thd, Item *arg) :Item_sum_double(thd, arg) { }
double val_real()
{
- if (get_row_count() == 0)
- {
- null_value= true;
- return 0;
- }
- ulonglong partition_row_count= get_row_count();
- null_value= false;
- return static_cast<double>(current_row_count_) / partition_row_count;
+ return calc_val_real(&null_value, current_row_count_);
}
bool add()
@@ -604,7 +615,7 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
void clear()
{
current_row_count_= 0;
- set_row_count(0);
+ partition_row_count_= 0;
}
const char*func_name() const
@@ -622,29 +633,26 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
return FALSE;
}
- Item *get_copy(THD *thd)
- { return get_item_copy<Item_sum_cume_dist>(thd, this); }
+ void reset_field() { DBUG_ASSERT(0); }
- ulonglong get_row_number()
+ void set_partition_row_count(ulonglong count)
{
- return current_row_count_ ;
+ Partition_row_count::set_partition_row_count(count);
}
- private:
- ulonglong current_row_count_;
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_sum_cume_dist>(thd, this); }
+
};
-class Item_sum_ntile : public Item_sum_window_with_row_count
+class Item_sum_ntile : public Item_sum_int,
+ public Partition_row_count,
+ public Current_row_count
{
public:
Item_sum_ntile(THD* thd, Item* num_quantiles_expr) :
- Item_sum_window_with_row_count(thd, num_quantiles_expr),
- current_row_count_(0) {};
-
- double val_real()
- {
- return (double) val_int();
- }
+ Item_sum_int(thd, num_quantiles_expr)
+ { }
longlong val_int()
{
@@ -685,7 +693,7 @@ class Item_sum_ntile : public Item_sum_window_with_row_count
void clear()
{
current_row_count_= 0;
- set_row_count(0);
+ partition_row_count_= 0;
}
const char*func_name() const
@@ -696,20 +704,28 @@ class Item_sum_ntile : public Item_sum_window_with_row_count
void update_field() {}
const Type_handler *type_handler() const { return &type_handler_slonglong; }
-
+
+ void reset_field() { DBUG_ASSERT(0); }
+
+ void set_partition_row_count(ulonglong count)
+ {
+ Partition_row_count::set_partition_row_count(count);
+ }
+
Item *get_copy(THD *thd)
{ return get_item_copy<Item_sum_ntile>(thd, this); }
private:
longlong get_num_quantiles() { return args[0]->val_int(); }
- ulong current_row_count_;
};
-class Item_sum_percentile_disc : public Item_sum_cume_dist,
- public Type_handler_hybrid_field_type
+class Item_sum_percentile_disc : public Item_sum_num,
+ public Type_handler_hybrid_field_type,
+ public Partition_row_count,
+ public Current_row_count
{
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_num(thd, arg),
Type_handler_hybrid_field_type(&type_handler_slonglong),
value(NULL), val_calculated(FALSE), first_call(TRUE),
prev_value(0), order_item(NULL){}
@@ -758,6 +774,17 @@ public:
return value->val_str(str);
}
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
+ {
+ if (get_row_count() == 0 || get_arg(0)->is_null())
+ {
+ null_value= true;
+ return 0;
+ }
+ null_value= false;
+ return value->get_date(thd, ltime, fuzzydate);
+ }
+
bool add()
{
Item *arg= get_arg(0);
@@ -791,8 +818,8 @@ public:
if (value->null_value)
return false;
- Item_sum_cume_dist::add();
- double val= Item_sum_cume_dist::val_real();
+ current_row_count_++;
+ double val= calc_val_real(&null_value, current_row_count_);
if (val >= prev_value && !val_calculated)
val_calculated= true;
@@ -809,7 +836,8 @@ public:
val_calculated= false;
first_call= true;
value->clear();
- Item_sum_cume_dist::clear();
+ partition_row_count_= 0;
+ current_row_count_= 0;
}
const char*func_name() const
@@ -818,7 +846,6 @@ public:
}
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();}
@@ -829,6 +856,13 @@ public:
return FALSE;
}
+ void reset_field() { DBUG_ASSERT(0); }
+
+ void set_partition_row_count(ulonglong count)
+ {
+ Partition_row_count::set_partition_row_count(count);
+ }
+
Item *get_copy(THD *thd)
{ return get_item_copy<Item_sum_percentile_disc>(thd, this); }
void setup_window_func(THD *thd, Window_spec *window_spec);
@@ -843,12 +877,12 @@ private:
Item *order_item;
};
-class Item_sum_percentile_cont : public Item_sum_cume_dist,
- public Type_handler_hybrid_field_type
+class Item_sum_percentile_cont : public Item_sum_double,
+ public Partition_row_count,
+ public Current_row_count
{
public:
- Item_sum_percentile_cont(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg),
- Type_handler_hybrid_field_type(&type_handler_double),
+ Item_sum_percentile_cont(THD *thd, Item* arg) : Item_sum_double(thd, arg),
floor_value(NULL), ceil_value(NULL), first_call(TRUE),prev_value(0),
ceil_val_calculated(FALSE), floor_val_calculated(FALSE), order_item(NULL){}
@@ -918,7 +952,7 @@ public:
return false;
}
- Item_sum_cume_dist::add();
+ current_row_count_++;
double val= 1 + prev_value * (get_row_count()-1);
if (!floor_val_calculated && get_row_number() == floor(val))
@@ -941,7 +975,8 @@ public:
ceil_value->clear();
floor_val_calculated= false;
ceil_val_calculated= false;
- Item_sum_cume_dist::clear();
+ partition_row_count_= 0;
+ current_row_count_= 0;
}
const char*func_name() const
@@ -949,9 +984,6 @@ public:
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();}
bool fix_length_and_dec()
{
@@ -960,6 +992,13 @@ public:
return FALSE;
}
+ void reset_field() { DBUG_ASSERT(0); }
+
+ void set_partition_row_count(ulonglong count)
+ {
+ Partition_row_count::set_partition_row_count(count);
+ }
+
Item *get_copy(THD *thd)
{ return get_item_copy<Item_sum_percentile_cont>(thd, this); }
void setup_window_func(THD *thd, Window_spec *window_spec);