let $no_pushdown= set statement optimizer_switch='condition_pushdown_for_derived=off' for; 

create table t1 (a int, b int, c int);
create table t2 (a int, b int, c int, d decimal);
insert into t1 values 
  (1,21,345), (1,33,7), (8,33,114), (1,21,500), (1,19,107), (5,14,787),
  (8,33,123), (9,10,211), (5,16,207), (1,33,988), (5,27,132), (1,21,104),
  (6,20,309), (6,20,315), (1,21,101), (8,33,404), (9,10,800), (1,21,123),
  (7,11,708), (6,20,214);
insert into t2 values
  (2,3,207,207.0000), (1,21,909,12.0000), (7,13,312,406.0000), 
  (8,64,248,107.0000), (6,20,315,279.3333), (1,19,203,107.0000),
  (8,80,800,314.0000), (3,12,231,190.0000), (6,23,303,909.0000);
  
create table t1_double(a int, b double, c double);
insert into t1_double values 
  (1,23.4,14.3333), (1,12.5,18.9), (3,12.5,18.9),
  (4,33.4,14.3333), (4,14.3333,13.65), (5,17.89,7.22),
  (6,33.4,14.3), (10,33.4,13.65), (11,33.4,13.65);
  
create table t2_double(a int, b double, c double);
insert into t2_double values 
  (1,22.4,14.3333), (1,12.5,18.9), (2,22.4,18.9),
  (4,33.4,14.3333), (5,22.4,13.65), (7,17.89,18.9),
  (6,33.4,14.3333), (10,31.4,13.65), (12,33.4,13.65); 
  
create table t1_char(a char, b char(8), c int);
insert into t1_char values
  ('a','Ivan',1), ('b','Vika',2), ('b','Inga',6), ('c','Vika',7),
  ('b','Ivan',7), ('a','Alex',6), ('b','Inga',5), ('d','Ron',9),
  ('d','Harry',2), ('d','Hermione',3), ('c','Ivan',3), ('c','Harry',4); 
  
create table t2_char(a char, b char(8), c int);
insert into t2_char values
  ('b','Ivan',1), ('c','Vinny',3), ('c','Inga',9), ('a','Vika',1),
  ('c','Ivan',2), ('b','Ali',6), ('c','Inga',2), ('a','Ron',9),
  ('d','Harry',1), ('b','Hermes',3), ('b','Ivan',11), ('b','Harry',4);
  
create table t1_decimal (a decimal(3,1), b decimal(3,1), c int);
insert into t1_decimal values
  (1,1,23),(2,2,11),(3,3,16),
  (1,1,12),(1,1,14),(2,3,15),
  (2,1,13),(2,3,11),(3,3,16);    

create table t2_decimal (a decimal(3,1), b decimal(3,1), c int);
insert into t2_decimal values
  (2,1,13),(2,2,11),(3,3,16),
  (1,3,22),(1,3,14),(2,2,15),
  (2,1,43),(2,3,11),(2,3,16);

create view v1 as select a, b, max(c) as max_c, avg(c) as avg_c from t1 
  group by a,b having max_c < 707;
  
create view v2 as select a, b, max(c) as max_c, avg(c) as avg_c from t1 
  where t1.a>5 group by a,b having max_c < 707;  
  
create view v3 as select a, b, min(c) as min_c from t1
  where t1.a<10 group by a,b having min_c > 109;
  
create view v4 as
  select a, b, min(max_c) as min_c from v1
    where (v1.a<15) group by a,b;  
  
create view v_union as 
  select a, b, min(c) as c from t1
    where t1.a<10 group by a,b having c > 109
      union
  select a, b, max(c) as c from t1
    where t1.b>10 group by a,b having c < 300;  
    
create view v2_union as 
  select a, b, min(c) as c from t1
    where t1.a<10 group by a,b having c > 109
      union
  select a, b, max(c) as c from t1
    where t1.b>10 group by a,b having c < 300
      union
  select a, b, avg(c) as c from t1
    where t1.c>300 group by a,b having c < 707;   

