mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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).
This commit is contained in:
committed by
Oleksandr Byelkin
parent
6fe882cd85
commit
ea270178b0
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
|
||||
|
||||
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 @@ public:
|
||||
{
|
||||
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 +
|
||||
|
Reference in New Issue
Block a user