Commit ea270178 authored by Igor Babaev's avatar Igor Babaev Committed by Oleksandr Byelkin

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).
parent 6fe882cd
......@@ -24,3 +24,66 @@ pk count(a) over (order by pk rows between 2 preceding and 2 following)
28 5
27 5
drop table t0,t1;
#
# MDEV-30052: Crash with a query containing nested WINDOW clauses
#
CREATE TABLE t1 (c INT);
insert into t1 values (1),(2);
UPDATE t1 SET c=1
WHERE c=2
ORDER BY
(1 IN ((
SELECT *
FROM (SELECT * FROM t1) AS v1
GROUP BY c
WINDOW v2 AS (ORDER BY
(SELECT *
FROM t1
GROUP BY c
WINDOW v3 AS (PARTITION BY c)
)
)
))
);
drop table t1;
#
# MDEV-29359: Server crashed with heap-use-after-free in
# Field::is_null(long long) const (Just testcase)
#
CREATE TABLE t1 (id int);
INSERT INTO t1 VALUES (-1),(0),(84);
SELECT
id IN (SELECT id
FROM t1
WINDOW w AS (ORDER BY (SELECT 1
FROM t1
WHERE
EXISTS ( SELECT id
FROM t1
GROUP BY id
WINDOW w2 AS (ORDER BY id)
)
)
)
)
FROM t1;
id IN (SELECT id
FROM t1
WINDOW w AS (ORDER BY (SELECT 1
FROM t1
WHERE
EXISTS ( SELECT id
FROM t1
GROUP BY id
WINDOW w2 AS (ORDER BY id)
)
)
)
)
1
1
1
DROP TABLE t1;
#
# End of 10.3 tests
#
......@@ -33,3 +33,58 @@ limit 4;
--disable_view_protocol
drop table t0,t1;
--echo #
--echo # MDEV-30052: Crash with a query containing nested WINDOW clauses
--echo #
CREATE TABLE t1 (c INT);
insert into t1 values (1),(2);
UPDATE t1 SET c=1
WHERE c=2
ORDER BY
(1 IN ((
SELECT *
FROM (SELECT * FROM t1) AS v1
GROUP BY c
WINDOW v2 AS (ORDER BY
(SELECT *
FROM t1
GROUP BY c
WINDOW v3 AS (PARTITION BY c)
)
)
))
);
drop table t1;
--echo #
--echo # MDEV-29359: Server crashed with heap-use-after-free in
--echo # Field::is_null(long long) const (Just testcase)
--echo #
CREATE TABLE t1 (id int);
INSERT INTO t1 VALUES (-1),(0),(84);
SELECT
id IN (SELECT id
FROM t1
WINDOW w AS (ORDER BY (SELECT 1
FROM t1
WHERE
EXISTS ( SELECT id
FROM t1
GROUP BY id
WINDOW w2 AS (ORDER BY id)
)
)
)
)
FROM t1;
DROP TABLE t1;
--echo #
--echo # End of 10.3 tests
--echo #
......@@ -755,8 +755,6 @@ void LEX::start(THD *thd_arg)
stmt_var_list.empty();
proc_list.elements=0;
save_group_list.empty();
save_order_list.empty();
win_ref= NULL;
win_frame= NULL;
frame_top_bound= NULL;
......@@ -2389,9 +2387,8 @@ void st_select_lex::init_select()
ftfunc_list_alloc.empty();
inner_sum_func_list= 0;
ftfunc_list= &ftfunc_list_alloc;
order_list.elements= 0;
order_list.first= 0;
order_list.next= &order_list.first;
order_list.empty();
/* Set limit and offset to default values */
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
offset_limit= 0; /* denotes the default offset = 0 */
......
......@@ -975,6 +975,7 @@ class st_select_lex: public st_select_lex_node
group_list_ptrs, and re-establish the original list before each execution.
*/
SQL_I_List<ORDER> group_list;
SQL_I_List<ORDER> save_group_list;
Group_list_ptrs *group_list_ptrs;
List<Item> item_list; /* list of fields & expressions */
......@@ -1040,6 +1041,7 @@ class st_select_lex: public st_select_lex_node
const char *type; /* type of select for EXPLAIN */
SQL_I_List<ORDER> order_list; /* ORDER clause */
SQL_I_List<ORDER> save_order_list;
SQL_I_List<ORDER> gorder_list;
Item *select_limit, *offset_limit; /* LIMIT clause parameters */
......@@ -1249,9 +1251,7 @@ class st_select_lex: public st_select_lex_node
void set_lock_for_tables(thr_lock_type lock_type, bool for_update);
inline void init_order()
{
order_list.elements= 0;
order_list.first= 0;
order_list.next= &order_list.first;
order_list.empty();
}
/*
This method created for reiniting LEX in mysql_admin_table() and can be
......@@ -3215,8 +3215,6 @@ struct LEX: public Query_tables_list
}
SQL_I_List<ORDER> save_group_list;
SQL_I_List<ORDER> save_order_list;
LEX_CSTRING *win_ref;
Window_frame *win_frame;
Window_frame_bound *frame_top_bound;
......
......@@ -53,7 +53,7 @@ class SQL_I_List :public Sql_alloc
{
elements= tmp.elements;
first= tmp.first;
next= tmp.next;
next= elements ? tmp.next : &first;;
return *this;
}
......
......@@ -8662,8 +8662,8 @@ TABLE_LIST *st_select_lex::convert_right_join()
void st_select_lex::prepare_add_window_spec(THD *thd)
{
LEX *lex= thd->lex;
lex->save_group_list= group_list;
lex->save_order_list= order_list;
save_group_list= group_list;
save_order_list= order_list;
lex->win_ref= NULL;
lex->win_frame= NULL;
lex->frame_top_bound= NULL;
......@@ -8690,8 +8690,8 @@ bool st_select_lex::add_window_def(THD *thd,
win_part_list_ptr,
win_order_list_ptr,
win_frame);
group_list= thd->lex->save_group_list;
order_list= thd->lex->save_order_list;
group_list= save_group_list;
order_list= save_order_list;
if (parsing_place != SELECT_LIST)
{
fields_in_window_functions+= win_part_list_ptr->elements +
......@@ -8717,8 +8717,8 @@ bool st_select_lex::add_window_spec(THD *thd,
win_part_list_ptr,
win_order_list_ptr,
win_frame);
group_list= thd->lex->save_group_list;
order_list= thd->lex->save_order_list;
group_list= save_group_list;
order_list= save_order_list;
if (parsing_place != SELECT_LIST)
{
fields_in_window_functions+= win_part_list_ptr->elements +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment