summaryrefslogtreecommitdiff
path: root/sql/item_sum.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_sum.h')
-rw-r--r--sql/item_sum.h82
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();
};