create view v3_union as 
  select a, b, (a+1) as c from t1
    where t1.a<10
      union
  select a, b, c from t1
    where t1.b>10 and t1.c>100;     
    
create view v4_union as 
  select a, b, max(c)-100 as c from t1
    where t1.a<10 group by a,b having c > 109
      union
  select a, b, (c+100) as c from t1
    where t1.b>10;         

create view v_double as
  select a, avg(a/4) as avg_a, b, c from t1_double
    where (b>12.2) group by b,c having (avg_a<22.333);  
    
create view v_char as 
  select a, b, max(c) as max_c from t1_char 
    group by a,b having max_c < 9;   
    
create view v_decimal as
  select a, b, avg(c) as avg_c from t1_decimal
    group by a,b having (avg_c>12);    

--echo # conjunctive subformula : pushing into HAVING 
let $query= select * from v1,t2 where (v1.max_c>214) and (t2.a>v1.a);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

let $query= 
  select * from
    (select a, b, max(c) as max_c, avg(c) as avg_c from t1
      group by a,b having max_c < 707) v1, 
        t2 where (v1.a=t2.a) and (v1.max_c>300);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;        

--echo # extracted or formula : pushing into HAVING 
let $query= 
  select * from v1,t2 where 
    ((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;        
    
let $query= 
  select * from v1,t2 where
    ((v1.max_c>300) and (v1.avg_c>t2.d) and (v1.b=t2.b)) or 
      ((v1.max_c<135) and (v1.max_c<t2.c) and (v1.a=t2.a));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;           

--echo # conjunctive subformula : pushing into WHERE
let $query= select * from v1,t2 where (v1.a>6) and (t2.b>v1.b);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

let $query= select * from v2,t2 where (v2.b>25) and (t2.a<v2.a);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   

--echo # extracted or formula : pushing into WHERE
let $query= 
  select * from v1,t2 where 
    ((v1.a>7) and (t2.c<v1.max_c)) or ((v1.a<2) and (t2.b<v1.b));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;    
    
let $query= 
  select * from v2,t2 where 
   ((v2.a>7) and (t2.c<v2.max_c)) or ((v2.a>5) and (t2.b<v2.b));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;    
   
let $query= 
  select * from v1,t2 where 
    ((v1.a>4) and (v1.b>t2.b) and (v1.max_c=t2.d)) or 
      ((v1.a<2) and (v1.max_c<t2.c) and (v1.max_c=t2.d));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;          

--echo # conjunctive subformulas : pushing into HAVING and WHERE
let $query= 
  select * from v1,t2 where (v1.a<2) and (v1.max_c>400) and (t2.b>v1.b);      
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

let $query= 
  select * from v_double as v,t2_double as t where
    (v.a=t.a) and (v.avg_a>0.45) and (v.b>10);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

let $query= 
  select * from v_decimal as v,t2_decimal as t where
    (v.a=t.a) and (v.avg_c>15) and (v.b>1);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;     
  
--echo # extracted or formula : pushing into HAVING and WHERE
let $query= 
  select * from v1,t2 where 
    ((v1.a>7) and (v1.max_c>300) and (t2.c<v1.max_c)) or 
    ((v1.a<4) and (v1.max_c<500) and (t2.b<v1.b)); 
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
    
let $query= 
  select * from v1,t2 where ((v1.a<2) and (v1.max_c>120)) or (v1.a>7);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
  
--echo # extracted or formulas : pushing into WHERE and HAVING     
let $query= 
  select * from v1,t2 where 
    ((v1.a<2) and (v1.max_c>120) and (v1.b=t2.b)) or (v1.a>7);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;    
    
let $query= 
  select * from v1,t2 where
    ((v1.a<2) and (v1.max_c<200) and (t2.c>v1.max_c) and (v1.max_c=t2.d)) or
      ((v1.a>4) and (v1.max_c<500) and (t2.b<v1.b) and (v1.max_c=t2.c));    
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;       
  
--echo # prepare of a query containing extracted or formula
prepare stmt from "select * from v1,t2 where 
  ((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a));";
execute stmt;
execute stmt;
deallocate prepare stmt;
prepare stmt from 
  "explain format=json select * from v1,t2 where 
    ((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a));";
execute stmt;
execute stmt;
deallocate prepare stmt;

--echo # conjunctive subformula : pushing into WHERE
--echo # pushing equalities
let $query= 
  select * from v1,t2 where (t2.a=v1.a) and (v1.b=t2.b) and (v1.a=1);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

let $query= select * from v1,t2 where (v1.a=5) and (v1.max_c=t2.d);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # conjunctive subformula : pushing into WHERE using equalities
let $query= select * from v1,t2 where (t2.a<5) and (v1.a=t2.a);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;  
  
let $query= 
  select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   
  
--echo # conjunctive subformula : pushing into HAVING using equalities
let $query= select * from v1,t2 where (t2.c>150) and (v1.max_c=t2.c);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # extracted and formula : pushing into WHERE  
--echo # pushing equalities
let $query= 
  select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a) and (v1.a=3);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
  
let $query= 
  select * from v1,t2 where (v1.a=1) and (v1.b=21) and (t2.a=2);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

let $query= 
  select * from v_char as v,t2_char as t where 
    (v.a='c') and (v.b<'Hermes') and ((v.b=t.b) or (v.max_c>20));  
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # extracted and formula : pushing into WHERE using equalities
--echo # pushing equalities
let $query= 
select * from v_decimal as v,t2_decimal as t where
    (v.a=v.b) and (v.b=t.b) and ((t.b>1) or (v.a=1));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;    

--echo # extracted or formula : pushing into HAVING using equalities     
let $query= 
  select * from v1,t2
    where ((t2.a<4) and (v1.a=t2.a)) or ((t2.c>150) and (v1.max_c=t2.c)); 
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;      

--echo # conjunctive subformulas : pushing into WHERE and HAVING using equalities
let $query= 
  select * from v1,t2
    where ((t2.a>5) and (v1.a=t2.a)) and ((t2.c>250) and (v1.max_c=t2.c));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # conjunctive subformulas : pushing into WHERE and HAVING
--echo # pushing equalities    
let $query= 
  select * from
    (select a, b, max(c) as max_c, avg(c) as avg_c from t1
      group by a,b having max_c < 707) v1, 
        t2 where (v1.a=8) and (v1.a=t2.a) and (v1.max_c=404);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;        
        
--echo # conjunctive subformulas : pushing into WHERE and HAVING 
let $query= 
  select * from v1,t2 where 
    (v1.a>3) and (v1.max_c>200) and (t2.b<v1.b) and (t2.d=v1.max_c);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # conjunctive subformula : pushing into WHERE
--echo # extracted or formula : pushing into HAVING using equalities
--echo # pushing equalities
let $query=  
  select * from v_double as v,t2_double as t where
    (v.b=v.c) and (v.c=t.c) and ((t.c>10) or (v.a=1));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;      

--echo # conjunctive subformula : pushing into WHERE
--echo # extracted or formula : pushing into HAVING using equalities 
let $query=  
  select * from v_double as v,t2_double as t where
    (((v.a>0.2) or (v.b<17)) or (t.c>17)) and (t.c=v.c) and (v.c>18);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # extracted or formula : pushing into WHERE
--echo # conjunctive subformula : pushing into HAVING
--echo # pushing equalities
let $query=     
  select * from v_decimal as v,t2_decimal as t where
    (((v.a>4) or (v.a=2)) or (v.b>3)) and (v.avg_c=13);  
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

let $query= 
  select * from
    (select a, b, max(c) as max_c, avg(c) as avg_c from t1
      where t1.a>5 group by a,b having max_c < 707) v1, 
        t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.a=v1.b);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
      
