Commit d8a20d4d authored by Sergei Petrunia's avatar Sergei Petrunia

Post-merge fixes. win.test passes but further cleanup is needed.

parent a9ed132a
......@@ -29,8 +29,8 @@ insert into t1 values (3, 10, 'xxx');
insert into t1 values (3, 20, 'vvv');
select a, row_number() over (partition by a order by b) from t1;
a row_number() over (partition by a order by b)
2 1
2 2
2 1
2 3
3 1
3 2
......
......@@ -19,6 +19,7 @@ Item_window_func::fix_fields(THD *thd, Item **ref)
return TRUE;
fixed= 1;
force_return_blank= true;
read_value_from_result_field= false;
return FALSE;
}
......
......@@ -19,11 +19,18 @@ class Item_sum_row_number: public Item_sum_int
{
longlong count;
void clear() {}
bool add() { return false; }
public:
void clear()
{
count= 0;
}
bool add()
{
count++;
return false;
}
void update_field() {}
public:
Item_sum_row_number(THD *thd)
: Item_sum_int(thd), count(0) {}
......@@ -32,6 +39,10 @@ class Item_sum_row_number: public Item_sum_int
return ROW_NUMBER_FUNC;
}
longlong val_int()
{
return count;
}
const char*func_name() const
{
return "row_number";
......@@ -251,19 +262,29 @@ class Item_sum_cume_dist: public Item_sum_num
class Item_window_func : public Item_result_field
{
/* Window function parameters as we've got them from the parser */
Item_sum *window_func;
LEX_STRING *window_name;
public:
Window_spec *window_spec;
/*
This stores the data bout the partition we're currently in.
advance_window() uses this to tell when we've left one partition and
entered another.
*/
List<Cached_item> partition_fields;
public:
Item_window_func(THD *thd, Item_sum *win_func, LEX_STRING *win_name)
: Item_result_field(thd), window_func(win_func),
window_name(win_name), window_spec(NULL),
force_return_blank(true),
read_value_from_result_field(false) {}
Item_window_func(THD *thd, Item_sum *win_func, Window_spec *win_spec)
: Item_result_field(thd), window_func(win_func),
window_name(NULL), window_spec(win_spec),
force_return_blank(true),
read_value_from_result_field(false) {}
/*
......@@ -271,6 +292,8 @@ class Item_window_func : public Item_result_field
*/
void setup_partition_border_check(THD *thd);
void advance_window();
enum_field_types field_type() const { return window_func->field_type(); }
enum Item::Type type() const { return Item::WINDOW_FUNC_ITEM; }
......@@ -292,7 +315,11 @@ class Item_window_func : public Item_result_field
item_windowfunc->val_int() will be called.
During Phase#3, read_value_from_result_field= true.
*/
public:
// TODO: how to reset this for subquery re-execution??
bool force_return_blank;
private:
bool read_value_from_result_field;
public:
......@@ -303,24 +330,32 @@ class Item_window_func : public Item_result_field
double val_real()
{
if (force_return_blank)
return 0.0;
return read_value_from_result_field? result_field->val_real() :
window_func->val_real();
}
longlong val_int()
{
if (force_return_blank)
return 0;
return read_value_from_result_field? result_field->val_int() :
window_func->val_int();
}
String* val_str(String* str)
{
if (force_return_blank)
return str;
return read_value_from_result_field? result_field->val_str(str) :
window_func->val_str(str);
}
my_decimal* val_decimal(my_decimal* dec)
{
if (force_return_blank)
return dec;
return read_value_from_result_field? result_field->val_decimal(dec) :
window_func->val_decimal(dec);
}
......
......@@ -181,7 +181,6 @@ end_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static enum_nested_loop_state
end_unique_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
static int test_if_group_changed(List<Cached_item> &list);
static int join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos);
static int join_read_system(JOIN_TAB *tab);
static int join_read_const(JOIN_TAB *tab);
......@@ -234,7 +233,7 @@ static bool list_contains_unique_index(TABLE *table,
bool (*find_func) (Field *, void *), void *data);
static bool find_field_in_item_list (Field *field, void *data);
static bool find_field_in_order_list (Field *field, void *data);
static int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab);
int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
Item *having);
static int remove_dup_with_hash_index(THD *thd,TABLE *table,
......@@ -3235,7 +3234,6 @@ void JOIN::exec_inner()
error= thd->is_error();
DBUG_VOID_RETURN;
}
process_window_functions(curr_fields_list);
THD_STAGE_INFO(thd, stage_sending_data);
DBUG_PRINT("info", ("%s", thd->proc_info));
......@@ -8500,6 +8498,11 @@ bool JOIN::get_best_combination()
(tmp_table_param. using_outer_summary_function ? 2 : 1) : 0) +
(order ? 1 : 0) +
(select_options & (SELECT_BIG_RESULT | OPTION_BUFFER_RESULT) ? 1 : 0) ;
// psergey-temp:
if (select_lex->window_specs.elements)
aggr_tables++;
if (aggr_tables > 2)
aggr_tables= 2;
if (!(join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*
......@@ -19062,7 +19065,7 @@ int join_init_read_record(JOIN_TAB *tab)
if (tab->distinct && tab->remove_duplicates()) // Remove duplicates.
return 1;
if (tab->filesort && tab->sort_table()) // Sort table.
if (tab->filesort && !tab->used_for_window_func && tab->sort_table()) // Sort table.
return 1;
if (tab->select && tab->select->quick && (error= tab->select->quick->reset()))
......@@ -21102,7 +21105,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
1 No records
*/
static int
int
create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab)
{
ha_rows examined_rows;
......@@ -22347,7 +22350,7 @@ int test_if_item_cache_changed(List<Cached_item> &list)
value>=0 - Number of the component where the group changed
*/
static int
int
test_if_group_changed(List<Cached_item> &list)
{
DBUG_ENTER("test_if_group_changed");
......@@ -25810,8 +25813,10 @@ AGGR_OP::end_send()
table->file->print_error(new_errno,MYF(0));
return NESTED_LOOP_ERROR;
}
// Update ref array
join_tab->join->set_items_ref_array(*join_tab->ref_array);
join->process_window_functions(&join->fields_list); // location #2
table->reginfo.lock_type= TL_UNLOCK;
bool in_first_read= true;
......
......@@ -424,6 +424,8 @@ typedef struct st_join_table {
/* Sorting related info */
Filesort *filesort;
bool used_for_window_func;
/**
List of topmost expressions in the select list. The *next* JOIN TAB
in the plan should use it to obtain correct values. Same applicable to
......@@ -2295,4 +2297,6 @@ class Pushdown_query: public Sql_alloc
};
bool test_if_order_compatible(SQL_I_List<ORDER> &a, SQL_I_List<ORDER> &b);
int test_if_group_changed(List<Cached_item> &list);
int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab);
#endif /* SQL_SELECT_INCLUDED */
......@@ -233,9 +233,24 @@ bool JOIN::process_window_functions(List<Item> *curr_fields_list)
if (item->type() == Item::WINDOW_FUNC_ITEM)
{
Item_window_func *item_win = (Item_window_func *) item;
item_win->force_return_blank= false;
Window_spec *spec = item_win->window_spec;
DBUG_ASSERT(spec->partition_list.next[0] == NULL);
*(spec->partition_list.next)= spec->order_list.first;
// spec->partition_list
// spec->order_list
add_sorting_to_table(&join_tab[top_join_tab_count],
spec->partition_list.first);
join_tab[top_join_tab_count].used_for_window_func= true;
create_sort_index(this->thd, this, &join_tab[top_join_tab_count]);
*(spec->partition_list.next)= NULL;
//join_tab[top_join_tab_count] has the temp. table that we need.
//bool JOIN::add_sorting_to_table(JOIN_TAB *tab, ORDER *order)
// spec->partition_list.first
#if 0
ha_rows examined_rows = 0;
ha_rows found_rows = 0;
ha_rows filesort_retval;
......@@ -277,18 +292,19 @@ bool JOIN::process_window_functions(List<Item> *curr_fields_list)
join_tab->records= found_rows;
my_free(s_order);
#endif
/*
Go through the sorted array and compute the window function
*/
READ_RECORD info;
if (init_read_record(&info, thd, table[0], select, 0, 1, FALSE))
//TABLE *tbl= *table;
TABLE *tbl= join_tab[top_join_tab_count].table;
if (init_read_record(&info, thd, tbl, select, 0, 1, FALSE))
return true;
item_win->setup_partition_border_check(thd);
int err;
TABLE *tbl= *table;
while (!(err=info.read_record(&info)))
{
store_record(tbl,record[1]);
......@@ -311,8 +327,10 @@ bool JOIN::process_window_functions(List<Item> *curr_fields_list)
}
item_win->set_read_value_from_result_field();
end_read_record(&info);
#if 0
filesort_free_buffers(table[0], true);
free_io_cache(table[0]);
#endif
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment