Commit 2efabf81 authored by Sergei Petrunia's avatar Sergei Petrunia

MDEV-9847: Window functions: crash with big_tables=1

- Move filesort's sort_positions argument into class Filesort.
- Make window function code construct Filesort with sort_positions=true.
parent 0a34dc1e
......@@ -1694,3 +1694,24 @@ EXPLAIN
}
}
drop table t1;
#
# MDEV-9847: Window functions: crash with big_tables=1
#
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
set @tmp=@@big_tables;
set big_tables=1;
select rank() over (order by a) from t1;
rank() over (order by a)
1
2
3
4
5
6
7
8
9
10
set big_tables=@tmp;
drop table t1;
......@@ -1063,3 +1063,15 @@ from t1;
drop table t1;
--echo #
--echo # MDEV-9847: Window functions: crash with big_tables=1
--echo #
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
set @tmp=@@big_tables;
set big_tables=1;
select rank() over (order by a) from t1;
set big_tables=@tmp;
drop table t1;
......@@ -124,17 +124,12 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table,
@param thd Current thread
@param table Table to sort
@param filesort How to sort the table
@param sort_positions Set to TRUE if we want to force sorting by
position
(Needed by UPDATE/INSERT or ALTER TABLE or
when rowids are required by executor)
applying WHERE condition.
@param[out] found_rows Store the number of found rows here.
This is the number of found rows after
applying WHERE condition.
@note
If we sort by position (like if sort_positions is 1) filesort() will
call table->prepare_for_position().
If we sort by position (like if filesort->sort_positions==true)
filesort() will call table->prepare_for_position().
@retval
0 Error
......@@ -142,7 +137,6 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table,
*/
SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
bool sort_positions,
Filesort_tracker* tracker)
{
int error;
......@@ -203,7 +197,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
&multi_byte_charset),
table,
thd->variables.max_length_for_sort_data,
max_rows, sort_positions);
max_rows, filesort->sort_positions);
sort->addon_buf= param.addon_buf;
sort->addon_field= param.addon_field;
......
......@@ -47,16 +47,25 @@ class Filesort: public Sql_alloc
bool own_select;
/** true means we are using Priority Queue for order by with limit. */
bool using_pq;
/*
TRUE means sort operation must produce table rowids.
FALSE means that it halso has an option of producing {sort_key,
addon_fields} pairs.
*/
bool sort_positions;
Filesort_tracker *tracker;
Filesort(ORDER *order_arg, ha_rows limit_arg, SQL_SELECT *select_arg):
Filesort(ORDER *order_arg, ha_rows limit_arg, bool sort_positions_arg,
SQL_SELECT *select_arg):
order(order_arg),
limit(limit_arg),
sortorder(NULL),
select(select_arg),
own_select(false),
using_pq(false)
using_pq(false),
sort_positions(sort_positions_arg)
{
DBUG_ASSERT(order);
};
......@@ -143,12 +152,10 @@ class SORT_INFO
{ return filesort_buffer.sort_buffer_size(); }
friend SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
bool sort_positions,
Filesort_tracker* tracker);
};
SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
bool sort_positions,
Filesort_tracker* tracker);
void change_double_for_sort(double nr,uchar *to);
......
......@@ -492,12 +492,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
{
{
Filesort fsort(order, HA_POS_ERROR, select);
Filesort fsort(order, HA_POS_ERROR, true, select);
DBUG_ASSERT(query_plan.index == MAX_KEY);
Filesort_tracker *fs_tracker=
thd->lex->explain->get_upd_del_plan()->filesort_tracker;
if (!(file_sort= filesort(thd, table, &fsort, true, fs_tracker)))
if (!(file_sort= filesort(thd, table, &fsort, fs_tracker)))
goto got_error;
thd->inc_examined_row_count(file_sort->examined_rows);
......
......@@ -2814,7 +2814,9 @@ JOIN::optimize_distinct()
bool
JOIN::add_sorting_to_table(JOIN_TAB *tab, ORDER *order)
{
tab->filesort= new (thd->mem_root) Filesort(order, HA_POS_ERROR, tab->select);
tab->filesort=
new (thd->mem_root) Filesort(order, HA_POS_ERROR, tab->keep_current_rowid,
tab->select);
if (!tab->filesort)
return true;
/*
......@@ -21279,7 +21281,7 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort)
if (table->s->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count
file_sort= filesort(thd, table, fsort, tab->keep_current_rowid, fsort->tracker);
file_sort= filesort(thd, table, fsort, fsort->tracker);
DBUG_ASSERT(tab->filesort_result == 0);
tab->filesort_result= file_sort;
tab->records= 0;
......
......@@ -9447,13 +9447,14 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
THD_STAGE_INFO(thd, stage_sorting);
Filesort_tracker dummy_tracker(false);
Filesort fsort(order, HA_POS_ERROR, NULL);
Filesort fsort(order, HA_POS_ERROR, true, NULL);
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
&tables, fields, all_fields, order))
goto err;
if (!(file_sort= filesort(thd, from, &fsort, true, &dummy_tracker)))
if (!(file_sort= filesort(thd, from, &fsort, &dummy_tracker)))
goto err;
}
thd_progress_next_stage(thd);
......
......@@ -558,12 +558,12 @@ int mysql_update(THD *thd,
to update
NOTE: filesort will call table->prepare_for_position()
*/
Filesort fsort(order, limit, select);
Filesort fsort(order, limit, true, select);
Filesort_tracker *fs_tracker=
thd->lex->explain->get_upd_del_plan()->filesort_tracker;
if (!(file_sort= filesort(thd, table, &fsort, true, fs_tracker)))
if (!(file_sort= filesort(thd, table, &fsort, fs_tracker)))
goto err;
thd->inc_examined_row_count(file_sort->examined_rows);
......
......@@ -1834,7 +1834,7 @@ bool Window_funcs_sort::setup(THD *thd, SQL_SELECT *sel,
ORDER* sort_order= concat_order_lists(thd->mem_root,
spec->partition_list->first,
spec->order_list->first);
filesort= new (thd->mem_root) Filesort(sort_order, HA_POS_ERROR, NULL);
filesort= new (thd->mem_root) Filesort(sort_order, HA_POS_ERROR, true, NULL);
/* Apply the same condition that the subsequent sort has. */
filesort->select= sel;
......
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