Skip to content

Commit ea27017

Browse files
igorbabaevsanja-byelkin
authored andcommitted
MDEV-30052 Crash with a query containing nested WINDOW clauses
Use SELECT_LEX to save lists for ORDER BY and GROUP BY before parsing WINDOW clauses / specifications. This is needed for proper parsing of a nested WINDOW clause when a WINDOW clause is used in a subquery contained in another WINDOW clause. Fix assignment of empty SQL_I_List to another one (in case of empty list next shoud point on first).
1 parent 6fe882c commit ea27017

File tree

6 files changed

+130
-17
lines changed

6 files changed

+130
-17
lines changed

mysql-test/main/win_orderby.result

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,66 @@ pk count(a) over (order by pk rows between 2 preceding and 2 following)
2424
28 5
2525
27 5
2626
drop table t0,t1;
27+
#
28+
# MDEV-30052: Crash with a query containing nested WINDOW clauses
29+
#
30+
CREATE TABLE t1 (c INT);
31+
insert into t1 values (1),(2);
32+
UPDATE t1 SET c=1
33+
WHERE c=2
34+
ORDER BY
35+
(1 IN ((
36+
SELECT *
37+
FROM (SELECT * FROM t1) AS v1
38+
GROUP BY c
39+
WINDOW v2 AS (ORDER BY
40+
(SELECT *
41+
FROM t1
42+
GROUP BY c
43+
WINDOW v3 AS (PARTITION BY c)
44+
)
45+
)
46+
))
47+
);
48+
drop table t1;
49+
#
50+
# MDEV-29359: Server crashed with heap-use-after-free in
51+
# Field::is_null(long long) const (Just testcase)
52+
#
53+
CREATE TABLE t1 (id int);
54+
INSERT INTO t1 VALUES (-1),(0),(84);
55+
SELECT
56+
id IN (SELECT id
57+
FROM t1
58+
WINDOW w AS (ORDER BY (SELECT 1
59+
FROM t1
60+
WHERE
61+
EXISTS ( SELECT id
62+
FROM t1
63+
GROUP BY id
64+
WINDOW w2 AS (ORDER BY id)
65+
)
66+
)
67+
)
68+
)
69+
FROM t1;
70+
id IN (SELECT id
71+
FROM t1
72+
WINDOW w AS (ORDER BY (SELECT 1
73+
FROM t1
74+
WHERE
75+
EXISTS ( SELECT id
76+
FROM t1
77+
GROUP BY id
78+
WINDOW w2 AS (ORDER BY id)
79+
)
80+
)
81+
)
82+
)
83+
1
84+
1
85+
1
86+
DROP TABLE t1;
87+
#
88+
# End of 10.3 tests
89+
#

mysql-test/main/win_orderby.test

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,58 @@ limit 4;
3333
--disable_view_protocol
3434

3535
drop table t0,t1;
36+
37+
38+
--echo #
39+
--echo # MDEV-30052: Crash with a query containing nested WINDOW clauses
40+
--echo #
41+
42+
CREATE TABLE t1 (c INT);
43+
insert into t1 values (1),(2);
44+
UPDATE t1 SET c=1
45+
WHERE c=2
46+
ORDER BY
47+
(1 IN ((
48+
SELECT *
49+
FROM (SELECT * FROM t1) AS v1
50+
GROUP BY c
51+
WINDOW v2 AS (ORDER BY
52+
(SELECT *
53+
FROM t1
54+
GROUP BY c
55+
WINDOW v3 AS (PARTITION BY c)
56+
)
57+
)
58+
))
59+
);
60+
drop table t1;
61+
62+
--echo #
63+
--echo # MDEV-29359: Server crashed with heap-use-after-free in
64+
--echo # Field::is_null(long long) const (Just testcase)
65+
--echo #
66+
67+
CREATE TABLE t1 (id int);
68+
INSERT INTO t1 VALUES (-1),(0),(84);
69+
70+
SELECT
71+
id IN (SELECT id
72+
FROM t1
73+
WINDOW w AS (ORDER BY (SELECT 1
74+
FROM t1
75+
WHERE
76+
EXISTS ( SELECT id
77+
FROM t1
78+
GROUP BY id
79+
WINDOW w2 AS (ORDER BY id)
80+
)
81+
)
82+
)
83+
)
84+
FROM t1;
85+
86+
DROP TABLE t1;
87+
88+
--echo #
89+
--echo # End of 10.3 tests
90+
--echo #

