1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Window functions: make "ORDER BY window_func" work

- When window functions are present, JOIN::simple_order should be set
  to FALSE. (Otherwise, the optimizer may attempt to do a "pre-sorting"
  on the first join_tab. Which can work in some cases, but generally
  isn't)

- filesort tries to only read table fields that it requires. Window
  function requires its temp.table field.  In order to pass this info
  to filesort, added an implementation of Item_window_func::
  register_field_in_read_map.
This commit is contained in:
Sergei Petrunia
2016-04-08 03:21:25 +03:00
parent 59e5f5b47e
commit cb002d3479
4 changed files with 82 additions and 0 deletions

View File

@ -1767,3 +1767,48 @@ rank() over (order by a)
10 10
set big_tables=@tmp; set big_tables=@tmp;
drop table t1; drop table t1;
#
# Check if "ORDER BY window_func" works
#
create table t1 (s1 int, s2 char(5));
insert into t1 values (1,'a');
insert into t1 values (null,null);
insert into t1 values (1,null);
insert into t1 values (null,'a');
insert into t1 values (2,'b');
insert into t1 values (-1,'');
explain format=json
select *, row_number() over (order by s1) as X from t1 order by X desc;
EXPLAIN
{
"query_block": {
"select_id": 1,
"filesort": {
"sort_key": "X",
"window_functions_computation": {
"sorts": {
"filesort": {
"sort_key": "t1.s1"
}
},
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 6,
"filtered": 100
}
}
}
}
}
}
select *, row_number() over (order by s1) as X from t1 order by X desc;
s1 s2 X
2 b 6
1 a 5
1 NULL 4
-1 3
NULL NULL 2
NULL a 1
drop table t1;

View File

@ -1079,3 +1079,20 @@ select rank() over (order by a) from t1;
set big_tables=@tmp; set big_tables=@tmp;
drop table t1; drop table t1;
--echo #
--echo # Check if "ORDER BY window_func" works
--echo #
create table t1 (s1 int, s2 char(5));
insert into t1 values (1,'a');
insert into t1 values (null,null);
insert into t1 values (1,null);
insert into t1 values (null,'a');
insert into t1 values (2,'b');
insert into t1 values (-1,'');
explain format=json
select *, row_number() over (order by s1) as X from t1 order by X desc;
select *, row_number() over (order by s1) as X from t1 order by X desc;
drop table t1;

View File

@ -511,6 +511,25 @@ public:
void update_used_tables(); void update_used_tables();
/*
This is used by filesort to mark the columns it needs to read (because they
participate in the sort criteria and/or row retrieval. Window functions can
only be used in sort criteria).
Sorting by window function value is only done after the window functions
have been computed. In that case, window function will need to read its
temp.table field. In order to allow that, mark that field in the read_set.
*/
bool register_field_in_read_map(uchar *arg)
{
TABLE *table= (TABLE*) arg;
if (result_field && (result_field->table == table || !table))
{
bitmap_set_bit(result_field->table->read_set, result_field->field_index);
}
return 0;
}
bool is_frame_prohibited() const bool is_frame_prohibited() const
{ {
switch (window_func()->sum_func()) { switch (window_func()->sum_func()) {

View File

@ -1846,6 +1846,7 @@ JOIN::optimize_inner()
//TODO this could probably go in test_if_need_tmp_table. //TODO this could probably go in test_if_need_tmp_table.
if (this->select_lex->window_specs.elements > 0) { if (this->select_lex->window_specs.elements > 0) {
need_tmp= TRUE; need_tmp= TRUE;
simple_order= FALSE;
} }
/* /*