Skip to content

Commit 28cdbab

Browse files
MDEV-29681 Server crashes when optimizing SQL with ORDER BY
When parsing statements like (SELECT .. FROM ..) ORDER BY <expr>, there is a step LEX::add_tail_to_query_expression_body_ext_parens() which calls LEX::wrap_unit_into_derived(). After that the statement looks like SELECT * FROM (SELECT .. FROM ..), and parser's Lex_order_limit_lock structure (ORDER BY <expr>) is assigned to the new SELECT. But what is missing here is that Items in Lex_order_limit_lock are left with their original name resolution contexts, and fix_fields() later resolves the names incorrectly. For example, when processing (SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a Item_field 'a' in the ORDER BY clause is left with the name resolution context of the derived table (first_name_resolution_table='t1'), so it is resolved to 't1.a', which is incorrect. After LEX::wrap_unit_into_derived() the statement looks like SELECT * FROM (SELECT * FROM t1 JOIN t2 ON a=b) AS '__2' ORDER BY a, and the name resolution context for Item_field 'a' in the ORDER BY must be set to the wrapping SELECT's one. This commit fixes the issue by changing context for Items in Lex_order_limit_lock after LEX::wrap_unit_into_derived().
1 parent f755231 commit 28cdbab

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

mysql-test/main/order_by.result

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3725,4 +3725,124 @@ id select_type table type possible_keys key key_len ref rows Extra
37253725
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
37263726
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.t2.b 1 Using where
37273727
DROP TABLE t1,t2;
3728+
#
3729+
# MDEV-29681 Server crashes when optimizing SQL with ORDER BY
3730+
#
3731+
CREATE TABLE t1 (b INT);
3732+
CREATE TABLE t2 (a INT, c INT);
3733+
# First test empty tables
3734+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a+1;
3735+
id select_type table type possible_keys key key_len ref rows filtered Extra
3736+
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 Const row not found
3737+
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3738+
Warnings:
3739+
Note 1003 /* select#1 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from ((/* select#2 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from `test`.`t1` join `test`.`t2` where 0 limit 3)) `__2` order by NULL + 1
3740+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=2;
3741+
id select_type table type possible_keys key key_len ref rows filtered Extra
3742+
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 Const row not found
3743+
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3744+
Warnings:
3745+
Note 1003 /* select#1 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from ((/* select#2 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from `test`.`t1` join `test`.`t2` where 0 limit 3)) `__2` order by NULL = 2
3746+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3)
3747+
ORDER BY a+1, a-b DESC, c<>a;
3748+
id select_type table type possible_keys key key_len ref rows filtered Extra
3749+
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 Const row not found
3750+
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3751+
Warnings:
3752+
Note 1003 /* select#1 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from ((/* select#2 */ select NULL AS `b`,NULL AS `a`,NULL AS `c` from `test`.`t1` join `test`.`t2` where 0 limit 3)) `__2` order by NULL + 1,NULL - NULL desc,NULL <> NULL
3753+
# Insert some data
3754+
INSERT INTO t1 VALUES (1),(2),(3),(4);
3755+
INSERT INTO t2 VALUES (1,1),(2,2),(3,3),(4,4);
3756+
(SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=b, a-10 DESC, b+a, c+a+a+b;
3757+
b a c
3758+
1 1 1
3759+
2 2 2
3760+
3 3 3
3761+
(SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=2;
3762+
b a c
3763+
1 1 1
3764+
2 2 2
3765+
3 3 3
3766+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3)
3767+
ORDER BY a=b, a-10, b+a, c+a+a+b;
3768+
id select_type table type possible_keys key key_len ref rows filtered Extra
3769+
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 100.00 Using filesort
3770+
2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00
3771+
2 DERIVED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
3772+
Warnings:
3773+
Note 1003 /* select#1 */ select `__2`.`b` AS `b`,`__2`.`a` AS `a`,`__2`.`c` AS `c` from ((/* select#2 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` limit 3)) `__2` order by `__2`.`a` = `__2`.`b`,`__2`.`a` - 10,`__2`.`b` + `__2`.`a`,`__2`.`c` + `__2`.`a` + `__2`.`a` + `__2`.`b`
3774+
# When there is no LIMIT clause the derived table must be merged
3775+
(SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a+16, b+a, c<>b;
3776+
b a c
3777+
1 1 1
3778+
2 2 2
3779+
3 3 3
3780+
4 4 4
3781+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a+16 DESC, b+a, c<>b;
3782+
id select_type table type possible_keys key key_len ref rows filtered Extra
3783+
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort
3784+
1 SIMPLE t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
3785+
Warnings:
3786+
Note 1003 (select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` order by `test`.`t2`.`a` + 16 desc,`test`.`t1`.`b` + `test`.`t2`.`a`,`test`.`t2`.`c` <> `test`.`t1`.`b`)
3787+
# Test UNIONs:
3788+
(SELECT * FROM t1 JOIN t2 ON a=b UNION
3789+
SELECT * FROM t1 JOIN t2 ON a!=b
3790+
LIMIT 3)
3791+
ORDER BY a+16, b+a, c<>b;
3792+
b a c
3793+
1 1 1
3794+
2 2 2
3795+
3 3 3
3796+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION
3797+
SELECT * FROM t1 JOIN t2 ON a!=b
3798+
LIMIT 3)
3799+
ORDER BY a+16, b+a, c<>b;
3800+
id select_type table type possible_keys key key_len ref rows filtered Extra
3801+
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 32 100.00 Using filesort
3802+
2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00
3803+
2 DERIVED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
3804+
3 UNION t1 ALL NULL NULL NULL NULL 4 100.00
3805+
3 UNION t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
3806+
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
3807+
Warnings:
3808+
Note 1003 /* select#1 */ select `__3`.`b` AS `b`,`__3`.`a` AS `a`,`__3`.`c` AS `c` from (/* select#2 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` union /* select#3 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` <> `test`.`t1`.`b` limit 3) `__3` order by `__3`.`a` + 16,`__3`.`b` + `__3`.`a`,`__3`.`c` <> `__3`.`b`
3809+
(SELECT * FROM t1 JOIN t2 ON a=b UNION
3810+
SELECT NULL, NULL, NULL
3811+
LIMIT 3)
3812+
ORDER BY b-a-c;
3813+
b a c
3814+
1 1 1
3815+
2 2 2
3816+
3 3 3
3817+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION
3818+
SELECT NULL, NULL, NULL
3819+
LIMIT 3)
3820+
ORDER BY b-a-c;
3821+
id select_type table type possible_keys key key_len ref rows filtered Extra
3822+
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 16 100.00 Using filesort
3823+
2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00
3824+
2 DERIVED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
3825+
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
3826+
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
3827+
Warnings:
3828+
Note 1003 /* select#1 */ select `__3`.`b` AS `b`,`__3`.`a` AS `a`,`__3`.`c` AS `c` from (/* select#2 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` union /* select#3 */ select NULL AS `NULL`,NULL AS `NULL`,NULL AS `NULL` limit 3) `__3` order by `__3`.`b` - `__3`.`a` - `__3`.`c`
3829+
(SELECT * FROM t1 JOIN t2 ON a=b UNION
3830+
SELECT NULL, NULL, NULL
3831+
ORDER BY a LIMIT 3)
3832+
ORDER BY b-a-c LIMIT 1;
3833+
b a c
3834+
NULL NULL NULL
3835+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION
3836+
SELECT NULL, NULL, NULL
3837+
ORDER BY a LIMIT 3)
3838+
ORDER BY b-a-c LIMIT 1;
3839+
id select_type table type possible_keys key key_len ref rows filtered Extra
3840+
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 16 100.00 Using filesort
3841+
2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00
3842+
2 DERIVED t2 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
3843+
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
3844+
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL Using filesort
3845+
Warnings:
3846+
Note 1003 /* select#1 */ select `__3`.`b` AS `b`,`__3`.`a` AS `a`,`__3`.`c` AS `c` from (/* select#2 */ select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`b` union /* select#3 */ select NULL AS `NULL`,NULL AS `NULL`,NULL AS `NULL` order by `a` limit 3) `__3` order by `__3`.`b` - `__3`.`a` - `__3`.`c` limit 1
3847+
DROP TABLE t1, t2;
37283848
# End of 10.4 tests

mysql-test/main/order_by.test

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,4 +2468,63 @@ EXPLAIN SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FRO
24682468

24692469
DROP TABLE t1,t2;
24702470

2471+
--echo #
2472+
--echo # MDEV-29681 Server crashes when optimizing SQL with ORDER BY
2473+
--echo #
2474+
CREATE TABLE t1 (b INT);
2475+
CREATE TABLE t2 (a INT, c INT);
2476+
2477+
--echo # First test empty tables
2478+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a+1;
2479+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=2;
2480+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3)
2481+
ORDER BY a+1, a-b DESC, c<>a;
2482+
2483+
--echo # Insert some data
2484+
INSERT INTO t1 VALUES (1),(2),(3),(4);
2485+
INSERT INTO t2 VALUES (1,1),(2,2),(3,3),(4,4);
2486+
2487+
--sorted_result
2488+
(SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=b, a-10 DESC, b+a, c+a+a+b;
2489+
--sorted_result
2490+
(SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3) ORDER BY a=2;
2491+
2492+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b LIMIT 3)
2493+
ORDER BY a=b, a-10, b+a, c+a+a+b;
2494+
2495+
--echo # When there is no LIMIT clause the derived table must be merged
2496+
--sorted_result
2497+
(SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a+16, b+a, c<>b;
2498+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a+16 DESC, b+a, c<>b;
2499+
2500+
--echo # Test UNIONs:
2501+
--sorted_result
2502+
(SELECT * FROM t1 JOIN t2 ON a=b UNION
2503+
SELECT * FROM t1 JOIN t2 ON a!=b
2504+
LIMIT 3)
2505+
ORDER BY a+16, b+a, c<>b;
2506+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION
2507+
SELECT * FROM t1 JOIN t2 ON a!=b
2508+
LIMIT 3)
2509+
ORDER BY a+16, b+a, c<>b;
2510+
--sorted_result
2511+
(SELECT * FROM t1 JOIN t2 ON a=b UNION
2512+
SELECT NULL, NULL, NULL
2513+
LIMIT 3)
2514+
ORDER BY b-a-c;
2515+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION
2516+
SELECT NULL, NULL, NULL
2517+
LIMIT 3)
2518+
ORDER BY b-a-c;
2519+
--sorted_result
2520+
(SELECT * FROM t1 JOIN t2 ON a=b UNION
2521+
SELECT NULL, NULL, NULL
2522+
ORDER BY a LIMIT 3)
2523+
ORDER BY b-a-c LIMIT 1;
2524+
EXPLAIN EXTENDED (SELECT * FROM t1 JOIN t2 ON a=b UNION
2525+
SELECT NULL, NULL, NULL
2526+
ORDER BY a LIMIT 3)
2527+
ORDER BY b-a-c LIMIT 1;
2528+
DROP TABLE t1, t2;
2529+
24712530
--echo # End of 10.4 tests

sql/sql_lex.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9414,8 +9414,17 @@ bool Lex_order_limit_lock::set_to(SELECT_LEX *sel)
94149414
"CUBE/ROLLUP", "ORDER BY");
94159415
return TRUE;
94169416
}
9417+
for (ORDER *order= order_list->first; order; order= order->next)
9418+
(*order->item)->walk(&Item::change_context_processor, FALSE,
9419+
&sel->context);
94179420
sel->order_list= *(order_list);
94189421
}
9422+
if (limit.select_limit)
9423+
limit.select_limit->walk(&Item::change_context_processor, FALSE,
9424+
&sel->context);
9425+
if (limit.offset_limit)
9426+
limit.offset_limit->walk(&Item::change_context_processor, FALSE,
9427+
&sel->context);
94199428
sel->is_set_query_expr_tail= true;
94209429
return FALSE;
94219430
}

0 commit comments

Comments
 (0)