Skip to content
Permalink
Browse files

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.
  • Loading branch information...
spetrunia committed Apr 6, 2016
1 parent 0a34dc1 commit 2efabf81f1faae693ac381de688579283c6fad47
Showing with 60 additions and 22 deletions.
  1. +21 −0 mysql-test/r/win.result
  2. +12 −0 mysql-test/t/win.test
  3. +3 −9 sql/filesort.cc
  4. +11 −4 sql/filesort.h
  5. +3 −2 sql/sql_delete.cc
  6. +4 −2 sql/sql_select.cc
  7. +3 −2 sql/sql_table.cc
  8. +2 −2 sql/sql_update.cc
  9. +1 −1 sql/sql_window.cc
@@ -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,25 +124,19 @@ 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
# SORT_INFO
*/

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;
/*

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;

0 comments on commit 2efabf8

Please sign in to comment.
You can’t perform that action at this time.