mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Lay the groundwork for variable number of cursors.
Instead of relying solely on top bound and bottom bound cursors, now we create a list of cursors that are iterated over.
This commit is contained in:
@@ -499,11 +499,11 @@ public:
|
|||||||
force_return_blank(true),
|
force_return_blank(true),
|
||||||
read_value_from_result_field(false) {}
|
read_value_from_result_field(false) {}
|
||||||
|
|
||||||
Item_sum *window_func() { return (Item_sum *) args[0]; }
|
Item_sum *window_func() const { return (Item_sum *) args[0]; }
|
||||||
|
|
||||||
void update_used_tables();
|
void update_used_tables();
|
||||||
|
|
||||||
bool is_frame_prohibited()
|
bool is_frame_prohibited() const
|
||||||
{
|
{
|
||||||
switch (window_func()->sum_func()) {
|
switch (window_func()->sum_func()) {
|
||||||
case Item_sum::ROW_NUMBER_FUNC:
|
case Item_sum::ROW_NUMBER_FUNC:
|
||||||
@@ -517,7 +517,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_order_list_mandatory()
|
bool is_order_list_mandatory() const
|
||||||
{
|
{
|
||||||
switch (window_func()->sum_func()) {
|
switch (window_func()->sum_func()) {
|
||||||
case Item_sum::RANK_FUNC:
|
case Item_sum::RANK_FUNC:
|
||||||
|
@@ -1212,6 +1212,28 @@ Frame_cursor *get_frame_cursor(Window_frame *frame, bool is_top_bound)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Frame_cursor> get_window_func_required_cursors(
|
||||||
|
const Item_window_func* item_win)
|
||||||
|
{
|
||||||
|
List<Frame_cursor> result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
If it is not a regular window function that follows frame specifications,
|
||||||
|
specific cursors are required.
|
||||||
|
*/
|
||||||
|
if (item_win->is_frame_prohibited())
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0); // TODO-cvicentiu not-implemented yet.
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A regular window function follows the frame specification. */
|
||||||
|
result.push_back(get_frame_cursor(item_win->window_spec->window_frame,
|
||||||
|
false));
|
||||||
|
result.push_back(get_frame_cursor(item_win->window_spec->window_frame,
|
||||||
|
true));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Streamed window function computation with window frames.
|
Streamed window function computation with window frames.
|
||||||
@@ -1254,21 +1276,21 @@ bool compute_window_func_with_frames(Item_window_func *item_win,
|
|||||||
{
|
{
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
int err= 0;
|
int err= 0;
|
||||||
Frame_cursor *top_bound;
|
|
||||||
Frame_cursor *bottom_bound;
|
|
||||||
|
|
||||||
Item_sum *sum_func= item_win->window_func();
|
Item_sum *sum_func= item_win->window_func();
|
||||||
/* This algorithm doesn't support DISTINCT aggregator */
|
/* This algorithm doesn't support DISTINCT aggregator */
|
||||||
sum_func->set_aggregator(Aggregator::SIMPLE_AGGREGATOR);
|
sum_func->set_aggregator(Aggregator::SIMPLE_AGGREGATOR);
|
||||||
|
|
||||||
Window_frame *window_frame= item_win->window_spec->window_frame;
|
List<Frame_cursor> cursors= get_window_func_required_cursors(item_win);
|
||||||
top_bound= get_frame_cursor(window_frame, true);
|
|
||||||
bottom_bound= get_frame_cursor(window_frame, false);
|
|
||||||
|
|
||||||
top_bound->init(thd, info, item_win->window_spec->partition_list,
|
|
||||||
item_win->window_spec->order_list);
|
List_iterator_fast<Frame_cursor> it(cursors);
|
||||||
bottom_bound->init(thd, info, item_win->window_spec->partition_list,
|
Frame_cursor *c;
|
||||||
|
while((c= it++))
|
||||||
|
{
|
||||||
|
c->init(thd, info, item_win->window_spec->partition_list,
|
||||||
item_win->window_spec->order_list);
|
item_win->window_spec->order_list);
|
||||||
|
}
|
||||||
|
|
||||||
bool is_error= false;
|
bool is_error= false;
|
||||||
longlong rownum= 0;
|
longlong rownum= 0;
|
||||||
@@ -1293,24 +1315,28 @@ bool compute_window_func_with_frames(Item_window_func *item_win,
|
|||||||
pre_XXX functions assume that tbl->record[0] contains current_row, and
|
pre_XXX functions assume that tbl->record[0] contains current_row, and
|
||||||
they may not change it.
|
they may not change it.
|
||||||
*/
|
*/
|
||||||
bottom_bound->pre_next_partition(rownum, sum_func);
|
it.rewind();
|
||||||
top_bound->pre_next_partition(rownum, sum_func);
|
while ((c= it++))
|
||||||
|
c->pre_next_partition(rownum, sum_func);
|
||||||
/*
|
/*
|
||||||
We move bottom_bound first, because we want rows to be added into the
|
We move bottom_bound first, because we want rows to be added into the
|
||||||
aggregate before top_bound attempts to remove them.
|
aggregate before top_bound attempts to remove them.
|
||||||
*/
|
*/
|
||||||
bottom_bound->next_partition(rownum, sum_func);
|
it.rewind();
|
||||||
top_bound->next_partition(rownum, sum_func);
|
while ((c= it++))
|
||||||
|
c->next_partition(rownum, sum_func);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Again, both pre_XXX function can find current_row in tbl->record[0] */
|
/* Again, both pre_XXX function can find current_row in tbl->record[0] */
|
||||||
bottom_bound->pre_next_row(sum_func);
|
it.rewind();
|
||||||
top_bound->pre_next_row(sum_func);
|
while ((c= it++))
|
||||||
|
c->pre_next_row(sum_func);
|
||||||
|
|
||||||
/* These make no assumptions about tbl->record[0] and may change it */
|
/* These make no assumptions about tbl->record[0] and may change it */
|
||||||
bottom_bound->next_row(sum_func);
|
it.rewind();
|
||||||
top_bound->next_row(sum_func);
|
while ((c= it++))
|
||||||
|
c->next_row(sum_func);
|
||||||
}
|
}
|
||||||
rownum++;
|
rownum++;
|
||||||
|
|
||||||
@@ -1331,8 +1357,7 @@ bool compute_window_func_with_frames(Item_window_func *item_win,
|
|||||||
}
|
}
|
||||||
|
|
||||||
my_free(rowid_buf);
|
my_free(rowid_buf);
|
||||||
delete top_bound;
|
cursors.delete_elements();
|
||||||
delete bottom_bound;
|
|
||||||
return is_error? true: false;
|
return is_error? true: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user