--echo # nothing to push
let $query= 
  select * from v1,t2 where (t2.a<2) and (t2.c>900);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   

let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 
  
let $query= 
  select * from v1,t2 where 
    (t2.a=v1.a) or (v1.b=t2.b) and ((v1.a=1) or (v1.a=6)); 
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;    
      
let $query= 
  select * from v1,t2 where (v1.a=1) or (v1.b=21) or (t2.a=2);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

let $query= 
  select * from v1,t2 where 
    (t2.a<2) and (t2.c>900) and ((v1.a<t2.a) or (t2.a<11));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   

--echo # using several derived tables : nothing to push
let $query= select * from v1,v2,t2 where 
  (v1.a=v2.a) and (v1.a=t2.a) and (v2.b<50);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   

let $query= 
  select * from v1,v2,t2 where 
    ((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   

let $query= 
  select * from v1,v2,t2 where 
    ((v1.a=v2.a) and (v1.a=t2.a)) or ((v2.b>13) and (t2.c<115));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   

--echo # using several derived tables : pushing in all tables
--echo # conjunctive subformula : pushing into HAVING
--echo # extracted or formula : pushing into WHERE
--echo # pushing equalities  
let $query= 
  select * from v1,v2,t2 where ((v1.a=v2.a) or (v1.a=t2.a)) and 
    ((v2.b<50) or (v2.b=19)) and (v1.max_c<300);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;      
  
--echo # using several derived tables : pushing only in one table
--echo # conjunctive subformula : pushing into WHERE
--echo # pushing equalities
let $query= 
  select * from v1,v2,t2 where 
    (v1.a=t2.a) and (v1.a=v1.b) and (v1.a=v2.a) and (v2.max_c<300); 
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;     

--echo # using several derived tables : pushing only in one table
--echo # extracted and formula : pushing into WHERE
--echo # conjunctive subformula : pushing into WHERE using equalities
--echo # pushing equalities
let $query= 
  select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   

--echo # extracted or formula : pushing into WHERE
--echo # conjunctive subformula : pushing into WHERE using equalities
--echo # pushing equalities
let $query= 
  select * from v_char as v,t2_char as t where 
    (v.a=t.a) and (t.a='b') and ((v.b='Vika') or (v.b='Ali'));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   

--echo # using several derived tables : pushing in all tables
--echo # extracted or formula : pushing into WHERE
--echo # conjunctive subformulas : pushing into HAVING  
--echo # pushing equalities
let $query= 
  select * from v1,v2,v3,t2 where 
    ((v1.a=v2.a) or (v1.a=t2.a)) and ((v3.b<50) or (v3.b=33)) 
      and (v1.max_c<500) and (v3.a=t2.a) and (v2.max_c>300);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;  

--echo # using several derived tables : pushing in all tables
--echo # conjunctive subformulas : pushing into HAVING 
let $query= 
  select * from
    (select a, b, max(c) as max_c, avg(c) as avg_c from t1
      where t1.a>5 group by a,b having max_c < 707) v1,
    (select a, b, min(c) as min_c from t1
      where t1.a>5 group by a,b having min_c < 707) v2,
      t2 where (v1.a=v2.a) and (v1.b=t2.b) and (v1.max_c>130) and (v2.min_c<130);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # using several derived tables : pushing in all tables
--echo # extracted or formulas : pushing into HAVING
--echo # conjunctive subformula : pushing into HAVING 
let $query=
  select * from
    (select a, b, max(c) as max_c, avg(c) as avg_c from t1
      where t1.a>5 group by a,b having max_c < 707) v1,
    (select a, b, min(c) as min_c from t1
      where t1.a>5 group by a,b having min_c < 707) v2,
    (select a, b, avg(c) as avg_c from t1
      where t1.a<8 group by a,b) v3,
      t2 where (v1.a=v2.a) and (v1.b=v3.b) and ((v3.avg_c>170) or (v3.a<5))
        and ((v1.avg_c<400) or (v1.a>1)) and (v2.min_c<200);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 
      
--echo # extracted or formula : pushing into HAVING
--echo # conjunctive subformula : pushing into WHERE        
let $query= 
  select * from
    (select a, b, max(c) as max_c, avg(c) as avg_c from t1
      group by a,b having max_c < 707) v1, 
        t2 where ((v1.a=1) or (v1.max_c<300)) and (v1.b>25); 
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;           
      
--echo # extracted and formula : pushing into WHERE
--echo # conjunctive subformula : pushing into HAVING          
let $query= 
  select * from
    (select a, b, max(c) as max_c, avg(c) as avg_c from t1
      where t1.a>5 group by a,b having max_c < 707) v1, 
        t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.b<30);        
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;          

--echo # using query with union
--echo # conjunctive subformula : pushing into WHERE
--echo # conjunctive subformulas : pushing into HAVING and WHERE
let $query= 
  select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (t2.c>800)
    union
  select * from v1,t2 where (v1.max_c>100) and (v1.a>7) and (t2.d>800);      
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # using query with union
--echo # extracted and formula : pushing into WHERE   
--echo # extracted or formula : pushing into HAVING    
--echo # pushing equalities
let $query= 
  select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (v1.b=19)
    union 
  select * from v1,t2 where ((v1.max_c>400) or (v1.avg_c>270)) and (v1.a<t2.a);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # using query with union
--echo # extracted or formula : pushing into HAVING 
--echo # extracted or formula : pushing into WHERE
--echo # pushing equalities
let $query= 
  select * from v1,t2 where 
    ((t2.a=v1.a) or (v1.b=t2.b)) and ((v1.a=1) or (v1.a=6))
      union
  select * from v1,t2 where ((v1.a>3) and (v1.b>27)) or (v1.max_c>550);    
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # using query with union
--echo # extracted or formula : pushing into HAVING 
--echo # conjunctive subformulas : pushing into WHERE 
--echo # pushing equalities
let $query= 
  select * from v1,t2 where 
    ((v1.a=1) and (v1.a=t2.a)) and ((v1.max_c<500) or (v1.avg_c>500))
      union
  select * from v2,t2 where
    ((v2.a<t2.b) or (v2.max_c>200)) and (v2.b>10) and (t2.a<2)
      union
  select * from v2,t2 where
    (v2.max_c=t2.c) and (v2.b<10);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # using derived table with union
--echo # conjunctive subformulas : pushing into WHERE and HAVING
let $query= select * from v_union,t2 where (v_union.a<3) and (v_union.c>100);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # using derived table with union
--echo # conjunctive subformula : pushing into WHERE
--echo # extracted or formula : pushing into HAVING 
let $query=   
  select * from v_union,t2 where
    ((v_union.a<2) or (v_union.c>800)) and (v_union.b>12);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # using derived table with union
--echo # conjunctive subformula : pushing into HAVING
--echo # conjunctive subformula : pushing into WHERE
--echo # pushing equalities
let $query= 
  select * from v_union,t2 where
    (v_union.a=1) and (v_union.a=t2.a) and (v_union.c<200);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

let $query= 
  select * from v_char as v,t2_char as t where 
    (v.a=t.a) and (v.b='Vika') and (v.max_c>2);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;    

--echo # using derived table with union
--echo # using several derived tables : pushing in all tables
--echo # conjunctive subformula : pushing into WHERE using equalities
--echo # pushing equalities
let $query= 
  select * from v_union,v1,t2 where
    (v_union.a=v1.a) and (v1.a=t2.a) and (t2.a=1) 
    and ((v_union.c>800) or (v1.max_c>200));    
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;

--echo # using derived table with union   
--echo # extracted or formula : pushing into WHERE    
--echo # conjunctive subformula : pushing into HAVING
--echo # pushing equalities
let $query= 
  select * from v2_union as v,t2 where 
    ((v.a=6) or (v.a=8)) and (v.c>200) and (v.a=t2.a);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;         

--echo # using derived table with union of selects without aggregation
--echo # extracted conjunctive predicate: pushing in WHERE of both selects
let $query=    
  select * from v3_union as v,t2 where (v.a=t2.a) and (v.c>6);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;  

--echo # using derived table with union of selects without aggregation
--echo # extracted conjunctive OR subformula: pushing in WHERE using equalities
let $query=    
  select * from v3_union as v,t2 where (v.a=t2.a) and ((t2.a>1) or (v.b<20));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;  

--echo # using derived table with union of selects without aggregation
--echo # extracted the whole condition: in WHERE of both selects
let $query=    
  select * from v3_union as v,t2 where 
    (v.a=t2.a) and ((v.b=19) or (v.b=21)) and ((v.c<3) or (v.c>600));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;  

--echo # using derived table with union of 
--echo # a select without aggregation and a select with aggregation
--echo # extracted conjunctive predicate: pushing in WHERE of both selects
let $query=    
  select * from v4_union as v,t2 where (v.a=t2.a) and (v.b<20);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # using derived table with union of 
--echo # a select without aggregation and a select with aggregation
--echo # extracted subformula: pushing in WHERE of one select
--echo # extracted subformula: pushing in HAVING of the other select
--echo # extracted sub-subformula: pushing in WHERE of the other select
--echo # using an equality in all pushdowns
let $query=    
  select * from v4_union as v,t2 where 
    (v.a=t2.a) and ((t2.a<3) or (v.b<40)) and (v.c>500);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # using embedded derived table : pushing the same conditions
--echo # using several derived tables : pushing in all tables
--echo # conjunctive subformula : pushing into WHERE
--echo # extracted and formula : pushing into WHERE
let $query= 
select * from v4,v1 where
    (v4.a<13) and (v1.a>5) and (v1.b>12);  
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # using embedded view : nothing to push
--echo # using several derived tables : pushing only in one table
--echo # conjunctive subformula : pushing into WHERE
let $query= 
  select * from v4,v1,t2 where
    (v4.a=t2.a) and (v4.a=v1.a) and (v1.b>30);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # using embedded view : pushing different conditions
--echo # using several derived tables : pushing in all tables
--echo # conjunctive subformula : pushing into WHERE using equalities
--echo # extracted and formula : pushing into WHERE using equalities
--echo # conjunctive subformula : pushing into HAVING
let $query=     
  select * from v4,v1,t2 where
    (v4.a=t2.a) and (v4.a>1) and (v4.a=v1.a) and (v4.min_c>100) and (v1.b<30);  
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query; 

--echo # using embedded view : pushing different conditions
--echo # using several derived tables : pushing in all tables
--echo # extracted or formula : pushing into WHERE
--echo # conjunctive subformula : pushing into HAVING
let $query= 
  select * from v4,v1,t2 where
    (((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;     
    
--echo # using embedded view : pushing different conditions
--echo # using several derived tables : pushing only in one table
--echo # extracted or formula : pushing into WHERE
--echo # extracted or formula : pushing into HAVING
let $query= 
  select * from v4,v2 where
    ((v4.a>12) and (v4.min_c<300) and (v4.b>13)) or (v4.a<1);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;    
    
--echo # using embedded view : pushing different conditions
--echo # using several derived tables : pushing only in one table
--echo # conjunctive subformula : pushing into WHERE
--echo # conjunctive subformula : pushing into HAVING
--echo # pushing equalities
let $query= 
  select * from v4,v2 where
    (v4.a=v2.b) and (v4.a=v4.b) and (v4.min_c<100); 
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;       
    
--echo # using embedded view : pushing the same conditions
--echo # using several derived tables : pushing in all tables
--echo # extracted and formula : pushing into WHERE using equalities
--echo # conjunctive subformula : pushing into WHERE
--echo # pushing equalities
let $query= 
  select * from v4,v2 where
    (v4.a=v2.b) and (v4.a=v4.b) and (v2.b<30);  
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;    

--echo # using embedded view : pushing the same conditions
--echo # using several derived tables : pushing in all tables
--echo # extracted or formula : pushing into WHERE using equalities
--echo # extracted and formula : pushing into WHERE using equalities
--echo # pushing equalities
let $query= 
  select * from v4,v2 where
    (v4.a=v2.b) and (v4.a=v4.b) and ((v2.b<30) or (v4.a>2));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;     
    
--echo # using embedded view : pushing the same conditions
--echo # using several derived tables : pushing in all tables
--echo # extracted or formula : pushing into WHERE
--echo # conjunctive subformula : pushing into WHERE
--echo # pushing equalities    
let $query= 
  select * from v4,v2 where
    (((v4.a<12) and (v4.b>13)) or (v4.a>10)) and
    (v4.min_c=v2.max_c) and (v4.min_c>100);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;     

--echo # using embedded view : pushing the same conditions
--echo # using several derived tables : pushing only in one table
--echo # extracted or formula : pushing into WHERE
let $query= 
  select * from v4,v2,t2 where
    (((v4.a<12) and (t2.b>13)) or (v4.a>10)) and
    (v4.min_c=t2.c) and (t2.c>100);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;   
     
drop view v1,v2,v3,v4;
drop view v_union,v2_union,v3_union,v4_union;
drop view v_double,v_char,v_decimal;
drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;  

--echo #
--echo # MDEV-10782: condition extracted from a multiple equality
--echo #             pushed into HAVING
--echo #

CREATE TABLE t1 (i int);
INSERT INTO t1 VALUES (1),(2);
EXPLAIN EXTENDED
SELECT *
  FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
    WHERE f = 8;
SELECT *
  FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
    WHERE f = 8;
SELECT *
  FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
    WHERE f = 1;
DROP TABLE t1;

--echo #
--echo # MDEV-10783: pushdown into constant view
--echo #

CREATE TABLE t1 (i int) ENGINE=MyISAM;
CREATE VIEW v AS SELECT 5;
SELECT * FROM t1 WHERE 1 IN ( SELECT * FROM v );
DROP VIEW v;
DROP TABLE t1; 
 
--echo #
--echo # MDEV-10785: second execution of a query with condition
--echo #             pushed into view
--echo #

CREATE TABLE t1 (i int);
CREATE VIEW v1 AS SELECT i FROM t1 WHERE i < 5;
CREATE FUNCTION f (in1 int) RETURNS int RETURN in1;
CREATE VIEW v2 AS SELECT * FROM v1 GROUP BY i;
PREPARE stmt FROM "SELECT * FROM v2 WHERE f(0) <> 2";
EXECUTE stmt;
EXECUTE stmt;
DROP FUNCTION f;
DROP VIEW v2,v1;
DROP TABLE t1;

--echo #
--echo # MDEV-10884: condition pushdown into derived specified by
--echo #             1. unit with  SELECT containing ORDER BY ... LIMIT
--echo #             2. unit containing global ORDER BY ... LIMIT
--echo #

create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
select a from t1 order by a limit 5;

set statement optimizer_switch='condition_pushdown_for_derived=off' for
select * from (select a from t1 order by a limit 5) t where t.a not in (1,2,3);
set statement optimizer_switch='condition_pushdown_for_derived=on' for 
select * from (select a from t1 order by a limit 5) t where t.a not in (1,2,3);

select a from t1 where a < 4 union select a from t1 where a > 5
  order by a limit 5;
set statement optimizer_switch='condition_pushdown_for_derived=off' for
select * from 
(select a from t1 where a < 4 union select a from t1 where a > 5
 order by a limit 5) t where t.a not in (2,9);
set statement optimizer_switch='condition_pushdown_for_derived=on' for 
select * from 
(select a from t1 where a < 4 union select a from t1 where a > 5
 order by a limit 5) t where t.a not in (2,9);

drop table t1;

--echo #
--echo # MDEV-11072: pushdown of the condition obtained
--echo #             after constant row substitution
--echo #

CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
CREATE TABLE t3 (c INT);
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3;

SELECT * FROM t1 WHERE a IN ( 
  SELECT b FROM v2 WHERE b < a OR b IN ( 
    SELECT c FROM v3 WHERE c = a 
  ) 
);

INSERT INTO t1 VALUES (2);
INSERT INTO t2 VALUES (3), (2);
INSERT INTO t3 VALUES (4), (1), (2), (7);

SELECT * FROM t1 WHERE a IN ( 
  SELECT b FROM v2 WHERE b < a OR b IN ( 
    SELECT c FROM v3 WHERE c = a 
  ) 
);

EXPLAIN FORMAT=JSON
SELECT * FROM t1 WHERE a IN ( 
  SELECT b FROM v2 WHERE b < a OR b IN ( 
    SELECT c FROM v3 WHERE c = a 
  ) 
);

DROP VIEW v2,v3;
DROP TABLE t1,t2,t3;