summaryrefslogtreecommitdiff
path: root/sql/item_windowfunc.h
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2016-09-01 18:10:15 +0300
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2016-09-09 18:32:35 +0300
commit23e8b508a00a23653da436519371943487ad6fe4 (patch)
tree39640892aea08485ea2eb8f9005472b1808d500c /sql/item_windowfunc.h
parent19d24f011cc16efd0edb4ca8cc9ce8c720842961 (diff)
downloadmariadb-git-23e8b508a00a23653da436519371943487ad6fe4.tar.gz
MDEV-10059: Compute window functions with same sorting criteria simultaneously
Perform only one table scan for each window function present. We do this by keeping keeping cursors for each window function frame bound and running them for each function for every row.
Diffstat (limited to 'sql/item_windowfunc.h')
-rw-r--r--sql/item_windowfunc.h90
1 files changed, 51 insertions, 39 deletions
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index 163cc855fe2..bb2256207ec 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -12,25 +12,19 @@ int test_if_group_changed(List<Cached_item> &list);
/* A wrapper around test_if_group_changed */
class Group_bound_tracker
{
- List<Cached_item> group_fields;
- /*
- During the first check_if_next_group, the list of cached_items is not
- initialized. The compare function will return that the items match if
- the field's value is the same as the Cached_item's default value (0).
- This flag makes sure that we always return true during the first check.
-
- XXX This is better to be implemented within test_if_group_changed, but
- since it is used in other parts of the codebase, we keep it here for now.
- */
- bool first_check;
public:
- void init(THD *thd, SQL_I_List<ORDER> *list)
+
+ Group_bound_tracker(THD *thd, SQL_I_List<ORDER> *list)
{
for (ORDER *curr = list->first; curr; curr=curr->next)
{
Cached_item *tmp= new_Cached_item(thd, curr->item[0], TRUE);
group_fields.push_back(tmp);
}
+ }
+
+ void init()
+ {
first_check= true;
}
@@ -76,6 +70,19 @@ public:
}
return 0;
}
+
+private:
+ List<Cached_item> group_fields;
+ /*
+ During the first check_if_next_group, the list of cached_items is not
+ initialized. The compare function will return that the items match if
+ the field's value is the same as the Cached_item's default value (0).
+ This flag makes sure that we always return true during the first check.
+
+ XXX This is better to be implemented within test_if_group_changed, but
+ since it is used in other parts of the codebase, we keep it here for now.
+ */
+ bool first_check;
};
/*
@@ -92,19 +99,22 @@ class Item_sum_row_number: public Item_sum_int
longlong count;
public:
+
+ Item_sum_row_number(THD *thd)
+ : Item_sum_int(thd), count(0) {}
+
void clear()
{
count= 0;
}
- bool add()
+
+ bool add()
{
count++;
- return false;
+ return false;
}
- void update_field() {}
- Item_sum_row_number(THD *thd)
- : Item_sum_int(thd), count(0) {}
+ void update_field() {}
enum Sumfunctype sum_func() const
{
@@ -119,6 +129,7 @@ public:
{
return "row_number(";
}
+
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_row_number>(thd, mem_root, this); }
};
@@ -146,9 +157,12 @@ class Item_sum_rank: public Item_sum_int
protected:
longlong row_number; // just ROW_NUMBER()
longlong cur_rank; // current value
-
- Group_bound_tracker peer_tracker;
+
+ Group_bound_tracker *peer_tracker;
public:
+
+ Item_sum_rank(THD *thd) : Item_sum_int(thd), peer_tracker(NULL) {}
+
void clear()
{
/* This is called on partition start */
@@ -169,10 +183,6 @@ public:
TODO: ^^ what does this do ? It is not called ever?
*/
-public:
- Item_sum_rank(THD *thd)
- : Item_sum_int(thd) {}
-
enum Sumfunctype sum_func () const
{
return RANK_FUNC;
@@ -184,9 +194,12 @@ public:
}
void setup_window_func(THD *thd, Window_spec *window_spec);
+
void cleanup()
{
- peer_tracker.cleanup();
+ if (peer_tracker)
+ peer_tracker->cleanup();
+ delete peer_tracker;
Item_sum_int::cleanup();
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -217,7 +230,7 @@ class Item_sum_dense_rank: public Item_sum_int
{
longlong dense_rank;
bool first_add;
- Group_bound_tracker peer_tracker;
+ Group_bound_tracker *peer_tracker;
public:
/*
XXX(cvicentiu) This class could potentially be implemented in the rank
@@ -236,7 +249,7 @@ class Item_sum_dense_rank: public Item_sum_int
}
Item_sum_dense_rank(THD *thd)
- : Item_sum_int(thd), dense_rank(0), first_add(true) {}
+ : Item_sum_int(thd), dense_rank(0), first_add(true), peer_tracker(NULL) {}
enum Sumfunctype sum_func () const
{
return DENSE_RANK_FUNC;
@@ -251,7 +264,11 @@ class Item_sum_dense_rank: public Item_sum_int
void cleanup()
{
- peer_tracker.cleanup();
+ if (peer_tracker)
+ {
+ peer_tracker->cleanup();
+ delete peer_tracker;
+ }
Item_sum_int::cleanup();
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -294,7 +311,7 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
{
public:
Item_sum_percent_rank(THD *thd)
- : Item_sum_window_with_row_count(thd), cur_rank(1) {}
+ : Item_sum_window_with_row_count(thd), cur_rank(1), peer_tracker(NULL) {}
longlong val_int()
{
@@ -354,11 +371,15 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
longlong cur_rank; // Current rank of the current row.
longlong row_number; // Value if this were ROW_NUMBER() function.
- Group_bound_tracker peer_tracker;
+ Group_bound_tracker *peer_tracker;
void cleanup()
{
- peer_tracker.cleanup();
+ if (peer_tracker)
+ {
+ peer_tracker->cleanup();
+ delete peer_tracker;
+ }
Item_sum_num::cleanup();
}
};
@@ -515,12 +536,6 @@ public:
public:
Window_spec *window_spec;
- /*
- This stores the data about the partition we're currently in.
- advance_window() uses this to tell when we've left one partition and
- entered another
- */
- Group_bound_tracker partition_tracker;
public:
Item_window_func(THD *thd, Item_sum *win_func, LEX_STRING *win_name)
: Item_func_or_sum(thd, (Item *) win_func),
@@ -613,9 +628,6 @@ public:
*/
void setup_partition_border_check(THD *thd);
- void advance_window();
- bool check_if_partition_changed();
-
enum_field_types field_type() const
{
return ((Item_sum *) args[0])->field_type();