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
|
28 5
|
||||||
27 5
|
27 5
|
||||||
drop table t0,t1;
|
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
|
--disable_view_protocol
|
||||||
|
|
||||||
drop table t0,t1;
|
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();
|
stmt_var_list.empty();
|
||||||
proc_list.elements=0;
|
proc_list.elements=0;
|
||||||
|
|
||||||
save_group_list.empty();
|
|
||||||
save_order_list.empty();
|
|
||||||
win_ref= NULL;
|
win_ref= NULL;
|
||||||
win_frame= NULL;
|
win_frame= NULL;
|
||||||
frame_top_bound= NULL;
|
frame_top_bound= NULL;
|
||||||
@ -2389,9 +2387,8 @@ void st_select_lex::init_select()
|
|||||||
ftfunc_list_alloc.empty();
|
ftfunc_list_alloc.empty();
|
||||||
inner_sum_func_list= 0;
|
inner_sum_func_list= 0;
|
||||||
ftfunc_list= &ftfunc_list_alloc;
|
ftfunc_list= &ftfunc_list_alloc;
|
||||||
order_list.elements= 0;
|
order_list.empty();
|
||||||
order_list.first= 0;
|
|
||||||
order_list.next= &order_list.first;
|
|
||||||
/* Set limit and offset to default values */
|
/* Set limit and offset to default values */
|
||||||
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
|
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
|
||||||
offset_limit= 0; /* denotes the default offset = 0 */
|
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.
|
group_list_ptrs, and re-establish the original list before each execution.
|
||||||
*/
|
*/
|
||||||
SQL_I_List<ORDER> group_list;
|
SQL_I_List<ORDER> group_list;
|
||||||
|
SQL_I_List<ORDER> save_group_list;
|
||||||
Group_list_ptrs *group_list_ptrs;
|
Group_list_ptrs *group_list_ptrs;
|
||||||
|
|
||||||
List<Item> item_list; /* list of fields & expressions */
|
List<Item> item_list; /* list of fields & expressions */
|
||||||
@ -1040,6 +1041,7 @@ public:
|
|||||||
const char *type; /* type of select for EXPLAIN */
|
const char *type; /* type of select for EXPLAIN */
|
||||||
|
|
||||||
SQL_I_List<ORDER> order_list; /* ORDER clause */
|
SQL_I_List<ORDER> order_list; /* ORDER clause */
|
||||||
|
SQL_I_List<ORDER> save_order_list;
|
||||||
SQL_I_List<ORDER> gorder_list;
|
SQL_I_List<ORDER> gorder_list;
|
||||||
Item *select_limit, *offset_limit; /* LIMIT clause parameters */
|
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);
|
void set_lock_for_tables(thr_lock_type lock_type, bool for_update);
|
||||||
inline void init_order()
|
inline void init_order()
|
||||||
{
|
{
|
||||||
order_list.elements= 0;
|
order_list.empty();
|
||||||
order_list.first= 0;
|
|
||||||
order_list.next= &order_list.first;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
This method created for reiniting LEX in mysql_admin_table() and can be
|
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;
|
LEX_CSTRING *win_ref;
|
||||||
Window_frame *win_frame;
|
Window_frame *win_frame;
|
||||||
Window_frame_bound *frame_top_bound;
|
Window_frame_bound *frame_top_bound;
|
||||||
|
@ -53,7 +53,7 @@ public:
|
|||||||
{
|
{
|
||||||
elements= tmp.elements;
|
elements= tmp.elements;
|
||||||
first= tmp.first;
|
first= tmp.first;
|
||||||
next= tmp.next;
|
next= elements ? tmp.next : &first;;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8662,8 +8662,8 @@ TABLE_LIST *st_select_lex::convert_right_join()
|
|||||||
void st_select_lex::prepare_add_window_spec(THD *thd)
|
void st_select_lex::prepare_add_window_spec(THD *thd)
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
lex->save_group_list= group_list;
|
save_group_list= group_list;
|
||||||
lex->save_order_list= order_list;
|
save_order_list= order_list;
|
||||||
lex->win_ref= NULL;
|
lex->win_ref= NULL;
|
||||||
lex->win_frame= NULL;
|
lex->win_frame= NULL;
|
||||||
lex->frame_top_bound= NULL;
|
lex->frame_top_bound= NULL;
|
||||||
@ -8690,8 +8690,8 @@ bool st_select_lex::add_window_def(THD *thd,
|
|||||||
win_part_list_ptr,
|
win_part_list_ptr,
|
||||||
win_order_list_ptr,
|
win_order_list_ptr,
|
||||||
win_frame);
|
win_frame);
|
||||||
group_list= thd->lex->save_group_list;
|
group_list= save_group_list;
|
||||||
order_list= thd->lex->save_order_list;
|
order_list= save_order_list;
|
||||||
if (parsing_place != SELECT_LIST)
|
if (parsing_place != SELECT_LIST)
|
||||||
{
|
{
|
||||||
fields_in_window_functions+= win_part_list_ptr->elements +
|
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_part_list_ptr,
|
||||||
win_order_list_ptr,
|
win_order_list_ptr,
|
||||||
win_frame);
|
win_frame);
|
||||||
group_list= thd->lex->save_group_list;
|
group_list= save_group_list;
|
||||||
order_list= thd->lex->save_order_list;
|
order_list= save_order_list;
|
||||||
if (parsing_place != SELECT_LIST)
|
if (parsing_place != SELECT_LIST)
|
||||||
{
|
{
|
||||||
fields_in_window_functions+= win_part_list_ptr->elements +
|
fields_in_window_functions+= win_part_list_ptr->elements +
|
||||||
|
Reference in New Issue
Block a user