sql/sql_lex.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,8 +755,6 @@ void LEX::start(THD *thd_arg)
755755
stmt_var_list.empty();
756756
proc_list.elements=0;
757757

758-
save_group_list.empty();
759-
save_order_list.empty();
760758
win_ref= NULL;
761759
win_frame= NULL;
762760
frame_top_bound= NULL;
@@ -2389,9 +2387,8 @@ void st_select_lex::init_select()
23892387
ftfunc_list_alloc.empty();
23902388
inner_sum_func_list= 0;
23912389
ftfunc_list= &ftfunc_list_alloc;
2392-
order_list.elements= 0;
2393-
order_list.first= 0;
2394-
order_list.next= &order_list.first;
2390+
order_list.empty();
2391+
23952392
/* Set limit and offset to default values */
23962393
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
23972394
offset_limit= 0; /* denotes the default offset = 0 */

sql/sql_lex.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,7 @@ class st_select_lex: public st_select_lex_node
975975
group_list_ptrs, and re-establish the original list before each execution.
976976
*/
977977
SQL_I_List<ORDER> group_list;
978+
SQL_I_List<ORDER> save_group_list;
978979
Group_list_ptrs *group_list_ptrs;
979980

980981
List<Item> item_list; /* list of fields & expressions */
@@ -1040,6 +1041,7 @@ class st_select_lex: public st_select_lex_node
10401041
const char *type; /* type of select for EXPLAIN */
10411042

10421043
SQL_I_List<ORDER> order_list; /* ORDER clause */
1044+
SQL_I_List<ORDER> save_order_list;
10431045
SQL_I_List<ORDER> gorder_list;
10441046
Item *select_limit, *offset_limit; /* LIMIT clause parameters */
10451047

@@ -1249,9 +1251,7 @@ class st_select_lex: public st_select_lex_node
12491251
void set_lock_for_tables(thr_lock_type lock_type, bool for_update);
12501252
inline void init_order()
12511253
{
1252-
order_list.elements= 0;
1253-
order_list.first= 0;
1254-
order_list.next= &order_list.first;
1254+
order_list.empty();
12551255
}
12561256
/*
12571257
This method created for reiniting LEX in mysql_admin_table() and can be
@@ -3215,8 +3215,6 @@ struct LEX: public Query_tables_list
32153215
}
32163216

32173217

3218-
SQL_I_List<ORDER> save_group_list;
3219-
SQL_I_List<ORDER> save_order_list;
32203218
LEX_CSTRING *win_ref;
32213219
Window_frame *win_frame;
32223220
Window_frame_bound *frame_top_bound;

sql/sql_list.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class SQL_I_List :public Sql_alloc
5353
{
5454
elements= tmp.elements;
5555
first= tmp.first;
56-
next= tmp.next;
56+
next= elements ? tmp.next : &first;;
5757
return *this;
5858
}
5959

sql/sql_parse.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8662,8 +8662,8 @@ TABLE_LIST *st_select_lex::convert_right_join()
86628662
void st_select_lex::prepare_add_window_spec(THD *thd)
86638663
{
86648664
LEX *lex= thd->lex;
8665-
lex->save_group_list= group_list;
8666-
lex->save_order_list= order_list;
8665+
save_group_list= group_list;
8666+
save_order_list= order_list;
86678667
lex->win_ref= NULL;
86688668
lex->win_frame= NULL;
86698669
lex->frame_top_bound= NULL;
@@ -8690,8 +8690,8 @@ bool st_select_lex::add_window_def(THD *thd,
86908690
win_part_list_ptr,
86918691
win_order_list_ptr,
86928692
win_frame);
8693-
group_list= thd->lex->save_group_list;
8694-
order_list= thd->lex->save_order_list;
8693+
group_list= save_group_list;
8694+
order_list= save_order_list;
86958695
if (parsing_place != SELECT_LIST)
86968696
{
86978697
fields_in_window_functions+= win_part_list_ptr->elements +
@@ -8717,8 +8717,8 @@ bool st_select_lex::add_window_spec(THD *thd,
87178717
win_part_list_ptr,
87188718
win_order_list_ptr,
87198719
win_frame);
8720-
group_list= thd->lex->save_group_list;
8721-
order_list= thd->lex->save_order_list;
8720+
group_list= save_group_list;
8721+
order_list= save_order_list;
87228722
if (parsing_place != SELECT_LIST)
87238723
{
87248724
fields_in_window_functions+= win_part_list_ptr->elements +

0 commit comments

Comments
 (0)