diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 59ff6abdde2..f8629e578f0 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1694,3 +1694,21 @@ col1 col2 col2 col3 5 david NULL NULL DROP VIEW v1,v2,v3; DROP TABLE t1,t2; +create table t1 as select 1 A union select 2 union select 3; +create table t2 as select * from t1; +create view v1 as select * from t1 where a in (select * from t2); +select * from v1 A, v1 B where A.a = B.a; +A A +1 1 +2 2 +3 3 +create table t3 as select a a,a b from t2; +create view v2 as select * from t3 where +a in (select * from t1) or b in (select * from t2); +select * from v2 A, v2 B where A.a = B.b; +a b a b +1 1 1 1 +2 2 2 2 +3 3 3 3 +drop view v1, v2; +drop table t1, t2, t3; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 0c3c81d0b89..0303605a9ef 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1519,3 +1519,17 @@ SELECT a.col1,a.col2,b.col2,b.col3 DROP VIEW v1,v2,v3; DROP TABLE t1,t2; + +# BUG#8490 Select from views containing subqueries causes server to hang +# forever. +create table t1 as select 1 A union select 2 union select 3; +create table t2 as select * from t1; +create view v1 as select * from t1 where a in (select * from t2); +select * from v1 A, v1 B where A.a = B.a; +create table t3 as select a a,a b from t2; +create view v2 as select * from t3 where + a in (select * from t1) or b in (select * from t2); +select * from v2 A, v2 B where A.a = B.b; +drop view v1, v2; +drop table t1, t2, t3; + diff --git a/sql/sql_view.cc b/sql/sql_view.cc index be643c36d7d..21de99f2484 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -796,17 +796,25 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) /* Store WHERE clause for post-processing in setup_ancestor */ table->where= view_select->where; - /* - Add subqueries units to SELECT in which we merging current view. - + Add subqueries units to SELECT into which we merging current view. + + unit(->next)* chain starts with subqueries that are used by this + view and continues with subqueries that are used by other views. + We must not add any subquery twice (otherwise we'll form a loop), + to do this we remember in end_unit the first subquery that has + been already added. + NOTE: we do not support UNION here, so we take only one select */ + SELECT_LEX_NODE *end_unit= table->select_lex->slave; for (SELECT_LEX_UNIT *unit= lex->select_lex.first_inner_unit(); unit; unit= unit->next_unit()) { SELECT_LEX_NODE *save_slave= unit->slave; + if (unit == end_unit) + break; unit->include_down(table->select_lex); unit->slave= save_slave; // fix include_down initialisation }