mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
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.
This commit is contained in:
@@ -1694,3 +1694,24 @@ EXPLAIN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
drop table t1;
|
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;
|
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 thd Current thread
|
||||||
@param table Table to sort
|
@param table Table to sort
|
||||||
@param filesort How to sort the table
|
@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.
|
@param[out] found_rows Store the number of found rows here.
|
||||||
This is the number of found rows after
|
This is the number of found rows after
|
||||||
applying WHERE condition.
|
applying WHERE condition.
|
||||||
@note
|
@note
|
||||||
If we sort by position (like if sort_positions is 1) filesort() will
|
If we sort by position (like if filesort->sort_positions==true)
|
||||||
call table->prepare_for_position().
|
filesort() will call table->prepare_for_position().
|
||||||
|
|
||||||
@retval
|
@retval
|
||||||
0 Error
|
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,
|
SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
||||||
bool sort_positions,
|
|
||||||
Filesort_tracker* tracker)
|
Filesort_tracker* tracker)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
@@ -203,7 +197,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
|||||||
&multi_byte_charset),
|
&multi_byte_charset),
|
||||||
table,
|
table,
|
||||||
thd->variables.max_length_for_sort_data,
|
thd->variables.max_length_for_sort_data,
|
||||||
max_rows, sort_positions);
|
max_rows, filesort->sort_positions);
|
||||||
|
|
||||||
sort->addon_buf= param.addon_buf;
|
sort->addon_buf= param.addon_buf;
|
||||||
sort->addon_field= param.addon_field;
|
sort->addon_field= param.addon_field;
|
||||||
|
@@ -48,15 +48,24 @@ public:
|
|||||||
/** true means we are using Priority Queue for order by with limit. */
|
/** true means we are using Priority Queue for order by with limit. */
|
||||||
bool using_pq;
|
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_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),
|
order(order_arg),
|
||||||
limit(limit_arg),
|
limit(limit_arg),
|
||||||
sortorder(NULL),
|
sortorder(NULL),
|
||||||
select(select_arg),
|
select(select_arg),
|
||||||
own_select(false),
|
own_select(false),
|
||||||
using_pq(false)
|
using_pq(false),
|
||||||
|
sort_positions(sort_positions_arg)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(order);
|
DBUG_ASSERT(order);
|
||||||
};
|
};
|
||||||
@@ -143,12 +152,10 @@ public:
|
|||||||
{ return filesort_buffer.sort_buffer_size(); }
|
{ return filesort_buffer.sort_buffer_size(); }
|
||||||
|
|
||||||
friend SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
friend SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
||||||
bool sort_positions,
|
|
||||||
Filesort_tracker* tracker);
|
Filesort_tracker* tracker);
|
||||||
};
|
};
|
||||||
|
|
||||||
SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
||||||
bool sort_positions,
|
|
||||||
Filesort_tracker* tracker);
|
Filesort_tracker* tracker);
|
||||||
|
|
||||||
void change_double_for_sort(double nr,uchar *to);
|
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);
|
DBUG_ASSERT(query_plan.index == MAX_KEY);
|
||||||
|
|
||||||
Filesort_tracker *fs_tracker=
|
Filesort_tracker *fs_tracker=
|
||||||
thd->lex->explain->get_upd_del_plan()->filesort_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;
|
goto got_error;
|
||||||
|
|
||||||
thd->inc_examined_row_count(file_sort->examined_rows);
|
thd->inc_examined_row_count(file_sort->examined_rows);
|
||||||
|
@@ -2814,7 +2814,9 @@ JOIN::optimize_distinct()
|
|||||||
bool
|
bool
|
||||||
JOIN::add_sorting_to_table(JOIN_TAB *tab, ORDER *order)
|
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)
|
if (!tab->filesort)
|
||||||
return true;
|
return true;
|
||||||
/*
|
/*
|
||||||
@@ -21279,7 +21281,7 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort)
|
|||||||
|
|
||||||
if (table->s->tmp_table)
|
if (table->s->tmp_table)
|
||||||
table->file->info(HA_STATUS_VARIABLE); // Get record count
|
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);
|
DBUG_ASSERT(tab->filesort_result == 0);
|
||||||
tab->filesort_result= file_sort;
|
tab->filesort_result= file_sort;
|
||||||
tab->records= 0;
|
tab->records= 0;
|
||||||
|
@@ -9447,13 +9447,14 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
|||||||
|
|
||||||
THD_STAGE_INFO(thd, stage_sorting);
|
THD_STAGE_INFO(thd, stage_sorting);
|
||||||
Filesort_tracker dummy_tracker(false);
|
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) ||
|
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
|
||||||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
|
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
|
||||||
&tables, fields, all_fields, order))
|
&tables, fields, all_fields, order))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (!(file_sort= filesort(thd, from, &fsort, true, &dummy_tracker)))
|
if (!(file_sort= filesort(thd, from, &fsort, &dummy_tracker)))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
thd_progress_next_stage(thd);
|
thd_progress_next_stage(thd);
|
||||||
|
@@ -558,12 +558,12 @@ int mysql_update(THD *thd,
|
|||||||
to update
|
to update
|
||||||
NOTE: filesort will call table->prepare_for_position()
|
NOTE: filesort will call table->prepare_for_position()
|
||||||
*/
|
*/
|
||||||
Filesort fsort(order, limit, select);
|
Filesort fsort(order, limit, true, select);
|
||||||
|
|
||||||
Filesort_tracker *fs_tracker=
|
Filesort_tracker *fs_tracker=
|
||||||
thd->lex->explain->get_upd_del_plan()->filesort_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;
|
goto err;
|
||||||
thd->inc_examined_row_count(file_sort->examined_rows);
|
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,
|
ORDER* sort_order= concat_order_lists(thd->mem_root,
|
||||||
spec->partition_list->first,
|
spec->partition_list->first,
|
||||||
spec->order_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. */
|
/* Apply the same condition that the subsequent sort has. */
|
||||||
filesort->select= sel;
|
filesort->select= sel;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user