Commit 60496497 authored by unknown's avatar unknown
Browse files

Fix for BUG#8490: In mysql_make_view for join algorithm views we need

to insert view's subqueries into select_lex->slave(->next)* chain. 
In case a join has several such views, don't add the same subqueries several times
(this forms a loop on the above chain which breaks many parts of the code)


mysql-test/r/view.result:
  Testcase for BUG#8490
mysql-test/t/view.test:
  Testcase for BUG#8490
parent 241bedad
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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;
+14 −0
Original line number Diff line number Diff line
@@ -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;
+11 −3
Original line number Diff line number Diff line
@@ -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
      }