Skip to content

Commit 4872ec6

Browse files
committed
Fixed bug mdev-10874.
In some cases the method Window_funcs_sort::setup() did not build the sequence of sorting keys correctly.
1 parent 78f5879 commit 4872ec6

File tree

3 files changed

+151
-6
lines changed

3 files changed

+151
-6
lines changed

mysql-test/r/win.result

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,3 +2054,91 @@ pk r_desc r_asc
20542054
10 2 10
20552055
11 1 11
20562056
drop table t1;
2057+
#
2058+
# MDEV-10874: two window functions with ccompatible sorting
2059+
#
2060+
create table t1 (
2061+
pk int primary key,
2062+
a int,
2063+
b int,
2064+
c char(10),
2065+
d decimal(10, 3),
2066+
e real
2067+
);
2068+
insert into t1 values
2069+
( 1, 0, 1, 'one', 0.1, 0.001),
2070+
( 2, 0, 2, 'two', 0.2, 0.002),
2071+
( 3, 0, 3, 'three', 0.3, 0.003),
2072+
( 4, 1, 2, 'three', 0.4, 0.004),
2073+
( 5, 1, 1, 'two', 0.5, 0.005),
2074+
( 6, 1, 1, 'one', 0.6, 0.006),
2075+
( 7, 2, NULL, 'n_one', 0.5, 0.007),
2076+
( 8, 2, 1, 'n_two', NULL, 0.008),
2077+
( 9, 2, 2, NULL, 0.7, 0.009),
2078+
(10, 2, 0, 'n_four', 0.8, 0.010),
2079+
(11, 2, 10, NULL, 0.9, NULL);
2080+
select pk, a, d,
2081+
sum(d) over (partition by a order by pk
2082+
ROWS between 1 preceding and current row) as sum_1,
2083+
sum(d) over (order by a
2084+
ROWS BETWEEN 1 preceding and 2 following) as sum_2
2085+
from t1;
2086+
pk a d sum_1 sum_2
2087+
1 0 0.100 0.100 0.600
2088+
2 0 0.200 0.300 1.000
2089+
3 0 0.300 0.500 1.400
2090+
4 1 0.400 0.400 1.800
2091+
5 1 0.500 0.900 2.000
2092+
6 1 0.600 1.100 1.600
2093+
7 2 0.500 0.500 1.800
2094+
8 2 NULL 0.500 2.000
2095+
9 2 0.700 0.700 2.400
2096+
10 2 0.800 1.500 2.400
2097+
11 2 0.900 1.700 1.700
2098+
explain format=json
2099+
select pk, a, d,
2100+
sum(d) over (partition by a order by pk
2101+
ROWS between 1 preceding and current row) as sum_1,
2102+
sum(d) over (order by a
2103+
ROWS BETWEEN 1 preceding and 2 following) as sum_2
2104+
from t1;
2105+
EXPLAIN
2106+
{
2107+
"query_block": {
2108+
"select_id": 1,
2109+
"window_functions_computation": {
2110+
"sorts": {
2111+
"filesort": {
2112+
"sort_key": "t1.a, t1.pk"
2113+
}
2114+
},
2115+
"temporary_table": {
2116+
"table": {
2117+
"table_name": "t1",
2118+
"access_type": "ALL",
2119+
"rows": 11,
2120+
"filtered": 100
2121+
}
2122+
}
2123+
}
2124+
}
2125+
}
2126+
select pk, a, d,
2127+
sum(d) over (partition by a order by pk desc
2128+
ROWS between 1 preceding and current row) as sum_1,
2129+
sum(d) over (order by a
2130+
ROWS BETWEEN 1 preceding and 2 following) as sum_2
2131+
from t1;
2132+
pk a d sum_1 sum_2
2133+
1 0 0.100 0.300 1.400
2134+
2 0 0.200 0.500 1.200
2135+
3 0 0.300 0.300 0.600
2136+
4 1 0.400 0.900 2.600
2137+
5 1 0.500 1.100 2.400
2138+
6 1 0.600 0.600 1.600
2139+
7 2 0.500 0.500 0.500
2140+
8 2 NULL 0.700 1.200
2141+
9 2 0.700 1.500 2.000
2142+
10 2 0.800 1.700 2.400
2143+
11 2 0.900 0.900 2.800
2144+
drop table t1;

