mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge branch '10.2-mdev9197-cons' of github.com:shagalla/server
into branch 10.2-mdev9197.
This commit is contained in:
commit
3fb4f9bb93
30 changed files with 8926 additions and 14 deletions
6436
mysql-test/r/derived_cond_pushdown.result
Normal file
6436
mysql-test/r/derived_cond_pushdown.result
Normal file
File diff suppressed because it is too large
Load diff
812
mysql-test/t/derived_cond_pushdown.test
Normal file
812
mysql-test/t/derived_cond_pushdown.test
Normal file
|
@ -0,0 +1,812 @@
|
|||
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 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 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,v_union,v2_union,v_double,v_char,v_decimal;
|
||||
drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
|
204
sql/item.cc
204
sql/item.cc
|
@ -488,6 +488,7 @@ Item::Item(THD *thd):
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Constructor used by Item_field, Item_ref & aggregate (sum)
|
||||
functions.
|
||||
|
@ -2258,6 +2259,73 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Building clone for Item_func_or_sum
|
||||
|
||||
@param thd thread handle
|
||||
@param mem_root part of the memory for the clone
|
||||
|
||||
@details
|
||||
This method gets copy of the current item and also
|
||||
build clones for its referencies. For the referencies
|
||||
build_copy is called again.
|
||||
|
||||
@retval
|
||||
clone of the item
|
||||
0 if an error occured
|
||||
*/
|
||||
|
||||
Item* Item_func_or_sum::build_clone(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
Item_func_or_sum *copy= (Item_func_or_sum *) get_copy(thd, mem_root);
|
||||
if (!copy)
|
||||
return 0;
|
||||
if (arg_count > 2)
|
||||
copy->args=
|
||||
(Item**) alloc_root(mem_root, sizeof(Item*) * arg_count);
|
||||
else if (arg_count > 0)
|
||||
copy->args= copy->tmp_arg;
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
Item *arg_clone= args[i]->build_clone(thd, mem_root);
|
||||
if (!arg_clone)
|
||||
return 0;
|
||||
copy->args[i]= arg_clone;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Building clone for Item_ref
|
||||
|
||||
@param thd thread handle
|
||||
@param mem_root part of the memory for the clone
|
||||
|
||||
@details
|
||||
This method gets copy of the current item and also
|
||||
builds clone for its reference.
|
||||
|
||||
@retval
|
||||
clone of the item
|
||||
0 if an error occured
|
||||
*/
|
||||
|
||||
Item* Item_ref::build_clone(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
Item_ref *copy= (Item_ref *) get_copy(thd, mem_root);
|
||||
if (!copy)
|
||||
return 0;
|
||||
Item *item_clone= (* ref)->build_clone(thd, mem_root);
|
||||
if (!item_clone)
|
||||
return 0;
|
||||
*copy->ref= item_clone;
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
void Item_ident_for_show::make_field(THD *thd, Send_field *tmp_field)
|
||||
{
|
||||
tmp_field->table_name= tmp_field->org_table_name= table_name;
|
||||
|
@ -6708,6 +6776,85 @@ Item *Item_field::update_value_transformer(THD *thd, uchar *select_arg)
|
|||
}
|
||||
|
||||
|
||||
Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
|
||||
{
|
||||
st_select_lex *sl= (st_select_lex *)arg;
|
||||
table_map map= sl->master_unit()->derived->table->map;
|
||||
if (!((Item_field*)this)->item_equal)
|
||||
{
|
||||
if (used_tables() == map)
|
||||
{
|
||||
Item_ref *rf=
|
||||
new (thd->mem_root) Item_ref(thd, &sl->context,
|
||||
NullS, NullS,
|
||||
((Item_field*) this)->field_name);
|
||||
if (!rf)
|
||||
return 0;
|
||||
return rf;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal;
|
||||
Item_equal_fields_iterator li(*cond);
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->used_tables() == map && item->type() == FIELD_ITEM)
|
||||
{
|
||||
Item_ref *rf=
|
||||
new (thd->mem_root) Item_ref(thd, &sl->context,
|
||||
NullS, NullS,
|
||||
((Item_field*) item)->field_name);
|
||||
if (!rf)
|
||||
return 0;
|
||||
return rf;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg)
|
||||
{
|
||||
st_select_lex *sl= (st_select_lex *)arg;
|
||||
List_iterator<Grouping_tmp_field> li(sl->grouping_tmp_fields);
|
||||
Grouping_tmp_field *field;
|
||||
table_map map= sl->master_unit()->derived->table->map;
|
||||
if (used_tables() == map)
|
||||
{
|
||||
while ((field=li++))
|
||||
{
|
||||
if (((Item_field*) this)->field == field->tmp_field)
|
||||
return field->producing_item->build_clone(thd, thd->mem_root);
|
||||
}
|
||||
}
|
||||
else if (((Item_field*)this)->item_equal)
|
||||
{
|
||||
Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal;
|
||||
Item_equal_fields_iterator it(*cond);
|
||||
Item *item;
|
||||
while ((item=it++))
|
||||
{
|
||||
if (item->used_tables() == map && item->type() == FIELD_ITEM)
|
||||
{
|
||||
Item_field *field_item= (Item_field *) item;
|
||||
li.rewind();
|
||||
while ((field=li++))
|
||||
{
|
||||
if (field_item->field == field->tmp_field)
|
||||
{
|
||||
return field->producing_item->build_clone(thd, thd->mem_root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
void Item_field::print(String *str, enum_query_type query_type)
|
||||
{
|
||||
if (field && field->table->const_table &&
|
||||
|
@ -9933,5 +10080,62 @@ const char *dbug_print_item(Item *item)
|
|||
return "Couldn't fit into buffer";
|
||||
}
|
||||
|
||||
|
||||
#endif /*DBUG_OFF*/
|
||||
|
||||
bool Item_field::exclusive_dependence_on_table_processor(uchar *map)
|
||||
{
|
||||
table_map tab_map= *((table_map *) map);
|
||||
return !((used_tables() == tab_map ||
|
||||
(item_equal && item_equal->used_tables() & tab_map)));
|
||||
}
|
||||
|
||||
bool Item_field::exclusive_dependence_on_grouping_fields_processor(uchar *arg)
|
||||
{
|
||||
st_select_lex *sl= (st_select_lex *)arg;
|
||||
List_iterator<Grouping_tmp_field> li(sl->grouping_tmp_fields);
|
||||
Grouping_tmp_field *field;
|
||||
table_map map= sl->master_unit()->derived->table->map;
|
||||
if (used_tables() == map)
|
||||
{
|
||||
while ((field=li++))
|
||||
{
|
||||
if (((Item_field*) this)->field == field->tmp_field)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (((Item_field*)this)->item_equal)
|
||||
{
|
||||
Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal;
|
||||
Item_equal_fields_iterator it(*cond);
|
||||
Item *item;
|
||||
while ((item=it++))
|
||||
{
|
||||
if (item->used_tables() == map && item->type() == FIELD_ITEM)
|
||||
{
|
||||
li.rewind();
|
||||
while ((field=li++))
|
||||
{
|
||||
if (((Item_field *)item)->field == field->tmp_field)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*Item *Item::get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
dbug_print_item(this);
|
||||
DBUG_ASSERT(0);
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
|
||||
void Item::register_in(THD *thd)
|
||||
{
|
||||
next= thd->free_list;
|
||||
thd->free_list= this;
|
||||
}
|
||||
|
|
121
sql/item.h
121
sql/item.h
|
@ -32,6 +32,8 @@ C_MODE_START
|
|||
#include <ma_dyncol.h>
|
||||
C_MODE_END
|
||||
|
||||
const char *dbug_print_item(Item *item);
|
||||
|
||||
class Protocol;
|
||||
struct TABLE_LIST;
|
||||
void item_init(void); /* Init item functions */
|
||||
|
@ -89,6 +91,10 @@ bool mark_unsupported_function(const char *w1, const char *w2,
|
|||
#define MY_COLL_ALLOW_CONV (MY_COLL_ALLOW_SUPERSET_CONV | MY_COLL_ALLOW_COERCIBLE_CONV)
|
||||
#define MY_COLL_CMP_CONV (MY_COLL_ALLOW_CONV | MY_COLL_DISALLOW_NONE)
|
||||
|
||||
#define NO_EXTRACTION_FL (1 << 6)
|
||||
#define FULL_EXTRACTION_FL (1 << 7)
|
||||
#define EXTRACTION_MASK (NO_EXTRACTION_FL | FULL_EXTRACTION_FL)
|
||||
|
||||
class DTCollation {
|
||||
public:
|
||||
CHARSET_INFO *collation;
|
||||
|
@ -591,7 +597,6 @@ class Item: public Value_source,
|
|||
public Type_std_attributes,
|
||||
public Type_handler
|
||||
{
|
||||
Item(const Item &); /* Prevent use of these */
|
||||
void operator=(Item &);
|
||||
/**
|
||||
The index in the JOIN::join_tab array of the JOIN_TAB this Item is attached
|
||||
|
@ -1110,6 +1115,7 @@ public:
|
|||
virtual bool basic_const_item() const { return 0; }
|
||||
/* cloning of constant items (0 if it is not const) */
|
||||
virtual Item *clone_item(THD *thd) { return 0; }
|
||||
virtual Item* build_clone(THD *thd, MEM_ROOT *mem_root) { return get_copy(thd, mem_root); }
|
||||
virtual cond_result eq_cmp_result() const { return COND_OK; }
|
||||
inline uint float_length(uint decimals_par) const
|
||||
{ return decimals < FLOATING_POINT_DECIMALS ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
|
||||
|
@ -1475,6 +1481,14 @@ public:
|
|||
virtual bool exists2in_processor(void *opt_arg) { return 0; }
|
||||
virtual bool find_selective_predicates_list_processor(void *opt_arg)
|
||||
{ return 0; }
|
||||
virtual bool exclusive_dependence_on_table_processor(uchar *map)
|
||||
{ return 0; }
|
||||
virtual bool exclusive_dependence_on_grouping_fields_processor(uchar *arg)
|
||||
{ return 0; }
|
||||
//virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root);
|
||||
|
||||
|
||||
virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root)=0;
|
||||
|
||||
/* To call bool function for all arguments */
|
||||
struct bool_func_call_args
|
||||
|
@ -1679,6 +1693,10 @@ public:
|
|||
{ return this; }
|
||||
virtual Item *expr_cache_insert_transformer(THD *thd, uchar *unused)
|
||||
{ return this; }
|
||||
virtual Item *derived_field_transformer_for_having(THD *thd, uchar *arg)
|
||||
{ return this; }
|
||||
virtual Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
|
||||
{ return this; }
|
||||
virtual bool expr_cache_is_needed(THD *) { return FALSE; }
|
||||
virtual Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
|
||||
bool needs_charset_converter(uint32 length, CHARSET_INFO *tocs)
|
||||
|
@ -1836,9 +1854,35 @@ public:
|
|||
*/
|
||||
virtual void under_not(Item_func_not * upper
|
||||
__attribute__((unused))) {};
|
||||
|
||||
|
||||
void register_in(THD *thd);
|
||||
|
||||
bool depends_only_on(table_map view_map)
|
||||
{ return marker & FULL_EXTRACTION_FL; }
|
||||
int get_extraction_flag()
|
||||
{ return marker & EXTRACTION_MASK; }
|
||||
void set_extraction_flag(int flags)
|
||||
{
|
||||
marker &= ~EXTRACTION_MASK;
|
||||
marker|= flags;
|
||||
}
|
||||
void clear_extraction_flag()
|
||||
{
|
||||
marker &= ~EXTRACTION_MASK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
inline Item* get_item_copy (THD *thd, MEM_ROOT *mem_root, T* item)
|
||||
{
|
||||
Item *copy= new (mem_root) T(*item);
|
||||
copy->register_in(thd);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Compare two Items for List<Item>::add_unique()
|
||||
*/
|
||||
|
@ -2119,6 +2163,8 @@ public:
|
|||
{ return this; }
|
||||
|
||||
bool append_for_log(THD *thd, String *str);
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -2165,6 +2211,7 @@ public:
|
|||
purposes.
|
||||
*/
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
|
||||
private:
|
||||
uint m_case_expr_id;
|
||||
|
@ -2245,6 +2292,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function("name_const()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_name_const>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_num: public Item_basic_constant
|
||||
|
@ -2377,6 +2426,8 @@ public:
|
|||
CHARSET_INFO *charset_for_protocol(void) const
|
||||
{ return field->charset_for_protocol(); }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||
Item* get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_ident_for_show>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2529,7 +2580,13 @@ public:
|
|||
Item_field *field_for_view_update() { return this; }
|
||||
int fix_outer_field(THD *thd, Field **field, Item **reference);
|
||||
virtual Item *update_value_transformer(THD *thd, uchar *select_arg);
|
||||
virtual Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
|
||||
virtual Item *derived_field_transformer_for_where(THD *thd, uchar *arg);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
bool exclusive_dependence_on_table_processor(uchar *map);
|
||||
bool exclusive_dependence_on_grouping_fields_processor(uchar *arg);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_field>(thd, mem_root, this); }
|
||||
bool is_outer_field() const
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
|
@ -2622,6 +2679,8 @@ public:
|
|||
|
||||
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
|
||||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_null>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_null_result :public Item_null
|
||||
|
@ -2783,6 +2842,8 @@ public:
|
|||
|
||||
bool append_for_log(THD *thd, String *str);
|
||||
bool check_vcol_func_processor(void *int_arg) {return FALSE;}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
|
||||
private:
|
||||
virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
||||
|
||||
|
@ -2831,6 +2892,8 @@ public:
|
|||
{ return (uint) (max_length - MY_TEST(value < 0)); }
|
||||
bool eq(const Item *item, bool binary_cmp) const
|
||||
{ return int_eq(value, item); }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_int>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2847,6 +2910,8 @@ public:
|
|||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *neg(THD *thd);
|
||||
uint decimal_precision() const { return max_length; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_uint>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2893,6 +2958,8 @@ public:
|
|||
uint decimal_precision() const { return decimal_value.precision(); }
|
||||
bool eq(const Item *, bool binary_cmp) const;
|
||||
void set_decimal_value(my_decimal *value_par);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_decimal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2941,6 +3008,8 @@ public:
|
|||
virtual void print(String *str, enum_query_type query_type);
|
||||
bool eq(const Item *item, bool binary_cmp) const
|
||||
{ return real_eq(value, item); }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_float>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -3130,6 +3199,9 @@ public:
|
|||
}
|
||||
return MYSQL_TYPE_STRING; // Not a temporal literal
|
||||
}
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_string>(thd, mem_root, this); }
|
||||
|
||||
};
|
||||
|
||||
|
@ -3358,6 +3430,8 @@ public:
|
|||
}
|
||||
enum Item_result cast_to_int_type() const { return INT_RESULT; }
|
||||
void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_hex_hybrid>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -3398,6 +3472,8 @@ public:
|
|||
}
|
||||
enum Item_result cast_to_int_type() const { return STRING_RESULT; }
|
||||
void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_hex_string>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -3479,6 +3555,8 @@ public:
|
|||
void print(String *str, enum_query_type query_type);
|
||||
Item *clone_item(THD *thd);
|
||||
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_date_literal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -3498,6 +3576,8 @@ public:
|
|||
void print(String *str, enum_query_type query_type);
|
||||
Item *clone_item(THD *thd);
|
||||
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_time_literal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -3519,6 +3599,8 @@ public:
|
|||
void print(String *str, enum_query_type query_type);
|
||||
Item *clone_item(THD *thd);
|
||||
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_datetime_literal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -3879,6 +3961,7 @@ public:
|
|||
virtual void fix_length_and_dec()= 0;
|
||||
bool const_item() const { return const_item_cache; }
|
||||
table_map used_tables() const { return used_tables_cache; }
|
||||
Item* build_clone(THD *thd, MEM_ROOT *mem_root);
|
||||
};
|
||||
|
||||
|
||||
|
@ -4054,6 +4137,8 @@ public:
|
|||
DBUG_ASSERT(ref);
|
||||
return (*ref)->is_outer_field();
|
||||
}
|
||||
|
||||
Item* build_clone(THD *thd, MEM_ROOT *mem_root);
|
||||
|
||||
/**
|
||||
Checks if the item tree that ref points to contains a subquery.
|
||||
|
@ -4062,6 +4147,8 @@ public:
|
|||
{
|
||||
return (*ref)->has_subquery();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_ref>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4104,6 +4191,8 @@ public:
|
|||
bool is_null();
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
virtual Ref_Type ref_type() { return DIRECT_REF; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_direct_ref>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4265,6 +4354,9 @@ public:
|
|||
{
|
||||
return mark_unsupported_function("cache", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cache_wrapper>(thd, mem_root, this); }
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4516,6 +4608,8 @@ public:
|
|||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
table_map used_tables() const;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_ref_null_helper>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -4675,6 +4769,8 @@ public:
|
|||
longlong val_int();
|
||||
void copy();
|
||||
int save_in_field(Field *field, bool no_conversions);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_copy_string>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4697,6 +4793,8 @@ public:
|
|||
return null_value ? 0 : cached_value;
|
||||
}
|
||||
virtual void copy();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_copy_int>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4713,6 +4811,8 @@ public:
|
|||
{
|
||||
return null_value ? 0.0 : (double) (ulonglong) cached_value;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_copy_uint>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4739,6 +4839,8 @@ public:
|
|||
cached_value= item->val_real();
|
||||
null_value= item->null_value;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_copy_float>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4758,6 +4860,8 @@ public:
|
|||
double val_real();
|
||||
longlong val_int();
|
||||
void copy();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_copy_decimal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -5183,6 +5287,8 @@ public:
|
|||
enum Item_result result_type() const { return INT_RESULT; }
|
||||
bool cache_value();
|
||||
int save_in_field(Field *field, bool no_conversions);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cache_int>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -5207,6 +5313,8 @@ public:
|
|||
Important when storing packed datetime values.
|
||||
*/
|
||||
Item *clone_item(THD *thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cache_temporal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -5223,6 +5331,8 @@ public:
|
|||
my_decimal *val_decimal(my_decimal *);
|
||||
enum Item_result result_type() const { return REAL_RESULT; }
|
||||
bool cache_value();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cache_real>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -5239,6 +5349,8 @@ public:
|
|||
my_decimal *val_decimal(my_decimal *);
|
||||
enum Item_result result_type() const { return DECIMAL_RESULT; }
|
||||
bool cache_value();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cache_decimal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -5265,6 +5377,8 @@ public:
|
|||
CHARSET_INFO *charset() const { return value->charset(); };
|
||||
int save_in_field(Field *field, bool no_conversions);
|
||||
bool cache_value();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cache_str>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -5288,6 +5402,8 @@ public:
|
|||
*/
|
||||
return Item::safe_charset_converter(thd, tocs);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cache_str_for_nullif>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -5359,6 +5475,8 @@ public:
|
|||
}
|
||||
bool cache_value();
|
||||
virtual void set_null();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cache_row>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -5414,6 +5532,7 @@ public:
|
|||
static uint32 display_length(Item *item);
|
||||
static enum_field_types get_real_type(Item *);
|
||||
Field::geometry_type get_geometry_type() const { return geometry_type; };
|
||||
Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#include "sql_time.h" // make_truncated_value_warning
|
||||
#include "sql_base.h" // dynamic_column_error_message
|
||||
|
||||
#define FULL_EXTRACTION_FL (1 << 6)
|
||||
#define NO_EXTRACTION_FL (1 << 7)
|
||||
|
||||
|
||||
/**
|
||||
find an temporal type (item) that others will be converted to
|
||||
|
@ -4856,6 +4859,43 @@ void Item_cond::neg_arguments(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Building clone for Item_cond
|
||||
|
||||
@param thd thread handle
|
||||
@param mem_root part of the memory for the clone
|
||||
|
||||
@details
|
||||
This method gets copy of the current item and also
|
||||
build clones for its elements. For this elements
|
||||
build_copy is called again.
|
||||
|
||||
@retval
|
||||
clone of the item
|
||||
0 if an error occured
|
||||
*/
|
||||
|
||||
Item *Item_cond::build_clone(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
List_iterator_fast<Item> li(list);
|
||||
Item *item;
|
||||
Item_cond *copy= (Item_cond *) get_copy(thd, mem_root);
|
||||
if (!copy)
|
||||
return 0;
|
||||
copy->list.empty();
|
||||
while ((item= li++))
|
||||
{
|
||||
Item *arg_clone= item->build_clone(thd, mem_root);
|
||||
if (!arg_clone)
|
||||
return 0;
|
||||
if (copy->list.push_back(arg_clone, mem_root))
|
||||
return 0;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding)
|
||||
{
|
||||
List_iterator<Item> li(list);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "item_func.h" /* Item_int_func, Item_bool_func */
|
||||
#define PCRE_STATIC 1 /* Important on Windows */
|
||||
#include "pcre.h" /* pcre header file */
|
||||
#include "item.h"
|
||||
|
||||
extern Item_result item_cmp_type(Item_result a,Item_result b);
|
||||
inline Item_result item_cmp_type(const Item *a, const Item *b)
|
||||
|
@ -124,6 +125,7 @@ public:
|
|||
comparators= 0;
|
||||
}
|
||||
friend class Item_func;
|
||||
friend class Item_bool_rowready_func2;
|
||||
};
|
||||
|
||||
|
||||
|
@ -244,6 +246,8 @@ public:
|
|||
Item_func_istrue(THD *thd, Item *a): Item_func_truth(thd, a, true, true) {}
|
||||
~Item_func_istrue() {}
|
||||
virtual const char* func_name() const { return "istrue"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_istrue>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -258,6 +262,8 @@ public:
|
|||
Item_func_truth(thd, a, true, false) {}
|
||||
~Item_func_isnottrue() {}
|
||||
virtual const char* func_name() const { return "isnottrue"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_isnottrue>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -271,6 +277,8 @@ public:
|
|||
Item_func_isfalse(THD *thd, Item *a): Item_func_truth(thd, a, false, true) {}
|
||||
~Item_func_isfalse() {}
|
||||
virtual const char* func_name() const { return "isfalse"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_isfalse>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -285,6 +293,8 @@ public:
|
|||
Item_func_truth(thd, a, false, false) {}
|
||||
~Item_func_isnotfalse() {}
|
||||
virtual const char* func_name() const { return "isnotfalse"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_isnotfalse>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -346,6 +356,8 @@ public:
|
|||
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
|
||||
bool invisible_mode();
|
||||
void reset_cache() { cache= NULL; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_in_optimizer>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -499,6 +511,17 @@ public:
|
|||
return add_key_fields_optimize_op(join, key_fields, and_level,
|
||||
usable_tables, sargables, false);
|
||||
}
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
Item_bool_rowready_func2 *clone=
|
||||
(Item_bool_rowready_func2 *) Item_func::build_clone(thd, mem_root);
|
||||
if (clone)
|
||||
{
|
||||
clone->cmp.comparators= 0;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -521,6 +544,8 @@ public:
|
|||
Item_args::propagate_equal_fields(thd, Context_boolean(), cond);
|
||||
return this;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_xor>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_not :public Item_bool_func
|
||||
|
@ -537,6 +562,8 @@ public:
|
|||
Item *neg_transformer(THD *thd);
|
||||
bool fix_fields(THD *, Item **);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_not>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_maxmin_subselect;
|
||||
|
@ -584,6 +611,8 @@ public:
|
|||
void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
|
||||
uint *and_level, table_map usable_tables,
|
||||
SARGABLE_PARAM **sargables);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_trig_cond>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_not_all :public Item_func_not
|
||||
|
@ -659,6 +688,8 @@ public:
|
|||
uint in_equality_no;
|
||||
virtual uint exists2in_reserved_items() { return 1; };
|
||||
friend class Arg_comparator;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_eq>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_equal :public Item_bool_rowready_func2
|
||||
|
@ -681,6 +712,8 @@ public:
|
|||
return add_key_fields_optimize_op(join, key_fields, and_level,
|
||||
usable_tables, sargables, true);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_equal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -695,6 +728,8 @@ public:
|
|||
cond_result eq_cmp_result() const { return COND_TRUE; }
|
||||
const char *func_name() const { return ">="; }
|
||||
Item *negated_item(THD *thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ge>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -709,6 +744,8 @@ public:
|
|||
cond_result eq_cmp_result() const { return COND_FALSE; }
|
||||
const char *func_name() const { return ">"; }
|
||||
Item *negated_item(THD *thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_gt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -723,6 +760,8 @@ public:
|
|||
cond_result eq_cmp_result() const { return COND_TRUE; }
|
||||
const char *func_name() const { return "<="; }
|
||||
Item *negated_item(THD *thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_le>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -737,6 +776,8 @@ public:
|
|||
cond_result eq_cmp_result() const { return COND_FALSE; }
|
||||
const char *func_name() const { return "<"; }
|
||||
Item *negated_item(THD *thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_lt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -760,6 +801,8 @@ public:
|
|||
Item *negated_item(THD *thd);
|
||||
void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
table_map usable_tables, SARGABLE_PARAM **sargables);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ne>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -840,6 +883,8 @@ public:
|
|||
cond);
|
||||
return this;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_between>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -858,6 +903,8 @@ public:
|
|||
agg_arg_charsets_for_comparison(cmp_collation, args, 2);
|
||||
fix_char_length(2); // returns "1" or "0" or "-1"
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_strcmp>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -888,6 +935,8 @@ public:
|
|||
str->append(func_name());
|
||||
print_args(str, 0, query_type);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_interval>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -910,6 +959,8 @@ public:
|
|||
}
|
||||
const char *func_name() const { return "coalesce"; }
|
||||
table_map not_null_tables() const { return 0; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_coalesce>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -959,6 +1010,8 @@ public:
|
|||
{
|
||||
return Item_func_case_abbreviation2::decimal_precision2(args);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ifnull>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -982,6 +1035,8 @@ public:
|
|||
const char *func_name() const { return "if"; }
|
||||
bool eval_not_null_tables(void *opt_arg);
|
||||
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_if>(thd, mem_root, this); }
|
||||
private:
|
||||
void cache_type_info(Item *source);
|
||||
};
|
||||
|
@ -1057,6 +1112,8 @@ public:
|
|||
cond, &args[2]);
|
||||
return this;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_nullif>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1240,7 +1297,6 @@ public:
|
|||
item_dec->set_decimal_value(dec);
|
||||
}
|
||||
Item_result result_type() { return DECIMAL_RESULT; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1499,6 +1555,19 @@ public:
|
|||
void cleanup();
|
||||
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond);
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_case>(thd, mem_root, this); }
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
Item_func_case *clone= (Item_func_case *) Item_func::build_clone(thd, mem_root);
|
||||
if (clone)
|
||||
{
|
||||
clone->case_item= 0;
|
||||
clone->arg_buffer= 0;
|
||||
bzero(&clone->cmp_items, sizeof(cmp_items));
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1595,6 +1664,18 @@ public:
|
|||
bool eval_not_null_tables(void *opt_arg);
|
||||
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
|
||||
bool count_sargable_conds(void *arg);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_in>(thd, mem_root, this); }
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
Item_func_in *clone= (Item_func_in *) Item_func::build_clone(thd, mem_root);
|
||||
if (clone)
|
||||
{
|
||||
clone->array= 0;
|
||||
bzero(&clone->cmp_items, sizeof(cmp_items));
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
|
||||
class cmp_item_row :public cmp_item
|
||||
|
@ -1689,6 +1770,8 @@ public:
|
|||
bool top_level);
|
||||
table_map not_null_tables() const { return 0; }
|
||||
Item *neg_transformer(THD *thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_isnull>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/* Functions used by HAVING for rewriting IN subquery */
|
||||
|
@ -1734,6 +1817,8 @@ public:
|
|||
Item *neg_transformer(THD *thd);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
void top_level_item() { abort_on_null=1; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_isnotnull>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1873,6 +1958,9 @@ public:
|
|||
void cleanup();
|
||||
|
||||
bool find_selective_predicates_list_processor(void *arg);
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_like>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1978,6 +2066,8 @@ public:
|
|||
longlong val_int();
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "regexp"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_regex>(thd, mem_root, this); }
|
||||
|
||||
virtual inline void print(String *str, enum_query_type query_type)
|
||||
{
|
||||
|
@ -2005,6 +2095,8 @@ public:
|
|||
longlong val_int();
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "regexp_instr"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_regexp_instr>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2082,6 +2174,7 @@ public:
|
|||
Item *compile(THD *thd, Item_analyzer analyzer, uchar **arg_p,
|
||||
Item_transformer transformer, uchar *arg_t);
|
||||
bool eval_not_null_tables(void *opt_arg);
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root);
|
||||
};
|
||||
|
||||
template <template<class> class LI, class T> class Item_equal_iterator;
|
||||
|
@ -2254,6 +2347,7 @@ public:
|
|||
|
||||
void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }
|
||||
void set_link_equal_fields(bool flag) { link_equal_fields= flag; }
|
||||
Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
friend class Item_equal_fields_iterator;
|
||||
bool count_sargable_conds(void *arg);
|
||||
friend class Item_equal_iterator<List_iterator_fast,Item>;
|
||||
|
@ -2398,6 +2492,8 @@ public:
|
|||
void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
table_map usable_tables, SARGABLE_PARAM **sargables);
|
||||
SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cond_and>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
inline bool is_cond_and(Item *item)
|
||||
|
@ -2422,6 +2518,8 @@ public:
|
|||
table_map not_null_tables() const { return and_tables_cache; }
|
||||
Item *copy_andor_structure(THD *thd);
|
||||
Item *neg_transformer(THD *thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_cond_or>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_dyncol_check :public Item_bool_func
|
||||
|
@ -2431,6 +2529,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "column_check"; }
|
||||
bool need_parentheses_in_default() { return false; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dyncol_check>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_dyncol_exists :public Item_bool_func
|
||||
|
@ -2441,6 +2541,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "column_exists"; }
|
||||
bool need_parentheses_in_default() { return false; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dyncol_exists>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
inline bool is_cond_or(Item *item)
|
||||
|
|
|
@ -6957,3 +6957,6 @@ void Item_func_last_value::fix_length_and_dec()
|
|||
Type_std_attributes::set(last_value);
|
||||
maybe_null= last_value->maybe_null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
158
sql/item_func.h
158
sql/item_func.h
|
@ -615,6 +615,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_connection_id>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -640,6 +642,8 @@ public:
|
|||
virtual void print(String *str, enum_query_type query_type);
|
||||
uint decimal_precision() const { return args[0]->decimal_precision(); }
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_signed>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -658,6 +662,8 @@ public:
|
|||
return value;
|
||||
}
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_unsigned>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -682,6 +688,8 @@ public:
|
|||
const char *func_name() const { return "decimal_typecast"; }
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_decimal_typecast>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -700,6 +708,8 @@ public:
|
|||
const char *func_name() const { return "double_typecast"; }
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_double_typecast>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -723,6 +733,8 @@ public:
|
|||
longlong int_op();
|
||||
double real_op();
|
||||
my_decimal *decimal_op(my_decimal *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_plus>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_minus :public Item_func_additive_op
|
||||
|
@ -735,6 +747,8 @@ public:
|
|||
double real_op();
|
||||
my_decimal *decimal_op(my_decimal *);
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_minus>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -750,6 +764,8 @@ public:
|
|||
void result_precision();
|
||||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_mul>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -764,6 +780,8 @@ public:
|
|||
const char *func_name() const { return "/"; }
|
||||
void fix_length_and_dec();
|
||||
void result_precision();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_div>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -784,6 +802,8 @@ public:
|
|||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_int_div>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -799,6 +819,8 @@ public:
|
|||
void fix_length_and_dec();
|
||||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_mod>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -816,6 +838,8 @@ public:
|
|||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_neg>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -830,6 +854,8 @@ public:
|
|||
void fix_length_and_dec();
|
||||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_abs>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
// A class to handle logarithmic and trigonometric functions
|
||||
|
@ -852,6 +878,8 @@ public:
|
|||
Item_func_exp(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "exp"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_exp>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -861,6 +889,8 @@ public:
|
|||
Item_func_ln(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "ln"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ln>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -871,6 +901,8 @@ public:
|
|||
Item_func_log(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "log"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_log>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -880,6 +912,8 @@ public:
|
|||
Item_func_log2(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "log2"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_log2>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -889,6 +923,8 @@ public:
|
|||
Item_func_log10(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "log10"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_log10>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -898,6 +934,8 @@ public:
|
|||
Item_func_sqrt(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "sqrt"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sqrt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -907,6 +945,8 @@ public:
|
|||
Item_func_pow(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "pow"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_pow>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -916,6 +956,8 @@ public:
|
|||
Item_func_acos(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "acos"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_acos>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_asin :public Item_dec_func
|
||||
|
@ -924,6 +966,8 @@ public:
|
|||
Item_func_asin(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "asin"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_asin>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_atan :public Item_dec_func
|
||||
|
@ -933,6 +977,8 @@ public:
|
|||
Item_func_atan(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "atan"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_atan>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_cos :public Item_dec_func
|
||||
|
@ -941,6 +987,8 @@ public:
|
|||
Item_func_cos(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "cos"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_cos>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_sin :public Item_dec_func
|
||||
|
@ -949,6 +997,8 @@ public:
|
|||
Item_func_sin(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "sin"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sin>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_tan :public Item_dec_func
|
||||
|
@ -957,6 +1007,8 @@ public:
|
|||
Item_func_tan(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "tan"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_tan>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_cot :public Item_dec_func
|
||||
|
@ -965,6 +1017,8 @@ public:
|
|||
Item_func_cot(THD *thd, Item *a): Item_dec_func(thd, a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "cot"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_cot>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_integer :public Item_int_func
|
||||
|
@ -993,6 +1047,8 @@ public:
|
|||
my_decimal *decimal_op(my_decimal *);
|
||||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ceiling>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1006,6 +1062,8 @@ public:
|
|||
my_decimal *decimal_op(my_decimal *);
|
||||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_floor>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/* This handles round and truncate */
|
||||
|
@ -1021,6 +1079,8 @@ public:
|
|||
longlong int_op();
|
||||
my_decimal *decimal_op(my_decimal *);
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_round>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1042,6 +1102,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_rand>(thd, mem_root, this); }
|
||||
private:
|
||||
void seed_random (Item * val);
|
||||
};
|
||||
|
@ -1053,6 +1115,8 @@ public:
|
|||
Item_func_sign(THD *thd, Item *a): Item_int_func(thd, a) {}
|
||||
const char *func_name() const { return "sign"; }
|
||||
longlong val_int();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sign>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1068,6 +1132,8 @@ public:
|
|||
const char *func_name() const { return name; }
|
||||
void fix_length_and_dec()
|
||||
{ decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_units>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1104,6 +1170,8 @@ class Item_func_min :public Item_func_min_max
|
|||
public:
|
||||
Item_func_min(THD *thd, List<Item> &list): Item_func_min_max(thd, list, 1) {}
|
||||
const char *func_name() const { return "least"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_min>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_max :public Item_func_min_max
|
||||
|
@ -1111,6 +1179,8 @@ class Item_func_max :public Item_func_min_max
|
|||
public:
|
||||
Item_func_max(THD *thd, List<Item> &list): Item_func_min_max(thd, list, -1) {}
|
||||
const char *func_name() const { return "greatest"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_max>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1143,6 +1213,8 @@ public:
|
|||
/* The item could be a NULL constant. */
|
||||
null_value= args[0]->is_null();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_rollup_const>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1154,6 +1226,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "length"; }
|
||||
void fix_length_and_dec() { max_length=10; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_length>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_bit_length :public Item_func_length
|
||||
|
@ -1163,6 +1237,8 @@ public:
|
|||
longlong val_int()
|
||||
{ DBUG_ASSERT(fixed == 1); return Item_func_length::val_int()*8; }
|
||||
const char *func_name() const { return "bit_length"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_bit_length>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_char_length :public Item_int_func
|
||||
|
@ -1173,6 +1249,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "char_length"; }
|
||||
void fix_length_and_dec() { max_length=10; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_char_length>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_coercibility :public Item_int_func
|
||||
|
@ -1186,6 +1264,8 @@ public:
|
|||
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
|
||||
{ return this; }
|
||||
bool const_item() const { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_coercibility>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_locate :public Item_int_func
|
||||
|
@ -1199,6 +1279,8 @@ public:
|
|||
longlong val_int();
|
||||
void fix_length_and_dec();
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_locate>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1212,6 +1294,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "field"; }
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_field>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1223,6 +1307,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "ascii"; }
|
||||
void fix_length_and_dec() { max_length=3; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ascii>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_ord :public Item_int_func
|
||||
|
@ -1232,6 +1318,8 @@ public:
|
|||
Item_func_ord(THD *thd, Item *a): Item_int_func(thd, a) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "ord"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ord>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_find_in_set :public Item_int_func
|
||||
|
@ -1246,6 +1334,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "find_in_set"; }
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_find_in_set>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
|
||||
|
@ -1270,6 +1360,8 @@ public:
|
|||
Item_func_bit_or(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "|"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_bit_or>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_bit_and :public Item_func_bit
|
||||
|
@ -1278,6 +1370,8 @@ public:
|
|||
Item_func_bit_and(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "&"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_bit_and>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_bit_count :public Item_int_func
|
||||
|
@ -1287,6 +1381,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "bit_count"; }
|
||||
void fix_length_and_dec() { max_length=2; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_bit_count>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_shift_left :public Item_func_bit
|
||||
|
@ -1295,6 +1391,8 @@ public:
|
|||
Item_func_shift_left(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "<<"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_shift_left>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_shift_right :public Item_func_bit
|
||||
|
@ -1303,6 +1401,8 @@ public:
|
|||
Item_func_shift_right(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return ">>"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_shift_right>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_bit_neg :public Item_func_bit
|
||||
|
@ -1316,6 +1416,8 @@ public:
|
|||
{
|
||||
Item_func::print(str, query_type);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_bit_neg>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1338,6 +1440,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_last_insert_id>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1355,6 +1459,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_benchmark>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1377,6 +1483,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sleep>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1500,6 +1608,8 @@ class Item_func_udf_float :public Item_udf_func
|
|||
String *val_str(String *str);
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||
void fix_length_and_dec() { fix_num_length_and_dec(); }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_udf_float>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1517,6 +1627,8 @@ public:
|
|||
enum Item_result result_type () const { return INT_RESULT; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
|
||||
void fix_length_and_dec() { decimals= 0; max_length= 21; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_udf_int>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1534,6 +1646,8 @@ public:
|
|||
enum Item_result result_type () const { return DECIMAL_RESULT; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
|
||||
void fix_length_and_dec() { fix_num_length_and_dec(); }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_udf_decimal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1572,6 +1686,8 @@ public:
|
|||
enum Item_result result_type () const { return STRING_RESULT; }
|
||||
enum_field_types field_type() const { return string_field_type(); }
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_udf_str>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#else /* Dummy functions to get sql_yacc.cc compiled */
|
||||
|
@ -1647,6 +1763,8 @@ class Item_func_get_lock :public Item_int_func
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_get_lock>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_release_lock :public Item_int_func
|
||||
|
@ -1667,6 +1785,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_release_lock>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/* replication functions */
|
||||
|
@ -1687,6 +1807,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_master_pos_wait>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1703,6 +1825,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_master_gtid_wait>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1816,6 +1940,8 @@ public:
|
|||
bool register_field_in_bitmap(void *arg);
|
||||
bool set_entry(THD *thd, bool create_if_not_exists);
|
||||
void cleanup();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_set_user_var>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1842,6 +1968,8 @@ public:
|
|||
table_map used_tables() const
|
||||
{ return const_item() ? 0 : RAND_TABLE_BIT; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_get_user_var>(thd, mem_root, this); }
|
||||
private:
|
||||
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
||||
|
||||
|
@ -1881,6 +2009,8 @@ public:
|
|||
void set_null_value(CHARSET_INFO* cs);
|
||||
void set_value(const char *str, uint length, CHARSET_INFO* cs);
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_user_var_as_out_param>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1935,6 +2065,8 @@ public:
|
|||
|
||||
void cleanup();
|
||||
bool check_vcol_func_processor(void *arg);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_get_system_var>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1984,6 +2116,9 @@ public:
|
|||
{
|
||||
return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_match>(thd, mem_root, this); }
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
private:
|
||||
/**
|
||||
Check whether storage engine for given table,
|
||||
|
@ -2027,6 +2162,8 @@ public:
|
|||
Item_func_bit_xor(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "^"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_bit_xor>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_is_free_lock :public Item_int_func
|
||||
|
@ -2041,6 +2178,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_is_free_lock>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_is_used_lock :public Item_int_func
|
||||
|
@ -2055,6 +2194,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_is_used_lock>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/* For type casts */
|
||||
|
@ -2105,6 +2246,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_row_count>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2232,6 +2375,15 @@ public:
|
|||
{
|
||||
return TRUE;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sp>(thd, mem_root, this); }
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
Item_func_sp *clone= (Item_func_sp *) Item_func::build_clone(thd, mem_root);
|
||||
if (clone)
|
||||
clone->sp_result_field= NULL;
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -2246,6 +2398,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_found_rows>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2264,6 +2418,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_uuid_short>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -2289,6 +2445,8 @@ public:
|
|||
Item_func::update_used_tables();
|
||||
maybe_null= last_value->maybe_null;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_last_value>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
Item_geometry_func(thd, a, srid) {}
|
||||
const char *func_name() const { return "st_geometryfromtext"; }
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_geometry_from_text>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_geometry_from_wkb: public Item_geometry_func
|
||||
|
@ -61,6 +63,8 @@ public:
|
|||
Item_geometry_func(thd, a, srid) {}
|
||||
const char *func_name() const { return "st_geometryfromwkb"; }
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_geometry_from_wkb>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_as_wkt: public Item_str_ascii_func
|
||||
|
@ -70,6 +74,8 @@ public:
|
|||
const char *func_name() const { return "st_astext"; }
|
||||
String *val_str_ascii(String *);
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_as_wkt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_as_wkb: public Item_geometry_func
|
||||
|
@ -79,6 +85,8 @@ public:
|
|||
const char *func_name() const { return "st_aswkb"; }
|
||||
String *val_str(String *);
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_as_wkb>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_geometry_type: public Item_str_ascii_func
|
||||
|
@ -93,6 +101,8 @@ public:
|
|||
fix_length_and_charset(20, default_charset());
|
||||
maybe_null= 1;
|
||||
};
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_geometry_type>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -125,6 +135,8 @@ public:
|
|||
{}
|
||||
const char *func_name() const { return "st_convexhull"; }
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_convexhull>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -135,6 +147,8 @@ public:
|
|||
const char *func_name() const { return "st_centroid"; }
|
||||
String *val_str(String *);
|
||||
Field::geometry_type get_geometry_type() const;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_centroid>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_envelope: public Item_geometry_func
|
||||
|
@ -144,6 +158,8 @@ public:
|
|||
const char *func_name() const { return "st_envelope"; }
|
||||
String *val_str(String *);
|
||||
Field::geometry_type get_geometry_type() const;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_envelope>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -175,6 +191,8 @@ public:
|
|||
Item_func_boundary(THD *thd, Item *a): Item_geometry_func(thd, a) {}
|
||||
const char *func_name() const { return "st_boundary"; }
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_boundary>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -187,6 +205,8 @@ public:
|
|||
const char *func_name() const { return "point"; }
|
||||
String *val_str(String *);
|
||||
Field::geometry_type get_geometry_type() const;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_point>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_spatial_decomp: public Item_geometry_func
|
||||
|
@ -211,6 +231,8 @@ public:
|
|||
}
|
||||
}
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_spatial_decomp>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_spatial_decomp_n: public Item_geometry_func
|
||||
|
@ -235,6 +257,8 @@ public:
|
|||
}
|
||||
}
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_spatial_decomp_n>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_spatial_collection: public Item_geometry_func
|
||||
|
@ -268,6 +292,8 @@ public:
|
|||
}
|
||||
|
||||
const char *func_name() const { return "st_multipoint"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_spatial_collection>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -300,6 +326,7 @@ public:
|
|||
usable_tables, sargables, false);
|
||||
}
|
||||
bool need_parentheses_in_default() { return false; }
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -311,6 +338,8 @@ public:
|
|||
{ }
|
||||
longlong val_int();
|
||||
const char *func_name() const;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_spatial_mbr_rel>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -325,6 +354,8 @@ public:
|
|||
{ }
|
||||
longlong val_int();
|
||||
const char *func_name() const;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_spatial_precise_rel>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -341,6 +372,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "st_relate"; }
|
||||
bool need_parentheses_in_default() { return false; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_spatial_relate>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -370,6 +403,8 @@ public:
|
|||
{
|
||||
Item_func::print(str, query_type);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_spatial_operation>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -421,6 +456,8 @@ public:
|
|||
Item_geometry_func(thd, obj, distance) {}
|
||||
const char *func_name() const { return "st_buffer"; }
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_buffer>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -432,6 +469,8 @@ public:
|
|||
const char *func_name() const { return "st_isempty"; }
|
||||
void fix_length_and_dec() { maybe_null= 1; }
|
||||
bool need_parentheses_in_default() { return false; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_isempty>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_issimple: public Item_int_func
|
||||
|
@ -446,6 +485,8 @@ public:
|
|||
const char *func_name() const { return "st_issimple"; }
|
||||
void fix_length_and_dec() { decimals=0; max_length=2; }
|
||||
uint decimal_precision() const { return 1; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_issimple>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_isclosed: public Item_int_func
|
||||
|
@ -456,6 +497,8 @@ public:
|
|||
const char *func_name() const { return "st_isclosed"; }
|
||||
void fix_length_and_dec() { decimals=0; max_length=2; }
|
||||
uint decimal_precision() const { return 1; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_isclosed>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_isring: public Item_func_issimple
|
||||
|
@ -464,6 +507,8 @@ public:
|
|||
Item_func_isring(THD *thd, Item *a): Item_func_issimple(thd, a) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "st_isring"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_isring>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_dimension: public Item_int_func
|
||||
|
@ -474,6 +519,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "st_dimension"; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dimension>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_x: public Item_real_func
|
||||
|
@ -488,6 +535,8 @@ public:
|
|||
Item_real_func::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_x>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -503,6 +552,8 @@ public:
|
|||
Item_real_func::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_y>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -514,6 +565,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "st_numgeometries"; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_numgeometries>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -525,6 +578,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "st_numinteriorrings"; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_numinteriorring>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -536,6 +591,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "st_numpoints"; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_numpoints>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -551,6 +608,8 @@ public:
|
|||
Item_real_func::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_area>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -566,6 +625,8 @@ public:
|
|||
Item_real_func::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_glength>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -577,6 +638,8 @@ public:
|
|||
longlong val_int();
|
||||
const char *func_name() const { return "srid"; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_srid>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -591,6 +654,8 @@ public:
|
|||
Item_func_distance(THD *thd, Item *a, Item *b): Item_real_func(thd, a, b) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "st_distance"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_distance>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -605,6 +670,8 @@ public:
|
|||
const char *func_name() const { return "st_pointonsurface"; }
|
||||
String *val_str(String *);
|
||||
Field::geometry_type get_geometry_type() const;
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_pointonsurface>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -620,6 +687,8 @@ class Item_func_gis_debug: public Item_int_func
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_gis_debug>(thd, mem_root, this); }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ public:
|
|||
maybe_null= 1;
|
||||
unsigned_flag= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_inet_aton>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -57,6 +59,8 @@ public:
|
|||
fix_length_and_charset(3 * 8 + 7, default_charset());
|
||||
maybe_null= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_inet_ntoa>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -124,6 +128,8 @@ public:
|
|||
fix_length_and_charset(16, &my_charset_bin);
|
||||
maybe_null= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_inet6_aton>(thd, mem_root, this); }
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(String *arg, String *buffer);
|
||||
|
@ -156,6 +162,8 @@ public:
|
|||
|
||||
maybe_null= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_inet6_ntoa>(thd, mem_root, this); }
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(String *arg, String *buffer);
|
||||
|
@ -176,6 +184,8 @@ public:
|
|||
public:
|
||||
virtual const char *func_name() const
|
||||
{ return "is_ipv4"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_is_ipv4>(thd, mem_root, this); }
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(const String *arg);
|
||||
|
@ -196,6 +206,8 @@ public:
|
|||
public:
|
||||
virtual const char *func_name() const
|
||||
{ return "is_ipv6"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_is_ipv6>(thd, mem_root, this); }
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(const String *arg);
|
||||
|
@ -216,6 +228,8 @@ public:
|
|||
public:
|
||||
virtual const char *func_name() const
|
||||
{ return "is_ipv4_compat"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_is_ipv4_compat>(thd, mem_root, this); }
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(const String *arg);
|
||||
|
@ -236,6 +250,8 @@ public:
|
|||
public:
|
||||
virtual const char *func_name() const
|
||||
{ return "is_ipv4_mapped"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_is_ipv4_mapped>(thd, mem_root, this); }
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(const String *arg);
|
||||
|
|
|
@ -160,3 +160,21 @@ void Item_row::bring_value()
|
|||
for (uint i= 0; i < arg_count; i++)
|
||||
args[i]->bring_value();
|
||||
}
|
||||
|
||||
|
||||
Item* Item_row::build_clone(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
Item_row *copy= (Item_row *) get_copy(thd, mem_root);
|
||||
if (!copy)
|
||||
return 0;
|
||||
copy->args= (Item**) alloc_root(mem_root, sizeof(Item*) * arg_count);
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
Item *arg_clone= args[i]->build_clone(thd, mem_root);
|
||||
if (!arg_clone)
|
||||
return 0;
|
||||
copy->args[i]= arg_clone;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,9 @@ public:
|
|||
bool null_inside() { return with_null; };
|
||||
void bring_value();
|
||||
bool check_vcol_func_processor(void *arg) {return FALSE; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_row>(thd, mem_root, this); }
|
||||
Item *build_clone(THD *thd, MEM_ROOT *mem_root);
|
||||
};
|
||||
|
||||
#endif /* ITEM_ROW_INCLUDED */
|
||||
|
|
|
@ -105,6 +105,8 @@ public:
|
|||
String *val_str_ascii(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "md5"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_md5>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -114,7 +116,9 @@ public:
|
|||
Item_func_sha(THD *thd, Item *a): Item_str_ascii_func(thd, a) {}
|
||||
String *val_str_ascii(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "sha"; }
|
||||
const char *func_name() const { return "sha"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sha>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_sha2 :public Item_str_ascii_func
|
||||
|
@ -124,6 +128,8 @@ public:
|
|||
String *val_str_ascii(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "sha2"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sha2>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_to_base64 :public Item_str_ascii_func
|
||||
|
@ -134,6 +140,8 @@ public:
|
|||
String *val_str_ascii(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "to_base64"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_to_base64>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_from_base64 :public Item_str_func
|
||||
|
@ -144,6 +152,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "from_base64"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_from_base64>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#include <my_crypt.h>
|
||||
|
@ -167,6 +177,8 @@ public:
|
|||
Item_aes_crypt(thd, a, b) {}
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "aes_encrypt"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_aes_encrypt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_aes_decrypt :public Item_aes_crypt
|
||||
|
@ -176,6 +188,8 @@ public:
|
|||
Item_aes_crypt(thd, a, b) {}
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "aes_decrypt"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_aes_decrypt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -188,6 +202,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "concat"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_concat>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_decode_histogram :public Item_str_func
|
||||
|
@ -204,6 +220,8 @@ public:
|
|||
maybe_null= 1;
|
||||
}
|
||||
const char *func_name() const { return "decode_histogram"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_decode_histogram>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_concat_ws :public Item_str_func
|
||||
|
@ -215,6 +233,8 @@ public:
|
|||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "concat_ws"; }
|
||||
table_map not_null_tables() const { return 0; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_concat_ws>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_reverse :public Item_str_func
|
||||
|
@ -225,6 +245,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "reverse"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_reverse>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -237,6 +259,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "replace"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_replace>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -260,6 +284,8 @@ public:
|
|||
String *val_str(String *str);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "regexp_replace"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_regexp_replace>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -280,6 +306,8 @@ public:
|
|||
String *val_str(String *str);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "regexp_substr"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_regexp_substr>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -293,6 +321,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "insert"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_insert>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -314,6 +344,8 @@ public:
|
|||
Item_func_lcase(THD *thd, Item *item): Item_str_conv(thd, item) {}
|
||||
const char *func_name() const { return "lcase"; }
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_lcase>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_ucase :public Item_str_conv
|
||||
|
@ -322,6 +354,8 @@ public:
|
|||
Item_func_ucase(THD *thd, Item *item): Item_str_conv(thd, item) {}
|
||||
const char *func_name() const { return "ucase"; }
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ucase>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -333,6 +367,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "left"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_left>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -344,6 +380,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "right"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_right>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -356,6 +394,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "substr"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_substr>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -368,6 +408,9 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "substring_index"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_substr_index>(thd, mem_root, this); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -399,6 +442,8 @@ public:
|
|||
const char *func_name() const { return "trim"; }
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
virtual const char *mode_name() const { return "both"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_trim>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -410,6 +455,8 @@ public:
|
|||
String *val_str(String *);
|
||||
const char *func_name() const { return "ltrim"; }
|
||||
const char *mode_name() const { return "leading"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_ltrim>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -421,6 +468,8 @@ public:
|
|||
String *val_str(String *);
|
||||
const char *func_name() const { return "rtrim"; }
|
||||
const char *mode_name() const { return "trailing"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_rtrim>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -458,6 +507,8 @@ public:
|
|||
"password" : "old_password"); }
|
||||
static char *alloc(THD *thd, const char *password, size_t pass_len,
|
||||
enum PW_Alg al);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_password>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -476,6 +527,8 @@ public:
|
|||
max_length = args[0]->max_length + 9;
|
||||
}
|
||||
const char *func_name() const { return "des_encrypt"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_des_encrypt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_des_decrypt :public Item_str_func
|
||||
|
@ -494,6 +547,8 @@ public:
|
|||
max_length-= 9U;
|
||||
}
|
||||
const char *func_name() const { return "des_decrypt"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_des_decrypt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_encrypt :public Item_str_func
|
||||
|
@ -521,6 +576,8 @@ public:
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_encrypt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#include "sql_crypt.h"
|
||||
|
@ -539,6 +596,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "encode"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_encode>(thd, mem_root, this); }
|
||||
protected:
|
||||
virtual void crypto_transform(String *);
|
||||
private:
|
||||
|
@ -552,6 +611,8 @@ class Item_func_decode :public Item_func_encode
|
|||
public:
|
||||
Item_func_decode(THD *thd, Item *a, Item *seed_arg): Item_func_encode(thd, a, seed_arg) {}
|
||||
const char *func_name() const { return "decode"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_decode>(thd, mem_root, this); }
|
||||
protected:
|
||||
void crypto_transform(String *);
|
||||
};
|
||||
|
@ -592,6 +653,8 @@ public:
|
|||
}
|
||||
const char *func_name() const { return "database"; }
|
||||
const char *fully_qualified_func_name() const { return "database()"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_database>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -622,6 +685,8 @@ public:
|
|||
{
|
||||
return save_str_value_in_field(field, &str_value);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_user>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -665,10 +730,13 @@ public:
|
|||
}
|
||||
bool check_vcol_func_processor(void *arg)
|
||||
{
|
||||
|
||||
context= 0;
|
||||
return mark_unsupported_function(fully_qualified_func_name(), arg,
|
||||
VCOL_SESSION_FUNC);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_current_role>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -680,6 +748,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "soundex"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_soundex>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -692,6 +762,8 @@ public:
|
|||
String *val_str(String *str);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "elt"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_elt>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -704,6 +776,8 @@ public:
|
|||
String *val_str(String *str);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "make_set"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_make_set>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -722,6 +796,8 @@ public:
|
|||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "format"; }
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_format>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -739,6 +815,8 @@ public:
|
|||
max_length= arg_count * 4;
|
||||
}
|
||||
const char *func_name() const { return "char"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_char>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -751,6 +829,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "repeat"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_repeat>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -761,6 +841,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "space"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_space>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -775,8 +857,11 @@ public:
|
|||
const char *func_name() const { return "binlog_gtid_pos"; }
|
||||
bool check_vcol_func_processor(void *arg)
|
||||
{
|
||||
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_binlog_gtid_pos>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -789,6 +874,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "rpad"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_rpad>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -801,6 +888,8 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "lpad"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_lpad>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -817,6 +906,8 @@ public:
|
|||
max_length=64;
|
||||
maybe_null= 1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_conv>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -834,6 +925,8 @@ public:
|
|||
decimals=0;
|
||||
fix_char_length(args[0]->max_length * 2);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_hex>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_unhex :public Item_str_func
|
||||
|
@ -853,6 +946,8 @@ public:
|
|||
decimals=0;
|
||||
max_length=(1+args[0]->max_length)/2;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_unhex>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -883,6 +978,8 @@ public:
|
|||
Item_func_like_range_min(THD *thd, Item *a, Item *b):
|
||||
Item_func_like_range(thd, a, b, true) { }
|
||||
const char *func_name() const { return "like_range_min"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_like_range_min>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -892,6 +989,8 @@ public:
|
|||
Item_func_like_range_max(THD *thd, Item *a, Item *b):
|
||||
Item_func_like_range(thd, a, b, false) { }
|
||||
const char *func_name() const { return "like_range_max"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_like_range_max>(thd, mem_root, this); }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -917,6 +1016,8 @@ public:
|
|||
virtual void print(String *str, enum_query_type query_type);
|
||||
const char *func_name() const { return "cast_as_binary"; }
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_binary>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -937,6 +1038,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_load_file>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -952,6 +1055,8 @@ class Item_func_export_set: public Item_str_func
|
|||
String *val_str(String *str);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "export_set"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_export_set>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -969,6 +1074,8 @@ public:
|
|||
2 * collation.collation->mbmaxlen;
|
||||
max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_quote>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_conv_charset :public Item_str_func
|
||||
|
@ -1051,6 +1158,8 @@ public:
|
|||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "convert"; }
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_conv_charset>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_set_collation :public Item_str_func
|
||||
|
@ -1070,6 +1179,8 @@ public:
|
|||
return args[0]->field_for_view_update();
|
||||
}
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_set_collation>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1097,6 +1208,8 @@ public:
|
|||
:Item_func_expr_str_metadata(thd, a) { }
|
||||
String *val_str(String *);
|
||||
const char *func_name() const { return "charset"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_charset>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1107,6 +1220,8 @@ public:
|
|||
:Item_func_expr_str_metadata(thd, a) {}
|
||||
String *val_str(String *);
|
||||
const char *func_name() const { return "collation"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_collation>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1139,6 +1254,8 @@ public:
|
|||
}
|
||||
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
|
||||
{ return this; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_weight_string>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_crc32 :public Item_int_func
|
||||
|
@ -1150,6 +1267,8 @@ public:
|
|||
const char *func_name() const { return "crc32"; }
|
||||
void fix_length_and_dec() { max_length=10; }
|
||||
longlong val_int();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_crc32>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_uncompressed_length : public Item_int_func
|
||||
|
@ -1160,6 +1279,8 @@ public:
|
|||
const char *func_name() const{return "uncompressed_length";}
|
||||
void fix_length_and_dec() { max_length=10; maybe_null= true; }
|
||||
longlong val_int();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_uncompressed_length>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#ifdef HAVE_COMPRESS
|
||||
|
@ -1176,6 +1297,8 @@ public:
|
|||
void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
|
||||
const char *func_name() const{return "compress";}
|
||||
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_compress>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_uncompress: public Item_str_func
|
||||
|
@ -1186,6 +1309,8 @@ public:
|
|||
void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
|
||||
const char *func_name() const{return "uncompress";}
|
||||
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_uncompress>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1205,6 +1330,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_uuid>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1226,6 +1353,8 @@ public:
|
|||
String *val_str(String *);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
virtual enum Functype functype() const { return DYNCOL_FUNC; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dyncol_create>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1238,6 +1367,8 @@ public:
|
|||
const char *func_name() const{ return "column_add"; }
|
||||
String *val_str(String *);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dyncol_add>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_dyncol_json: public Item_str_func
|
||||
|
@ -1253,6 +1384,8 @@ public:
|
|||
collation.set(&my_charset_bin);
|
||||
decimals= 0;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dyncol_json>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1293,6 +1426,8 @@ public:
|
|||
bool get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val, String *tmp);
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_dyncol_get>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1303,6 +1438,8 @@ public:
|
|||
void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; };
|
||||
const char *func_name() const{ return "column_list"; }
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dyncol_list>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#endif /* ITEM_STRFUNC_INCLUDED */
|
||||
|
|
|
@ -257,6 +257,9 @@ public:
|
|||
}
|
||||
|
||||
void init_expr_cache_tracker(THD *thd);
|
||||
|
||||
Item* build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
|
||||
|
||||
friend class select_result_interceptor;
|
||||
|
|
|
@ -768,6 +768,8 @@ public:
|
|||
}
|
||||
Item *copy_or_same(THD* thd);
|
||||
void remove();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_sum>(thd, mem_root, this); }
|
||||
|
||||
private:
|
||||
void add_helper(bool perform_removal);
|
||||
|
@ -825,6 +827,8 @@ class Item_sum_count :public Item_sum_int
|
|||
return has_with_distinct() ? "count(distinct " : "count(";
|
||||
}
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_count>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -872,6 +876,8 @@ public:
|
|||
count= 0;
|
||||
Item_sum_sum::cleanup();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_avg>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -930,6 +936,8 @@ public:
|
|||
count= 0;
|
||||
Item_sum_num::cleanup();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_variance>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -949,6 +957,8 @@ class Item_sum_std :public Item_sum_variance
|
|||
Item *result_item(THD *thd, Field *field);
|
||||
const char *func_name() const { return "std("; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_std>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
// This class is a string or number function depending on num_func
|
||||
|
@ -1014,6 +1024,8 @@ public:
|
|||
bool add();
|
||||
const char *func_name() const { return "min("; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_min>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1027,6 +1039,8 @@ public:
|
|||
bool add();
|
||||
const char *func_name() const { return "max("; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_max>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1101,6 +1115,8 @@ public:
|
|||
bool add();
|
||||
const char *func_name() const { return "bit_or("; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_or>(thd, mem_root, this); }
|
||||
|
||||
private:
|
||||
void set_bits_from_counters();
|
||||
|
@ -1116,6 +1132,8 @@ public:
|
|||
bool add();
|
||||
const char *func_name() const { return "bit_and("; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_and>(thd, mem_root, this); }
|
||||
|
||||
private:
|
||||
void set_bits_from_counters();
|
||||
|
@ -1129,6 +1147,8 @@ public:
|
|||
bool add();
|
||||
const char *func_name() const { return "bit_xor("; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_xor>(thd, mem_root, this); }
|
||||
|
||||
private:
|
||||
void set_bits_from_counters();
|
||||
|
@ -1187,6 +1207,8 @@ public:
|
|||
my_decimal *val_decimal(my_decimal *dec) { return val_decimal_from_real(dec); }
|
||||
String *val_str(String *str) { return val_string_from_real(str); }
|
||||
double val_real();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_avg_field_double>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1206,6 +1228,8 @@ public:
|
|||
longlong val_int() { return val_int_from_decimal(); }
|
||||
String *val_str(String *str) { return val_string_from_decimal(str); }
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_avg_field_decimal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1226,6 +1250,8 @@ public:
|
|||
bool is_null() { update_null_value(); return null_value; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||
enum Item_result result_type () const { return REAL_RESULT; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_variance_field>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1237,6 +1263,8 @@ public:
|
|||
{ }
|
||||
enum Type type() const { return FIELD_STD_ITEM; }
|
||||
double val_real();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_std_field>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1324,6 +1352,8 @@ class Item_sum_udf_float :public Item_udf_sum
|
|||
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||
void fix_length_and_dec() { fix_num_length_and_dec(); }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_udf_float>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1345,6 +1375,8 @@ public:
|
|||
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
|
||||
void fix_length_and_dec() { decimals=0; max_length=21; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_udf_int>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1385,6 +1417,8 @@ public:
|
|||
enum_field_types field_type() const { return string_field_type(); }
|
||||
void fix_length_and_dec();
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_udf_str>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1405,6 +1439,8 @@ public:
|
|||
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
|
||||
void fix_length_and_dec() { fix_num_length_and_dec(); }
|
||||
Item *copy_or_same(THD* thd);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_udf_decimal>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#else /* Dummy functions to get sql_yacc.cc compiled */
|
||||
|
@ -1598,6 +1634,8 @@ public:
|
|||
virtual void print(String *str, enum_query_type query_type);
|
||||
virtual bool change_context_processor(void *cntx)
|
||||
{ context= (Name_resolution_context *)cntx; return FALSE; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_group_concat>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#endif /* ITEM_SUM_INCLUDED */
|
||||
|
|
|
@ -53,6 +53,8 @@ public:
|
|||
{
|
||||
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_period_add>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -67,6 +69,8 @@ public:
|
|||
decimals=0;
|
||||
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_period_diff>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -90,6 +94,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_to_days>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -123,6 +129,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_to_seconds>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -144,6 +152,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dayofmonth>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -178,6 +188,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_month>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -196,8 +208,11 @@ public:
|
|||
}
|
||||
bool check_vcol_func_processor(void *arg)
|
||||
{
|
||||
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_monthname>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -219,6 +234,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_dayofyear>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -240,6 +257,8 @@ public:
|
|||
{
|
||||
return !has_time_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_hour>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -261,6 +280,8 @@ public:
|
|||
{
|
||||
return !has_time_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_minute>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -282,6 +303,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_quarter>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -303,6 +326,8 @@ public:
|
|||
{
|
||||
return !has_time_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_second>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -318,6 +343,8 @@ public:
|
|||
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
maybe_null=1;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_week>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_yearweek :public Item_int_func
|
||||
|
@ -338,6 +365,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_yearweek>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -361,6 +390,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_year>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -396,6 +427,8 @@ public:
|
|||
{
|
||||
return !has_date_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_weekday>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_dayname :public Item_func_weekday
|
||||
|
@ -468,6 +501,8 @@ public:
|
|||
}
|
||||
longlong int_op();
|
||||
my_decimal *decimal_op(my_decimal* buf);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_unix_timestamp>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -487,6 +522,8 @@ public:
|
|||
}
|
||||
longlong int_op();
|
||||
my_decimal *decimal_op(my_decimal* buf);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_time_to_sec>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -625,6 +662,8 @@ public:
|
|||
Item_func_curtime_local(THD *thd, uint dec): Item_func_curtime(thd, dec) {}
|
||||
const char *func_name() const { return "curtime"; }
|
||||
virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_curtime_local>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -634,6 +673,8 @@ public:
|
|||
Item_func_curtime_utc(THD *thd, uint dec): Item_func_curtime(thd, dec) {}
|
||||
const char *func_name() const { return "utc_time"; }
|
||||
virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_curtime_utc>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -661,6 +702,8 @@ public:
|
|||
Item_func_curdate_local(THD *thd): Item_func_curdate(thd) {}
|
||||
const char *func_name() const { return "curdate"; }
|
||||
void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_curdate_local>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -670,6 +713,8 @@ public:
|
|||
Item_func_curdate_utc(THD *thd): Item_func_curdate(thd) {}
|
||||
const char *func_name() const { return "utc_date"; }
|
||||
void store_now_in_TIME(THD* thd, MYSQL_TIME *now_time);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_curdate_utc>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -703,6 +748,8 @@ public:
|
|||
const char *func_name() const { return "now"; }
|
||||
virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time);
|
||||
virtual enum Functype functype() const { return NOW_FUNC; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_now_local>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -718,7 +765,8 @@ public:
|
|||
return mark_unsupported_function(func_name(), "()", arg,
|
||||
VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC);
|
||||
}
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_now_utc>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -741,6 +789,8 @@ public:
|
|||
VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC);
|
||||
}
|
||||
virtual enum Functype functype() const { return SYSDATE_FUNC; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sysdate_local>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -756,6 +806,8 @@ public:
|
|||
{
|
||||
return has_date_args() || has_time_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_from_days>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -778,6 +830,8 @@ public:
|
|||
{
|
||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_date_format>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -789,6 +843,8 @@ class Item_func_from_unixtime :public Item_datetimefunc
|
|||
const char *func_name() const { return "from_unixtime"; }
|
||||
void fix_length_and_dec();
|
||||
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_from_unixtime>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -823,6 +879,8 @@ class Item_func_convert_tz :public Item_datetimefunc
|
|||
void fix_length_and_dec();
|
||||
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||
void cleanup();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_convert_tz>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -837,6 +895,8 @@ public:
|
|||
Item_timefunc::fix_length_and_dec();
|
||||
}
|
||||
const char *func_name() const { return "sec_to_time"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_sec_to_time>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -855,6 +915,8 @@ public:
|
|||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
void print(String *str, enum_query_type query_type);
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_date_add_interval>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -909,6 +971,8 @@ class Item_extract :public Item_int_func
|
|||
}
|
||||
return true;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_extract>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -933,6 +997,8 @@ public:
|
|||
void fix_length_and_dec();
|
||||
void print(String *str, enum_query_type query_type);
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_char_typecast>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -958,6 +1024,8 @@ public:
|
|||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
|
||||
const char *cast_type() const { return "date"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_date_typecast>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -970,6 +1038,8 @@ public:
|
|||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
|
||||
const char *cast_type() const { return "time"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_time_typecast>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -982,6 +1052,8 @@ public:
|
|||
const char *cast_type() const { return "datetime"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_datetime_typecast>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -993,6 +1065,8 @@ public:
|
|||
const char *func_name() const { return "makedate"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_makedate>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1009,6 +1083,8 @@ public:
|
|||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
|
||||
void print(String *str, enum_query_type query_type);
|
||||
const char *func_name() const { return "add_time"; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_add_time>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_timediff :public Item_timefunc
|
||||
|
@ -1023,6 +1099,8 @@ public:
|
|||
Item_timefunc::fix_length_and_dec();
|
||||
}
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_timediff>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
class Item_func_maketime :public Item_timefunc
|
||||
|
@ -1038,6 +1116,8 @@ public:
|
|||
}
|
||||
const char *func_name() const { return "maketime"; }
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_maketime>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1058,6 +1138,8 @@ public:
|
|||
{
|
||||
return !has_time_args();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_microsecond>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1075,6 +1157,8 @@ public:
|
|||
maybe_null=1;
|
||||
}
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_timestamp_diff>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1099,6 +1183,8 @@ public:
|
|||
fix_length_and_charset(17, default_charset());
|
||||
}
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_get_format>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1117,6 +1203,8 @@ public:
|
|||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
|
||||
const char *func_name() const { return "str_to_date"; }
|
||||
void fix_length_and_dec();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_str_to_date>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1126,6 +1214,8 @@ public:
|
|||
Item_func_last_day(THD *thd, Item *a): Item_datefunc(thd, a) {}
|
||||
const char *func_name() const { return "last_day"; }
|
||||
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_last_day>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#endif /* ITEM_TIMEFUNC_INCLUDED */
|
||||
|
|
|
@ -119,7 +119,8 @@ public:
|
|||
{
|
||||
return "row_number(";
|
||||
}
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_row_number>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -188,6 +189,8 @@ public:
|
|||
peer_tracker.cleanup();
|
||||
Item_sum_int::cleanup();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_rank>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -251,6 +254,8 @@ class Item_sum_dense_rank: public Item_sum_int
|
|||
peer_tracker.cleanup();
|
||||
Item_sum_int::cleanup();
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_dense_rank>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -342,6 +347,8 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
|
|||
}
|
||||
|
||||
void setup_window_func(THD *thd, Window_spec *window_spec);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_percent_rank>(thd, mem_root, this); }
|
||||
|
||||
private:
|
||||
longlong cur_rank; // Current rank of the current row.
|
||||
|
@ -419,6 +426,9 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
|
|||
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
|
||||
// requires.
|
||||
}
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_cume_dist>(thd, mem_root, this); }
|
||||
|
||||
private:
|
||||
ulonglong current_row_count_;
|
||||
|
@ -487,6 +497,9 @@ class Item_sum_ntile : public Item_sum_window_with_row_count
|
|||
|
||||
enum Item_result result_type () const { return INT_RESULT; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_ntile>(thd, mem_root, this); }
|
||||
|
||||
private:
|
||||
longlong get_num_quantiles() { return args[0]->val_int(); }
|
||||
|
@ -751,6 +764,8 @@ public:
|
|||
bool fix_fields(THD *thd, Item **ref);
|
||||
|
||||
bool resolve_window_name(THD *thd);
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -250,6 +250,8 @@ public:
|
|||
Item_nodeset_func(thd, pxml) {}
|
||||
const char *func_name() const { return "xpath_rootelement"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_rootelement>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -261,6 +263,8 @@ public:
|
|||
Item_nodeset_func(thd, a, b, pxml) {}
|
||||
const char *func_name() const { return "xpath_union"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_union>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -293,6 +297,8 @@ public:
|
|||
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
|
||||
const char *func_name() const { return "xpath_selfbyname"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_selfbyname>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -305,6 +311,8 @@ public:
|
|||
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
|
||||
const char *func_name() const { return "xpath_childbyname"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_childbyname>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -319,6 +327,8 @@ public:
|
|||
need_self(need_self_arg) {}
|
||||
const char *func_name() const { return "xpath_descendantbyname"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_descendantbyname>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -333,6 +343,8 @@ public:
|
|||
need_self(need_self_arg) {}
|
||||
const char *func_name() const { return "xpath_ancestorbyname"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_ancestorbyname>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -345,6 +357,8 @@ public:
|
|||
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
|
||||
const char *func_name() const { return "xpath_parentbyname"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_parentbyname>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -357,6 +371,8 @@ public:
|
|||
Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {}
|
||||
const char *func_name() const { return "xpath_attributebyname"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_attributebyname>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -372,6 +388,8 @@ public:
|
|||
Item_nodeset_func(thd, a, b, pxml) {}
|
||||
const char *func_name() const { return "xpath_predicate"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_predicate>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -383,6 +401,8 @@ public:
|
|||
Item_nodeset_func(thd, a, b, pxml) { }
|
||||
const char *func_name() const { return "xpath_elementbyindex"; }
|
||||
String *val_nodeset(String *nodeset);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_func_elementbyindex>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -422,6 +442,8 @@ public:
|
|||
}
|
||||
return args[0]->val_real() ? 1 : 0;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_xpath_cast_bool>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -434,6 +456,8 @@ public:
|
|||
Item_xpath_cast_number(THD *thd, Item *a): Item_real_func(thd, a) {}
|
||||
const char *func_name() const { return "xpath_cast_number"; }
|
||||
virtual double val_real() { return args[0]->val_real(); }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_xpath_cast_number>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -449,6 +473,8 @@ public:
|
|||
String *val_nodeset(String *res)
|
||||
{ return string_cache; }
|
||||
void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; }
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_context_cache>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -468,6 +494,8 @@ public:
|
|||
return ((MY_XPATH_FLT*)flt->ptr())->pos + 1;
|
||||
return 0;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_xpath_position>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -489,6 +517,8 @@ public:
|
|||
return predicate_supplied_context_size;
|
||||
return res->length() / sizeof(MY_XPATH_FLT);
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_xpath_count>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -532,6 +562,8 @@ public:
|
|||
}
|
||||
return sum;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_xpath_sum>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -608,6 +640,8 @@ public:
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_nodeset_to_const_comparator>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@ public:
|
|||
Item_xml_str_func(thd, a, b) {}
|
||||
const char *func_name() const { return "extractvalue"; }
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_xml_extractvalue>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -115,6 +117,8 @@ public:
|
|||
Item_xml_str_func(thd, a, b, c) {}
|
||||
const char *func_name() const { return "updatexml"; }
|
||||
String *val_str(String *);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_xml_update>(thd, mem_root, this); }
|
||||
};
|
||||
|
||||
#endif /* ITEM_XMLFUNC_INCLUDED */
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
DBUG_ASSERT(0); // impossible
|
||||
return mark_unsupported_function("proc", arg, VCOL_IMPOSSIBLE);
|
||||
}
|
||||
Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
|
||||
};
|
||||
|
||||
class Item_proc_real :public Item_proc
|
||||
|
|
|
@ -1100,3 +1100,137 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
|
|||
unit->set_thd(thd);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Extract the condition depended on derived table/view and pushed it there
|
||||
|
||||
@param thd The thread handle
|
||||
@param cond The condition from which to extract the pushed condition
|
||||
@param derived The reference to the derived table/view
|
||||
|
||||
@details
|
||||
This functiom builds the most restrictive condition depending only on
|
||||
the derived table/view that can be extracted from the condition cond.
|
||||
The built condition is pushed into the having clauses of the
|
||||
selects contained in the query specifying the derived table/view.
|
||||
The function also checks for each select whether any condition depending
|
||||
only on grouping fields can be extracted from the pushed condition.
|
||||
If so, it pushes the condition over grouping fields into the where
|
||||
clause of the select.
|
||||
|
||||
@retval
|
||||
true if an error is reported
|
||||
false otherwise
|
||||
*/
|
||||
|
||||
bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
|
||||
{
|
||||
if (!cond)
|
||||
return false;
|
||||
/*
|
||||
Build the most restrictive condition extractable from 'cond'
|
||||
that can be pushed into the derived table 'derived'.
|
||||
All subexpressions of this condition are cloned from the
|
||||
subexpressions of 'cond'.
|
||||
This condition has to be fixed yet.
|
||||
*/
|
||||
Item *extracted_cond;
|
||||
derived->check_pushable_cond_for_table(cond);
|
||||
extracted_cond= derived->build_pushable_cond_for_table(thd, cond);
|
||||
if (!extracted_cond)
|
||||
{
|
||||
/* Nothing can be pushed into the derived table */
|
||||
return false;
|
||||
}
|
||||
/* Push extracted_cond into every select of the unit specifying 'derived' */
|
||||
st_select_lex_unit *unit= derived->get_unit();
|
||||
st_select_lex *save_curr_select= thd->lex->current_select;
|
||||
st_select_lex *sl= unit->first_select();
|
||||
for (; sl; sl= sl->next_select())
|
||||
{
|
||||
thd->lex->current_select= sl;
|
||||
/*
|
||||
For each select of the unit except the last one
|
||||
create a clone of extracted_cond
|
||||
*/
|
||||
Item *extracted_cond_copy= !sl->next_select() ? extracted_cond :
|
||||
extracted_cond->build_clone(thd, thd->mem_root);
|
||||
if (!extracted_cond_copy)
|
||||
continue;
|
||||
|
||||
/*
|
||||
Figure out what can be extracted from the pushed condition
|
||||
that could be pushed into the where clause of sl
|
||||
*/
|
||||
Item *cond_over_grouping_fields;
|
||||
sl->collect_grouping_fields(thd);
|
||||
sl->check_cond_extraction_for_grouping_fields(extracted_cond_copy,
|
||||
&Item::exclusive_dependence_on_grouping_fields_processor);
|
||||
cond_over_grouping_fields=
|
||||
sl->build_cond_for_grouping_fields(thd, extracted_cond_copy, true);
|
||||
|
||||
/*
|
||||
Transform the references to the 'derived' columns from the condition
|
||||
pushed into the where clause of sl to make them usable in the new context
|
||||
*/
|
||||
if (cond_over_grouping_fields)
|
||||
cond_over_grouping_fields= cond_over_grouping_fields->transform(thd,
|
||||
&Item::derived_field_transformer_for_where,
|
||||
(uchar*) sl);
|
||||
|
||||
if (cond_over_grouping_fields)
|
||||
{
|
||||
/*
|
||||
In extracted_cond_copy remove top conjuncts that
|
||||
has been pushed into the where clause of sl
|
||||
*/
|
||||
extracted_cond_copy= remove_pushed_top_conjuncts(thd, extracted_cond_copy);
|
||||
|
||||
/*
|
||||
Create the conjunction of the existing where condition of sl
|
||||
and the pushed condition, take it as the new where condition of sl
|
||||
and fix this new condition
|
||||
*/
|
||||
cond_over_grouping_fields->walk(&Item::cleanup_processor, 0, 0);
|
||||
thd->change_item_tree(&sl->join->conds,
|
||||
and_conds(thd, sl->join->conds,
|
||||
cond_over_grouping_fields));
|
||||
|
||||
if (sl->join->conds->fix_fields(thd, &sl->join->conds))
|
||||
goto err;
|
||||
|
||||
if (!extracted_cond_copy)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
Transform the references to the 'derived' columns from the condition
|
||||
pushed into the having clause of sl to make them usable in the new context
|
||||
*/
|
||||
extracted_cond_copy= extracted_cond_copy->transform(thd,
|
||||
&Item::derived_field_transformer_for_having,
|
||||
(uchar*) sl);
|
||||
if (!extracted_cond_copy)
|
||||
continue;
|
||||
/*
|
||||
Create the conjunction of the existing having condition of sl
|
||||
and the pushed condition, take it as the new having condition of sl
|
||||
and fix this new condition
|
||||
*/
|
||||
extracted_cond_copy->walk(&Item::cleanup_processor, 0, 0);
|
||||
thd->change_item_tree(&sl->join->having,
|
||||
and_conds(thd, sl->join->having,
|
||||
extracted_cond_copy));
|
||||
sl->having_fix_field= 1;
|
||||
if (sl->join->having->fix_fields(thd, &sl->join->having))
|
||||
return true;
|
||||
sl->having_fix_field= 0;
|
||||
}
|
||||
thd->lex->current_select= save_curr_select;
|
||||
return false;
|
||||
err:
|
||||
thd->lex->current_select= save_curr_select;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -37,4 +37,12 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived);
|
|||
*/
|
||||
bool mysql_derived_cleanup(THD *thd, LEX *lex, TABLE_LIST *derived);
|
||||
|
||||
Item *delete_not_needed_parts(THD *thd, Item *cond);
|
||||
|
||||
#if 0
|
||||
bool pushdown_cond_for_derived(THD *thd, Item **cond, TABLE_LIST *derived);
|
||||
#else
|
||||
bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived);
|
||||
#endif
|
||||
|
||||
#endif /* SQL_DERIVED_INCLUDED */
|
||||
|
|
188
sql/sql_lex.cc
188
sql/sql_lex.cc
|
@ -4915,3 +4915,191 @@ void binlog_unsafe_map_init()
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Finding fiels that are used in the GROUP BY of this st_select_lex
|
||||
|
||||
@param thd The thread handle
|
||||
|
||||
@details
|
||||
This method looks through the fields which are used in the GROUP BY of this
|
||||
st_select_lex and saves this fields.
|
||||
*/
|
||||
|
||||
void st_select_lex::collect_grouping_fields(THD *thd)
|
||||
{
|
||||
List_iterator<Item> li(join->fields_list);
|
||||
Item *item= li++;
|
||||
for (uint i= 0; i < master_unit()->derived->table->s->fields; i++, (item=li++))
|
||||
{
|
||||
for (ORDER *ord= join->group_list; ord; ord= ord->next)
|
||||
{
|
||||
if ((*ord->item)->eq((Item*)item, 0))
|
||||
{
|
||||
Grouping_tmp_field *grouping_tmp_field=
|
||||
new Grouping_tmp_field(master_unit()->derived->table->field[i], item);
|
||||
grouping_tmp_fields.push_back(grouping_tmp_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief
|
||||
For a condition check possibility of exraction a formula over grouping fields
|
||||
|
||||
@param cond The condition whose subformulas are to be analyzed
|
||||
|
||||
@details
|
||||
This method traverses the AND-OR condition cond and for each subformula of
|
||||
the condition it checks whether it can be usable for the extraction of a
|
||||
condition over the grouping fields of this select. The method uses
|
||||
the call-back parameter check_processor to ckeck whether a primary formula
|
||||
depends only on grouping fields.
|
||||
The subformulas that are not usable are marked with the flag NO_EXTRACTION_FL.
|
||||
The subformulas that can be entierly extracted are marked with the flag
|
||||
FULL_EXTRACTION_FL.
|
||||
@note
|
||||
This method is called before any call of extract_cond_for_grouping_fields.
|
||||
The flag NO_EXTRACTION_FL set in a subformula allows to avoid building clone
|
||||
for the subformula when extracting the pushable condition.
|
||||
The flag FULL_EXTRACTION_FL allows to delete later all top level conjuncts
|
||||
from cond.
|
||||
*/
|
||||
|
||||
void st_select_lex::check_cond_extraction_for_grouping_fields(Item *cond,
|
||||
Item_processor check_processor)
|
||||
{
|
||||
cond->clear_extraction_flag();
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
bool and_cond= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
|
||||
List<Item> *arg_list= ((Item_cond*) cond)->argument_list();
|
||||
List_iterator<Item> li(*arg_list);
|
||||
uint count= 0; // to count items not containing NO_EXTRACTION_FL
|
||||
uint count_full= 0; // to count items with FULL_EXTRACTION_FL
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
check_cond_extraction_for_grouping_fields(item, check_processor);
|
||||
if (item->get_extraction_flag() != NO_EXTRACTION_FL)
|
||||
{
|
||||
count++;
|
||||
if (item->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
count_full++;
|
||||
}
|
||||
else if (!and_cond)
|
||||
break;
|
||||
}
|
||||
if ((and_cond && count == 0) || item)
|
||||
cond->set_extraction_flag(NO_EXTRACTION_FL);
|
||||
if (count_full == arg_list->elements)
|
||||
cond->set_extraction_flag(FULL_EXTRACTION_FL);
|
||||
if (cond->get_extraction_flag() != 0)
|
||||
{
|
||||
li.rewind();
|
||||
while ((item=li++))
|
||||
item->clear_extraction_flag();
|
||||
}
|
||||
}
|
||||
else
|
||||
cond->set_extraction_flag(cond->walk(check_processor,
|
||||
0, (uchar *) this) ?
|
||||
NO_EXTRACTION_FL : FULL_EXTRACTION_FL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Build condition extractable from the given one depended on grouping fields
|
||||
|
||||
@param thd The thread handle
|
||||
@param cond The condition from which the condition depended
|
||||
on grouping fields is to be extracted
|
||||
@param no_top_clones If it's true then no clones for the top fully
|
||||
extractable conjuncts are built
|
||||
|
||||
@details
|
||||
For the given condition cond this method finds out what condition depended
|
||||
only on the grouping fields can be extracted from cond. If such condition C
|
||||
exists the method builds the item for it.
|
||||
This method uses the flags NO_EXTRACTION_FL and FULL_EXTRACTION_FL set by the
|
||||
preliminary call of st_select_lex::check_cond_extraction_for_grouping_fields
|
||||
to figure out whether a subformula depends only on these fields or not.
|
||||
@note
|
||||
The built condition C is always implied by the condition cond
|
||||
(cond => C). The method tries to build the most restictive such
|
||||
condition (i.e. for any other condition C' such that cond => C'
|
||||
we have C => C').
|
||||
@note
|
||||
The build item is not ready for usage: substitution for the field items
|
||||
has to be done and it has to be re-fixed.
|
||||
|
||||
@retval
|
||||
the built condition depended only on grouping fields if such a condition exists
|
||||
NULL if there is no such a condition
|
||||
*/
|
||||
|
||||
Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond,
|
||||
bool no_top_clones)
|
||||
{
|
||||
if (cond->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
{
|
||||
if (no_top_clones)
|
||||
return cond;
|
||||
cond->clear_extraction_flag();
|
||||
return cond->build_clone(thd, thd->mem_root);
|
||||
}
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
bool cond_and= false;
|
||||
Item_cond *new_cond;
|
||||
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
|
||||
{
|
||||
cond_and= true;
|
||||
new_cond= new (thd->mem_root) Item_cond_and(thd);
|
||||
}
|
||||
else
|
||||
new_cond= new (thd->mem_root) Item_cond_or(thd);
|
||||
if (!new_cond)
|
||||
return 0;
|
||||
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
{
|
||||
DBUG_ASSERT(cond_and);
|
||||
item->clear_extraction_flag();
|
||||
continue;
|
||||
}
|
||||
Item *fix= build_cond_for_grouping_fields(thd, item,
|
||||
no_top_clones & cond_and);
|
||||
if (!fix)
|
||||
{
|
||||
if (cond_and)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
new_cond->argument_list()->push_back(fix, thd->mem_root);
|
||||
}
|
||||
|
||||
if (!cond_and && item)
|
||||
{
|
||||
while((item= li++))
|
||||
item->clear_extraction_flag();
|
||||
return 0;
|
||||
}
|
||||
switch (new_cond->argument_list()->elements)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return new_cond->argument_list()->head();
|
||||
default:
|
||||
return new_cond;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -738,6 +738,21 @@ public:
|
|||
typedef class st_select_lex_unit SELECT_LEX_UNIT;
|
||||
typedef Bounds_checked_array<Item*> Ref_ptr_array;
|
||||
|
||||
|
||||
/*
|
||||
Structure which consists of the field and the item which
|
||||
produces this field.
|
||||
*/
|
||||
|
||||
class Grouping_tmp_field :public Sql_alloc
|
||||
{
|
||||
public:
|
||||
Field *tmp_field;
|
||||
Item *producing_item;
|
||||
Grouping_tmp_field(Field *fld, Item *item)
|
||||
:tmp_field(fld), producing_item(item) {}
|
||||
};
|
||||
|
||||
/*
|
||||
SELECT_LEX - store information of parsed SELECT statment
|
||||
*/
|
||||
|
@ -922,8 +937,9 @@ public:
|
|||
|
||||
/* namp of nesting SELECT visibility (for aggregate functions check) */
|
||||
nesting_map name_visibility_map;
|
||||
|
||||
|
||||
table_map with_dep;
|
||||
List<Grouping_tmp_field> grouping_tmp_fields;
|
||||
|
||||
void init_query();
|
||||
void init_select();
|
||||
|
@ -1110,6 +1126,11 @@ public:
|
|||
With_element *find_table_def_in_with_clauses(TABLE_LIST *table);
|
||||
bool check_unrestricted_recursive(bool only_standards_compliant);
|
||||
bool check_subqueries_with_recursive_references();
|
||||
void collect_grouping_fields(THD *thd);
|
||||
void check_cond_extraction_for_grouping_fields(Item *cond,
|
||||
Item_processor processor);
|
||||
Item *build_cond_for_grouping_fields(THD *thd, Item *cond,
|
||||
bool no_to_clones);
|
||||
|
||||
List<Window_spec> window_specs;
|
||||
void prepare_add_window_spec(THD *thd);
|
||||
|
@ -3221,6 +3242,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
extern sql_digest_state *
|
||||
digest_add_token(sql_digest_state *state, uint token, LEX_YYSTYPE yylval);
|
||||
|
||||
|
|
|
@ -226,6 +226,7 @@
|
|||
#define OPTIMIZER_SWITCH_EXTENDED_KEYS (1ULL << 27)
|
||||
#define OPTIMIZER_SWITCH_EXISTS_TO_IN (1ULL << 28)
|
||||
#define OPTIMIZER_SWITCH_ORDERBY_EQ_PROP (1ULL << 29)
|
||||
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED (1ULL << 30)
|
||||
|
||||
#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
|
||||
|
@ -249,7 +250,8 @@
|
|||
OPTIMIZER_SWITCH_SEMIJOIN | \
|
||||
OPTIMIZER_SWITCH_FIRSTMATCH | \
|
||||
OPTIMIZER_SWITCH_LOOSE_SCAN | \
|
||||
OPTIMIZER_SWITCH_EXISTS_TO_IN)
|
||||
OPTIMIZER_SWITCH_EXISTS_TO_IN | \
|
||||
OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED)
|
||||
/*
|
||||
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
|
||||
use strictly more than 64 bits by adding one more define above, you should
|
||||
|
|
|
@ -1131,11 +1131,14 @@ int JOIN::optimize()
|
|||
int
|
||||
JOIN::optimize_inner()
|
||||
{
|
||||
/*
|
||||
if (conds) { Item *it_clone= conds->build_clone(thd,thd->mem_root); }
|
||||
*/
|
||||
ulonglong select_opts_for_readinfo;
|
||||
uint no_jbuf_after;
|
||||
JOIN_TAB *tab;
|
||||
DBUG_ENTER("JOIN::optimize");
|
||||
|
||||
dbug_print_item(conds);
|
||||
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
|
||||
// to prevent double initialization on EXPLAIN
|
||||
if (optimized)
|
||||
|
@ -1148,10 +1151,6 @@ JOIN::optimize_inner()
|
|||
set_allowed_join_cache_types();
|
||||
need_distinct= TRUE;
|
||||
|
||||
/* Run optimize phase for all derived tables/views used in this SELECT. */
|
||||
if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (select_lex->first_cond_optimization)
|
||||
{
|
||||
//Do it only for the first execution
|
||||
|
@ -1263,9 +1262,32 @@ JOIN::optimize_inner()
|
|||
|
||||
if (setup_jtbm_semi_joins(this, join_list, &conds))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
|
||||
conds= optimize_cond(this, conds, join_list, FALSE,
|
||||
&cond_value, &cond_equal, OPT_LINK_EQUAL_FIELDS);
|
||||
|
||||
if (thd->lex->sql_command == SQLCOM_SELECT &&
|
||||
optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED))
|
||||
{
|
||||
TABLE_LIST *tbl;
|
||||
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
|
||||
while ((tbl= li++))
|
||||
{
|
||||
if (tbl->is_materialized_derived())
|
||||
{
|
||||
if (pushdown_cond_for_derived(thd, conds, tbl))
|
||||
DBUG_RETURN(1);
|
||||
if (mysql_handle_single_derived(thd->lex, tbl, DT_OPTIMIZE))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Run optimize phase for all derived tables/views used in this SELECT. */
|
||||
if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if (thd->is_error())
|
||||
{
|
||||
|
@ -26207,6 +26229,61 @@ AGGR_OP::end_send()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Remove marked top conjuncts of a condition
|
||||
|
||||
@param thd The thread handle
|
||||
@param cond The condition which subformulas are to be removed
|
||||
|
||||
@details
|
||||
The function removes all top conjuncts marked with the flag
|
||||
FULL_EXTRACTION_FL from the condition 'cond'. The resulting
|
||||
formula is returned a the result of the function
|
||||
If 'cond' s marked with such flag the function returns 0.
|
||||
The function clear the extraction flags for the removed
|
||||
formulas
|
||||
|
||||
@retval
|
||||
condition without removed subformulas
|
||||
0 if the whole 'cond' is removed
|
||||
*/
|
||||
|
||||
Item *remove_pushed_top_conjuncts(THD *thd, Item *cond)
|
||||
{
|
||||
if (cond->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
{
|
||||
cond->clear_extraction_flag();
|
||||
return 0;
|
||||
}
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
|
||||
{
|
||||
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
||||
Item *item;
|
||||
while ((item= li++))
|
||||
{
|
||||
if (item->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
{
|
||||
item->clear_extraction_flag();
|
||||
li.remove();
|
||||
}
|
||||
}
|
||||
switch (((Item_cond*) cond)->argument_list()->elements)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return ((Item_cond*) cond)->argument_list()->head();
|
||||
default:
|
||||
return cond;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cond;
|
||||
}
|
||||
|
||||
/**
|
||||
@} (end of group Query_Optimizer)
|
||||
*/
|
||||
|
|
|
@ -188,7 +188,7 @@ typedef enum_nested_loop_state
|
|||
Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab);
|
||||
int rr_sequential(READ_RECORD *info);
|
||||
int rr_sequential_and_unpack(READ_RECORD *info);
|
||||
|
||||
Item *remove_pushed_top_conjuncts(THD *thd, Item *cond);
|
||||
|
||||
#include "sql_explain.h"
|
||||
|
||||
|
|
|
@ -2390,6 +2390,7 @@ export const char *optimizer_switch_names[]=
|
|||
"extended_keys",
|
||||
"exists_to_in",
|
||||
"orderby_uses_equalities",
|
||||
"condition_pushdown_for_derived",
|
||||
"default",
|
||||
NullS
|
||||
};
|
||||
|
|
176
sql/table.cc
176
sql/table.cc
|
@ -7903,3 +7903,179 @@ double KEY::actual_rec_per_key(uint i)
|
|||
return (is_statistics_from_stat_tables ?
|
||||
read_stats->get_avg_frequency(i) : (double) rec_per_key[i]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Mark subformulas of a condition unusable for the condition pushed into table
|
||||
|
||||
@param cond The condition whose subformulas are to be marked
|
||||
|
||||
@details
|
||||
This method recursively traverses the AND-OR condition cond and for each subformula
|
||||
of the codition it checks whether it can be usable for the extraction of a condition
|
||||
that can be pushed into this table. The subformulas that are not usable are
|
||||
marked with the flag NO_EXTRACTION_FL.
|
||||
@note
|
||||
This method is called before any call of TABLE_LIST::build_pushable_cond_for_table.
|
||||
The flag NO_EXTRACTION_FL set in a subformula allows to avoid building clone
|
||||
for the subformula when extracting the pushable condition.
|
||||
*/
|
||||
|
||||
void TABLE_LIST::check_pushable_cond_for_table(Item *cond)
|
||||
{
|
||||
table_map tab_map= table->map;
|
||||
cond->clear_extraction_flag();
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
bool and_cond= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
|
||||
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
||||
uint count= 0;
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
check_pushable_cond_for_table(item);
|
||||
if (item->get_extraction_flag() != NO_EXTRACTION_FL)
|
||||
count++;
|
||||
else if (!and_cond)
|
||||
break;
|
||||
}
|
||||
if ((and_cond && count == 0) || item)
|
||||
{
|
||||
cond->set_extraction_flag(NO_EXTRACTION_FL);
|
||||
if (and_cond)
|
||||
li.rewind();
|
||||
while ((item= li++))
|
||||
item->clear_extraction_flag();
|
||||
}
|
||||
}
|
||||
else if (cond->walk(&Item::exclusive_dependence_on_table_processor,
|
||||
0, (uchar *) &tab_map))
|
||||
cond->set_extraction_flag(NO_EXTRACTION_FL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Build condition extractable from the given one depended only on this table
|
||||
|
||||
@param thd The thread handle
|
||||
@param cond The condition from which the pushable one is to be extracted
|
||||
|
||||
@details
|
||||
For the given condition cond this method finds out what condition depended
|
||||
only on this table can be extracted from cond. If such condition C exists
|
||||
the method builds the item for it.
|
||||
The method uses the flag NO_EXTRACTION_FL set by the preliminary call of
|
||||
the method TABLE_LIST::check_pushable_cond_for_table to figure out whether
|
||||
a subformula depends only on this table or not.
|
||||
@note
|
||||
The built condition C is always implied by the condition cond
|
||||
(cond => C). The method tries to build the most restictive such
|
||||
condition (i.e. for any other condition C' such that cond => C'
|
||||
we have C => C').
|
||||
@note
|
||||
The build item is not ready for usage: substitution for the field items
|
||||
has to be done and it has to be re-fixed.
|
||||
|
||||
@retval
|
||||
the built condition pushable into this table if such a condition exists
|
||||
NULL if there is no such a condition
|
||||
*/
|
||||
|
||||
Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond)
|
||||
{
|
||||
table_map tab_map= table->map;
|
||||
bool is_multiple_equality= cond->type() == Item::FUNC_ITEM &&
|
||||
((Item_func*) cond)->functype() == Item_func::MULT_EQUAL_FUNC;
|
||||
if (cond->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
return 0;
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
bool cond_and= false;
|
||||
Item_cond *new_cond;
|
||||
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
|
||||
{
|
||||
cond_and= true;
|
||||
new_cond=new (thd->mem_root) Item_cond_and(thd);
|
||||
}
|
||||
else
|
||||
new_cond= new (thd->mem_root) Item_cond_or(thd);
|
||||
if (!new_cond)
|
||||
return 0;
|
||||
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
{
|
||||
if (!cond_and)
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
Item *fix= build_pushable_cond_for_table(thd, item);
|
||||
if (!fix && !cond_and)
|
||||
return 0;
|
||||
if (!fix)
|
||||
continue;
|
||||
new_cond->argument_list()->push_back(fix, thd->mem_root);
|
||||
}
|
||||
switch (new_cond->argument_list()->elements)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return new_cond->argument_list()->head();
|
||||
default:
|
||||
return new_cond;
|
||||
}
|
||||
}
|
||||
else if (is_multiple_equality)
|
||||
{
|
||||
if (!(cond->used_tables() & tab_map))
|
||||
return 0;
|
||||
Item *new_cond= NULL;
|
||||
int i= 0;
|
||||
Item_equal *item_equal= (Item_equal *) cond;
|
||||
Item *left_item = item_equal->get_const();
|
||||
Item_equal_fields_iterator it(*item_equal);
|
||||
Item *item;
|
||||
if (!left_item)
|
||||
{
|
||||
while ((item=it++))
|
||||
if (item->used_tables() == tab_map)
|
||||
{
|
||||
left_item= item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!left_item)
|
||||
return 0;
|
||||
while ((item=it++))
|
||||
{
|
||||
if (!(item->used_tables() == tab_map))
|
||||
continue;
|
||||
Item_func_eq *eq=
|
||||
new (thd->mem_root) Item_func_eq(thd, item, left_item);
|
||||
if (eq)
|
||||
{
|
||||
i++;
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
new_cond= eq;
|
||||
break;
|
||||
case 2:
|
||||
new_cond= new (thd->mem_root) Item_cond_and(thd, new_cond, eq);
|
||||
break;
|
||||
default:
|
||||
((Item_cond_and*)new_cond)->argument_list()->push_back(eq, thd->mem_root);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new_cond;
|
||||
}
|
||||
else if (cond->get_extraction_flag() != NO_EXTRACTION_FL)
|
||||
return cond->build_clone(thd, thd->mem_root);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2344,6 +2344,8 @@ struct TABLE_LIST
|
|||
return false;
|
||||
}
|
||||
void set_lock_type(THD* thd, enum thr_lock_type lock);
|
||||
void check_pushable_cond_for_table(Item *cond);
|
||||
Item *build_pushable_cond_for_table(THD *thd, Item *cond);
|
||||
|
||||
private:
|
||||
bool prep_check_option(THD *thd, uint8 check_opt_type);
|
||||
|
|
Loading…
Reference in a new issue