mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fixed bug#36005: server crashes inside NOT IN clause subquery with
impossible WHERE/HAVING clause (subselect_single_select_engine::exec). Allocation and initialization of joined table list t1, t2... of subqueries like: NOT IN (SELECT ... FROM t1,t2,... WHERE 0) is optimized out, however server tries to traverse this list. mysql-test/r/subselect3.result: Added test case for bug#36005. mysql-test/t/subselect3.test: Added test case for bug#36005. sql/sql_select.cc: Fixed bug#36005. 1. JOIN::prepare initializes JOIN::table counter (actually a size of the JOIN::join_tab array) and sets it to a number of joined tables. 2. The make_join_statistics function (when called from JOIN::optimize) allocates and fills the JOIN::join_tab array. However, when optimizing subselect has impossible (definite false) WHERE or HAVING clause, optimizer skips call to make_join_statistics and leaves JOIN::join_tab == NULL. 3. subselect_single_select_engine::exec does traversal of the JOIN::join_tab array and the server dies because array is not allocated but array counter is greater than 0. The JOIN::optimize method has been modified to reset the JOIN::table counter to 0 in cause of impossible WHERE/HAVING clause.
This commit is contained in:
@ -770,4 +770,13 @@ SELECT ROW(1, 2) IN (SELECT t1.a, 2 FROM t2) FROM t1 GROUP BY t1.a;
|
||||
ROW(1, 2) IN (SELECT t1.a, 2 FROM t2)
|
||||
1
|
||||
DROP TABLE t1, t2;
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
DROP TABLE t1, t2;
|
||||
End of 5.0 tests
|
||||
|
@ -605,4 +605,17 @@ SELECT ROW(1, 2) IN (SELECT t1.a, 2 FROM t2) FROM t1 GROUP BY t1.a;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
#
|
||||
# Bug #36005: crash in subselect with single row
|
||||
# (subselect_single_select_engine::exec)
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
|
||||
SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -832,6 +832,7 @@ JOIN::optimize()
|
||||
"Impossible HAVING" : "Impossible WHERE"));
|
||||
zero_result_cause= having_value == Item::COND_FALSE ?
|
||||
"Impossible HAVING" : "Impossible WHERE";
|
||||
tables= 0;
|
||||
error= 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user