mysql-test/t/win.test

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,3 +1262,51 @@ select pk,
12621262
from t1;
12631263

12641264
drop table t1;
1265+
1266+
--echo #
1267+
--echo # MDEV-10874: two window functions with ccompatible sorting
1268+
--echo #
1269+
1270+
create table t1 (
1271+
pk int primary key,
1272+
a int,
1273+
b int,
1274+
c char(10),
1275+
d decimal(10, 3),
1276+
e real
1277+
);
1278+
insert into t1 values
1279+
( 1, 0, 1, 'one', 0.1, 0.001),
1280+
( 2, 0, 2, 'two', 0.2, 0.002),
1281+
( 3, 0, 3, 'three', 0.3, 0.003),
1282+
( 4, 1, 2, 'three', 0.4, 0.004),
1283+
( 5, 1, 1, 'two', 0.5, 0.005),
1284+
( 6, 1, 1, 'one', 0.6, 0.006),
1285+
( 7, 2, NULL, 'n_one', 0.5, 0.007),
1286+
( 8, 2, 1, 'n_two', NULL, 0.008),
1287+
( 9, 2, 2, NULL, 0.7, 0.009),
1288+
(10, 2, 0, 'n_four', 0.8, 0.010),
1289+
(11, 2, 10, NULL, 0.9, NULL);
1290+
1291+
select pk, a, d,
1292+
sum(d) over (partition by a order by pk
1293+
ROWS between 1 preceding and current row) as sum_1,
1294+
sum(d) over (order by a
1295+
ROWS BETWEEN 1 preceding and 2 following) as sum_2
1296+
from t1;
1297+
explain format=json
1298+
select pk, a, d,
1299+
sum(d) over (partition by a order by pk
1300+
ROWS between 1 preceding and current row) as sum_1,
1301+
sum(d) over (order by a
1302+
ROWS BETWEEN 1 preceding and 2 following) as sum_2
1303+
from t1;
1304+
1305+
select pk, a, d,
1306+
sum(d) over (partition by a order by pk desc
1307+
ROWS between 1 preceding and current row) as sum_1,
1308+
sum(d) over (order by a
1309+
ROWS BETWEEN 1 preceding and 2 following) as sum_2
1310+
from t1;
1311+
1312+
drop table t1;

sql/sql_window.cc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,19 +2391,28 @@ bool Window_funcs_sort::exec(JOIN *join)
23912391
bool Window_funcs_sort::setup(THD *thd, SQL_SELECT *sel,
23922392
List_iterator<Item_window_func> &it)
23932393
{
2394-
Item_window_func *win_func= it.peek();
2395-
Item_window_func *prev_win_func;
2394+
Window_spec *spec;
2395+
Item_window_func *win_func= it.peek();
2396+
Item_window_func *win_func_with_longest_order= NULL;
2397+
uint longest_order_elements= 0;
23962398

23972399
/* The iterator should point to a valid function at the start of execution. */
23982400
DBUG_ASSERT(win_func);
23992401
do
24002402
{
2403+
spec= win_func->window_spec;
2404+
uint win_func_order_elements= spec->partition_list->elements +
2405+
spec->order_list->elements;
2406+
if (win_func_order_elements > longest_order_elements)
2407+
{
2408+
win_func_with_longest_order= win_func;
2409+
longest_order_elements= win_func_order_elements;
2410+
}
24012411
if (runner.add_function_to_run(win_func))
24022412
return true;
24032413
it++;
2404-
prev_win_func= win_func;
2405-
} while ((win_func= it.peek()) &&
2406-
!(win_func->marker & SORTORDER_CHANGE_FLAG));
2414+
win_func= it.peek();
2415+
} while (win_func && !(win_func->marker & SORTORDER_CHANGE_FLAG));
24072416

24082417
/*
24092418
The sort criteria must be taken from the last win_func in the group of
@@ -2413,7 +2422,7 @@ bool Window_funcs_sort::setup(THD *thd, SQL_SELECT *sel,
24132422
in a way that the result is valid for all window functions belonging to
24142423
this Window_funcs_sort.
24152424
*/
2416-
Window_spec *spec= prev_win_func->window_spec;
2425+
spec= win_func_with_longest_order->window_spec;
24172426

24182427
ORDER* sort_order= concat_order_lists(thd->mem_root,
24192428
spec->partition_list->first,

0 commit comments

Comments
 (0)