diff options
Diffstat (limited to 'sql/item_sum.h')
-rw-r--r-- | sql/item_sum.h | 82 |
1 files changed, 73 insertions, 9 deletions
diff --git a/sql/item_sum.h b/sql/item_sum.h index 811e9d5c59c..e766e69a1c5 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -109,6 +109,7 @@ public: class st_select_lex; +class Window_spec; /** Class Item_sum is the base class used for special expressions that SQL calls @@ -347,7 +348,9 @@ public: enum Sumfunctype { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC, AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC, - 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, + CUME_DIST_FUNC, NTILE_FUNC }; Item **ref_by; /* pointer to a ref to the object used to register it */ @@ -540,12 +543,16 @@ public: virtual void clear()= 0; virtual bool add()= 0; virtual bool setup(THD *thd) { return false; } + + virtual void remove() { DBUG_ASSERT(0); } virtual void cleanup(); bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + + virtual void setup_window_func(THD *thd, Window_spec *window_spec) {} }; @@ -710,6 +717,7 @@ public: class Item_sum_int :public Item_sum_num { public: + Item_sum_int(THD *thd): Item_sum_num(thd) {} Item_sum_int(THD *thd, Item *item_par): Item_sum_num(thd, item_par) {} Item_sum_int(THD *thd, List<Item> &list): Item_sum_num(thd, list) {} Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {} @@ -724,7 +732,7 @@ public: class Item_sum_sum :public Item_sum_num, - public Type_handler_hybrid_field_type + public Type_handler_hybrid_field_type { protected: double sum; @@ -763,6 +771,11 @@ public: return has_with_distinct() ? "sum(distinct " : "sum("; } Item *copy_or_same(THD* thd); + void remove(); + +private: + void add_helper(bool perform_removal); + ulonglong count; }; @@ -775,6 +788,7 @@ class Item_sum_count :public Item_sum_int void clear(); bool add(); void cleanup(); + void remove(); public: Item_sum_count(THD *thd, Item *item_par): @@ -821,6 +835,8 @@ class Item_sum_count :public Item_sum_int class Item_sum_avg :public Item_sum_sum { public: + // TODO-cvicentiu given that Item_sum_sum now uses a counter of its own, in + // order to implement remove(), it is possible to remove this member. ulonglong count; uint prec_increment; uint f_precision, f_scale, dec_bin_size; @@ -839,6 +855,7 @@ public: } void clear(); bool add(); + void remove(); double val_real(); // In SPs we might force the "wrong" type with select into a declare variable longlong val_int() { return val_int_from_real(); } @@ -1019,14 +1036,18 @@ public: class Item_sum_bit :public Item_sum_int { -protected: - ulonglong reset_bits,bits; - public: Item_sum_bit(THD *thd, Item *item_par, ulonglong reset_arg): - Item_sum_int(thd, item_par), reset_bits(reset_arg), bits(reset_arg) {} + Item_sum_int(thd, item_par), reset_bits(reset_arg), bits(reset_arg), + as_window_function(FALSE), num_values_added(0) {} Item_sum_bit(THD *thd, Item_sum_bit *item): - Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits) {} + Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits), + as_window_function(item->as_window_function), + num_values_added(item->num_values_added) + { + if (as_window_function) + memcpy(bit_counters, item->bit_counters, sizeof(bit_counters)); + } enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;} void clear(); longlong val_int(); @@ -1037,8 +1058,42 @@ public: void cleanup() { bits= reset_bits; + if (as_window_function) + clear_as_window(); Item_sum_int::cleanup(); } + void setup_window_func(THD *thd __attribute__((unused)), + Window_spec *window_spec __attribute__((unused))) + { + as_window_function= TRUE; + clear_as_window(); + } + void remove() + { + if (as_window_function) + { + remove_as_window(args[0]->val_int()); + return; + } + // Unless we're counting bits, we can not remove anything. + DBUG_ASSERT(0); + } + +protected: + static const int NUM_BIT_COUNTERS= 64; + ulonglong reset_bits,bits; + /* + Marks whether the function is to be computed as a window function. + */ + bool as_window_function; + // When used as an aggregate window function, we need to store + // this additional information. + ulonglong num_values_added; + ulonglong bit_counters[NUM_BIT_COUNTERS]; + bool add_as_window(ulonglong value); + bool remove_as_window(ulonglong value); + bool clear_as_window(); + virtual void set_bits_from_counters()= 0; }; @@ -1050,28 +1105,37 @@ public: bool add(); const char *func_name() const { return "bit_or("; } Item *copy_or_same(THD* thd); + +private: + void set_bits_from_counters(); }; class Item_sum_and :public Item_sum_bit { - public: +public: Item_sum_and(THD *thd, Item *item_par): Item_sum_bit(thd, item_par, ULONGLONG_MAX) {} Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {} bool add(); const char *func_name() const { return "bit_and("; } Item *copy_or_same(THD* thd); + +private: + void set_bits_from_counters(); }; class Item_sum_xor :public Item_sum_bit { - public: +public: Item_sum_xor(THD *thd, Item *item_par): Item_sum_bit(thd, item_par, 0) {} Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {} bool add(); const char *func_name() const { return "bit_xor("; } Item *copy_or_same(THD* thd); + +private: + void set_bits_from_counters(); }; |