Merge sinisa@work.mysql.com:/home/bk/mysql-4.1
into sinisa.nasamreza.org:/mnt/work/mysql-4.1
This commit is contained in:
commit
ab70ad7c1e
@ -90,6 +90,7 @@ tonu@x153.internalnet
|
||||
tonu@x3.internalnet
|
||||
venu@myvenu.com
|
||||
venu@work.mysql.com
|
||||
vva@eagle.mysql.r18.ru
|
||||
vva@genie.(none)
|
||||
walrus@mysql.com
|
||||
wax@mysql.com
|
||||
|
@ -32040,6 +32040,10 @@ a single backslash to be matched).
|
||||
@item expr NOT LIKE pat [ESCAPE 'escape-char']
|
||||
Same as @code{NOT (expr LIKE pat [ESCAPE 'escape-char'])}.
|
||||
|
||||
@findex SOUNDS LIKE
|
||||
@item expr SOUNDS LIKE expr
|
||||
Same as @code{SOUNDEX(expr)=SOUNDEX(expr)}.
|
||||
|
||||
@cindex mSQL compatibility
|
||||
@cindex compatibility, with mSQL
|
||||
@findex REGEXP
|
||||
|
@ -42,21 +42,21 @@ insert into t1 values (null,null,'');
|
||||
select count(distinct a),count(distinct grp) from t1;
|
||||
count(distinct a) count(distinct grp)
|
||||
6 3
|
||||
select sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1;
|
||||
sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
|
||||
21 6 3.5000 1.7078 7 0 1 6 E
|
||||
select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp;
|
||||
grp sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
|
||||
NULL 0 0 NULL NULL 0 0 NULL NULL
|
||||
1 1 1 1.0000 0.0000 1 1 1 1 a a
|
||||
2 5 2 2.5000 0.5000 3 2 2 3 b c
|
||||
3 15 3 5.0000 0.8165 7 4 4 6 C E
|
||||
select grp, sum(a)+count(a)+avg(a)+std(a)+bit_or(a)+bit_and(a)+min(a)+max(a)+min(c)+max(c) as sum from t1 group by grp;
|
||||
select sum(a),count(a),avg(a),std(a),variance(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1;
|
||||
sum(a) count(a) avg(a) std(a) variance(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
|
||||
21 6 3.5000 1.7078 2.9167 7 0 1 6 E
|
||||
select grp, sum(a),count(a),avg(a),std(a),variance(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp;
|
||||
grp sum(a) count(a) avg(a) std(a) variance(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
|
||||
NULL 0 0 NULL NULL NULL 0 0 NULL NULL
|
||||
1 1 1 1.0000 0.0000 0.0000 1 1 1 1 a a
|
||||
2 5 2 2.5000 0.5000 0.2500 3 2 2 3 b c
|
||||
3 15 3 5.0000 0.8165 0.6667 7 4 4 6 C E
|
||||
select grp, sum(a)+count(a)+avg(a)+std(a)+variance(a)+bit_or(a)+bit_and(a)+min(a)+max(a)+min(c)+max(c) as sum from t1 group by grp;
|
||||
grp sum
|
||||
NULL NULL
|
||||
1 7
|
||||
2 20
|
||||
3 44.816496580928
|
||||
2 20.25
|
||||
3 45.483163247594
|
||||
create table t2 (grp int, a bigint unsigned, c char(10));
|
||||
insert into t2 select grp,max(a)+max(grp),max(c) from t1 group by grp;
|
||||
replace into t2 select grp, a, c from t1 limit 2,1;
|
||||
@ -72,14 +72,14 @@ CREATE TABLE t1 (id int(11),value1 float(10,2));
|
||||
INSERT INTO t1 VALUES (1,0.00),(1,1.00), (1,2.00), (2,10.00), (2,11.00), (2,12.00);
|
||||
CREATE TABLE t2 (id int(11),name char(20));
|
||||
INSERT INTO t2 VALUES (1,'Set One'),(2,'Set Two');
|
||||
select id, avg(value1), std(value1) from t1 group by id;
|
||||
id avg(value1) std(value1)
|
||||
1 1.000000 0.816497
|
||||
2 11.000000 0.816497
|
||||
select name, avg(value1), std(value1) from t1, t2 where t1.id = t2.id group by t1.id;
|
||||
name avg(value1) std(value1)
|
||||
Set One 1.000000 0.816497
|
||||
Set Two 11.000000 0.816497
|
||||
select id, avg(value1), std(value1), variance(value1) from t1 group by id;
|
||||
id avg(value1) std(value1) variance(value1)
|
||||
1 1.000000 0.816497 0.666667
|
||||
2 11.000000 0.816497 0.666667
|
||||
select name, avg(value1), std(value1), variance(value1) from t1, t2 where t1.id = t2.id group by t1.id;
|
||||
name avg(value1) std(value1) variance(value1)
|
||||
Set One 1.000000 0.816497 0.666667
|
||||
Set Two 11.000000 0.816497 0.666667
|
||||
drop table t1,t2;
|
||||
create table t1 (id int not null);
|
||||
create table t2 (id int not null,rating int null);
|
||||
|
@ -1,11 +1,95 @@
|
||||
select 1 in (1,2,3);
|
||||
1 in (1,2,3)
|
||||
1
|
||||
select 10 in (1,2,3);
|
||||
10 in (1,2,3)
|
||||
0
|
||||
select NULL in (1,2,3);
|
||||
NULL in (1,2,3)
|
||||
NULL
|
||||
select 1 in (1,NULL,3);
|
||||
1 in (1,NULL,3)
|
||||
1
|
||||
select 3 in (1,NULL,3);
|
||||
3 in (1,NULL,3)
|
||||
1
|
||||
select 10 in (1,NULL,3);
|
||||
10 in (1,NULL,3)
|
||||
NULL
|
||||
select 1.5 in (1.5,2.5,3.5);
|
||||
1.5 in (1.5,2.5,3.5)
|
||||
1
|
||||
select 10.5 in (1.5,2.5,3.5);
|
||||
10.5 in (1.5,2.5,3.5)
|
||||
0
|
||||
select NULL in (1.5,2.5,3.5);
|
||||
NULL in (1.5,2.5,3.5)
|
||||
NULL
|
||||
select 1.5 in (1.5,NULL,3.5);
|
||||
1.5 in (1.5,NULL,3.5)
|
||||
1
|
||||
select 3.5 in (1.5,NULL,3.5);
|
||||
3.5 in (1.5,NULL,3.5)
|
||||
1
|
||||
select 10.5 in (1.5,NULL,3.5);
|
||||
10.5 in (1.5,NULL,3.5)
|
||||
NULL
|
||||
drop table if exists t1;
|
||||
CREATE TABLE t1 (a int, b int, c int);
|
||||
insert into t1 values (1,2,3), (1,NULL,3);
|
||||
select 1 in (a,b,c) from t1;
|
||||
1 in (a,b,c)
|
||||
1
|
||||
1
|
||||
select 3 in (a,b,c) from t1;
|
||||
3 in (a,b,c)
|
||||
1
|
||||
1
|
||||
select 10 in (a,b,c) from t1;
|
||||
10 in (a,b,c)
|
||||
0
|
||||
NULL
|
||||
select NULL in (a,b,c) from t1;
|
||||
NULL in (a,b,c)
|
||||
NULL
|
||||
NULL
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a float, b float, c float);
|
||||
insert into t1 values (1.5,2.5,3.5), (1.5,NULL,3.5);
|
||||
select 1.5 in (a,b,c) from t1;
|
||||
1.5 in (a,b,c)
|
||||
1
|
||||
1
|
||||
select 3.5 in (a,b,c) from t1;
|
||||
3.5 in (a,b,c)
|
||||
1
|
||||
1
|
||||
select 10.5 in (a,b,c) from t1;
|
||||
10.5 in (a,b,c)
|
||||
0
|
||||
NULL
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a varchar(10), b varchar(10), c varchar(10));
|
||||
insert into t1 values ('A','BC','EFD'), ('A',NULL,'EFD');
|
||||
select 'A' in (a,b,c) from t1;
|
||||
'A' in (a,b,c)
|
||||
1
|
||||
1
|
||||
select 'EFD' in (a,b,c) from t1;
|
||||
'EFD' in (a,b,c)
|
||||
1
|
||||
1
|
||||
select 'XSFGGHF' in (a,b,c) from t1;
|
||||
'XSFGGHF' in (a,b,c)
|
||||
0
|
||||
NULL
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (field char(1));
|
||||
INSERT INTO t1 VALUES ('A'),(NULL);
|
||||
SELECT * from t1 WHERE field IN (NULL);
|
||||
field
|
||||
SELECT * from t1 WHERE field NOT IN (NULL);
|
||||
field
|
||||
A
|
||||
SELECT * from t1 where field = field;
|
||||
field
|
||||
A
|
||||
@ -16,6 +100,7 @@ NULL
|
||||
DELETE FROM t1 WHERE field NOT IN (NULL);
|
||||
SELECT * FROM t1;
|
||||
field
|
||||
A
|
||||
NULL
|
||||
drop table t1;
|
||||
create table t1 (id int(10) primary key);
|
||||
|
@ -80,6 +80,21 @@ this is a REAL test
|
||||
select soundex(''),soundex('he'),soundex('hello all folks');
|
||||
soundex('') soundex('he') soundex('hello all folks')
|
||||
H000 H4142
|
||||
select 'mood' sounds like 'mud';
|
||||
'mood' sounds like 'mud'
|
||||
1
|
||||
select 'Glazgo' sounds like 'Liverpool';
|
||||
'Glazgo' sounds like 'Liverpool'
|
||||
0
|
||||
select null sounds like 'null';
|
||||
null sounds like 'null'
|
||||
NULL
|
||||
select 'null' sounds like null;
|
||||
'null' sounds like null
|
||||
NULL
|
||||
select null sounds like null;
|
||||
null sounds like null
|
||||
NULL
|
||||
select md5('hello');
|
||||
md5('hello')
|
||||
5d41402abc4b2a76b9719d911017c592
|
||||
|
@ -62,4 +62,8 @@ select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null;
|
||||
Fld1 max(Fld2)
|
||||
1 20
|
||||
3 50
|
||||
select Fld1, max(Fld2) from t1 group by Fld1 having variance(Fld2) is not null;
|
||||
Fld1 max(Fld2)
|
||||
1 20
|
||||
3 50
|
||||
drop table t1;
|
||||
|
136
mysql-test/r/row.result
Normal file
136
mysql-test/r/row.result
Normal file
@ -0,0 +1,136 @@
|
||||
select row(1,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
|
||||
row(1,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3))
|
||||
1
|
||||
select row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
|
||||
row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3))
|
||||
0
|
||||
select row(1,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3));
|
||||
row(1,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3))
|
||||
1
|
||||
select row(10,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3));
|
||||
row(10,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3))
|
||||
0
|
||||
select row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a'));
|
||||
row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a'))
|
||||
1
|
||||
select row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3));
|
||||
row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3))
|
||||
1
|
||||
select row('a',0,3) IN (row(3,2,3), row('a','a','3'), row(1,3,3));
|
||||
row('a',0,3) IN (row(3,2,3), row('a','a','3'), row(1,3,3))
|
||||
1
|
||||
select row('a',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3));
|
||||
row('a',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3))
|
||||
1
|
||||
select row('b',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3));
|
||||
row('b',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3))
|
||||
0
|
||||
select row('b',1.5,3) IN (row('b',NULL,3), row('a',1.5,3), row(1,3,3));
|
||||
row('b',1.5,3) IN (row('b',NULL,3), row('a',1.5,3), row(1,3,3))
|
||||
NULL
|
||||
select row('b',1.5,3) IN (row('b',NULL,4), row('a',1.5,3), row(1,3,3));
|
||||
row('b',1.5,3) IN (row('b',NULL,4), row('a',1.5,3), row(1,3,3))
|
||||
0
|
||||
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,4)));
|
||||
row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,4)))
|
||||
1
|
||||
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,4));
|
||||
Cardinality error (more/less than 2 columns)
|
||||
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,NULL)));
|
||||
row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,NULL)))
|
||||
NULL
|
||||
SELECT ROW(1,2,3)=ROW(1,2,3);
|
||||
ROW(1,2,3)=ROW(1,2,3)
|
||||
1
|
||||
SELECT ROW(2,2,3)=ROW(1+1,2,3);
|
||||
ROW(2,2,3)=ROW(1+1,2,3)
|
||||
1
|
||||
SELECT ROW(1,2,3)=ROW(1+1,2,3);
|
||||
ROW(1,2,3)=ROW(1+1,2,3)
|
||||
0
|
||||
SELECT ROW(1,2,3)<ROW(1+1,2,3);
|
||||
ROW(1,2,3)<ROW(1+1,2,3)
|
||||
1
|
||||
SELECT ROW(1,2,3)>ROW(1+1,2,3);
|
||||
ROW(1,2,3)>ROW(1+1,2,3)
|
||||
0
|
||||
SELECT ROW(1,2,3)<=ROW(1+1,2,3);
|
||||
ROW(1,2,3)<=ROW(1+1,2,3)
|
||||
1
|
||||
SELECT ROW(1,2,3)>=ROW(1+1,2,3);
|
||||
ROW(1,2,3)>=ROW(1+1,2,3)
|
||||
0
|
||||
SELECT ROW(1,2,3)<>ROW(1+1,2,3);
|
||||
ROW(1,2,3)<>ROW(1+1,2,3)
|
||||
1
|
||||
SELECT ROW(NULL,2,3)=ROW(NULL,2,3);
|
||||
ROW(NULL,2,3)=ROW(NULL,2,3)
|
||||
NULL
|
||||
SELECT ROW(NULL,2,3)<=>ROW(NULL,2,3);
|
||||
ROW(NULL,2,3)<=>ROW(NULL,2,3)
|
||||
1
|
||||
SELECT ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5));
|
||||
ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5))
|
||||
1
|
||||
SELECT ROW('test',2,3.33)=ROW('test',2,3.33);
|
||||
ROW('test',2,3.33)=ROW('test',2,3.33)
|
||||
1
|
||||
SELECT ROW('test',2,3.33)=ROW('test',2,3.33,4);
|
||||
Cardinality error (more/less than 3 columns)
|
||||
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,33));
|
||||
ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,33))
|
||||
1
|
||||
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,3));
|
||||
ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,3))
|
||||
0
|
||||
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,NULL));
|
||||
ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,NULL))
|
||||
NULL
|
||||
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,4);
|
||||
Cardinality error (more/less than 2 columns)
|
||||
drop table if exists t1;
|
||||
create table t1 ( a int, b int, c int);
|
||||
insert into t1 values (1,2,3), (2,3,1), (3,2,1), (1,2,NULL);
|
||||
select * from t1 where ROW(1,2,3)=ROW(a,b,c);
|
||||
a b c
|
||||
1 2 3
|
||||
select * from t1 where ROW(0,2,3)=ROW(a,b,c);
|
||||
a b c
|
||||
select * from t1 where ROW(1,2,3)<ROW(a,b,c);
|
||||
a b c
|
||||
2 3 1
|
||||
3 2 1
|
||||
select ROW(a,2,3) IN(row(1,b,c), row(2,3,1)) from t1;
|
||||
ROW(a,2,3) IN(row(1,b,c), row(2,3,1))
|
||||
1
|
||||
0
|
||||
0
|
||||
NULL
|
||||
select ROW(c,2,3) IN(row(1,b,a), row(2,3,1)) from t1;
|
||||
ROW(c,2,3) IN(row(1,b,a), row(2,3,1))
|
||||
0
|
||||
0
|
||||
1
|
||||
NULL
|
||||
select ROW(a,b,c) IN(row(1,2,3), row(3,2,1)) from t1;
|
||||
ROW(a,b,c) IN(row(1,2,3), row(3,2,1))
|
||||
1
|
||||
0
|
||||
1
|
||||
NULL
|
||||
select ROW(1,2,3) IN(row(a,b,c), row(1,2,3)) from t1;
|
||||
ROW(1,2,3) IN(row(a,b,c), row(1,2,3))
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
drop table t1;
|
||||
select ROW(1,1);
|
||||
Cardinality error (more/less than 1 columns)
|
||||
drop table if exists t1;
|
||||
create table t1 (i int);
|
||||
select 1 from t1 where ROW(1,1);
|
||||
Cardinality error (more/less than 1 columns)
|
||||
select count(*) from t1 order by ROW(1,1);
|
||||
Cardinality error (more/less than 1 columns)
|
||||
drop table t1;
|
@ -1,60 +0,0 @@
|
||||
SELECT ROW(1,2,3)=ROW(1,2,3);
|
||||
ROW(1,2,3)=ROW(1,2,3)
|
||||
1
|
||||
SELECT ROW(2,2,3)=ROW(1+1,2,3);
|
||||
ROW(2,2,3)=ROW(1+1,2,3)
|
||||
1
|
||||
SELECT ROW(1,2,3)=ROW(1+1,2,3);
|
||||
ROW(1,2,3)=ROW(1+1,2,3)
|
||||
0
|
||||
SELECT ROW(1,2,3)<ROW(1+1,2,3);
|
||||
ROW(1,2,3)<ROW(1+1,2,3)
|
||||
1
|
||||
SELECT ROW(1,2,3)>ROW(1+1,2,3);
|
||||
ROW(1,2,3)>ROW(1+1,2,3)
|
||||
0
|
||||
SELECT ROW(1,2,3)<=ROW(1+1,2,3);
|
||||
ROW(1,2,3)<=ROW(1+1,2,3)
|
||||
1
|
||||
SELECT ROW(1,2,3)>=ROW(1+1,2,3);
|
||||
ROW(1,2,3)>=ROW(1+1,2,3)
|
||||
0
|
||||
SELECT ROW(1,2,3)<>ROW(1+1,2,3);
|
||||
ROW(1,2,3)<>ROW(1+1,2,3)
|
||||
1
|
||||
SELECT ROW(NULL,2,3)=ROW(NULL,2,3);
|
||||
ROW(NULL,2,3)=ROW(NULL,2,3)
|
||||
NULL
|
||||
SELECT ROW(NULL,2,3)<=>ROW(NULL,2,3);
|
||||
ROW(NULL,2,3)<=>ROW(NULL,2,3)
|
||||
1
|
||||
SELECT ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5));
|
||||
ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5))
|
||||
1
|
||||
SELECT ROW('test',2,3.33)=ROW('test',2,3.33);
|
||||
ROW('test',2,3.33)=ROW('test',2,3.33)
|
||||
1
|
||||
SELECT ROW('test',2,3.33)=ROW('test',2,3.33,4);
|
||||
Cardinality error (more/less than 3 columns)
|
||||
drop table if exists t1;
|
||||
create table t1 ( a int, b int, c int);
|
||||
insert into t1 values (1,2,3), (2,3,1), (3,2,1);
|
||||
select * from t1 where ROW(1,2,3)=ROW(a,b,c);
|
||||
a b c
|
||||
1 2 3
|
||||
select * from t1 where ROW(0,2,3)=ROW(a,b,c);
|
||||
a b c
|
||||
select * from t1 where ROW(1,2,3)<ROW(a,b,c);
|
||||
a b c
|
||||
2 3 1
|
||||
3 2 1
|
||||
drop table t1;
|
||||
select ROW(1,1);
|
||||
Cardinality error (more/less than 1 columns)
|
||||
drop table if exists t1;
|
||||
create table t1 (i int);
|
||||
select 1 from t1 where ROW(1,1);
|
||||
Cardinality error (more/less than 1 columns)
|
||||
select count(*) from t1 order by ROW(1,1);
|
||||
Cardinality error (more/less than 1 columns)
|
||||
drop table t1;
|
@ -2656,14 +2656,14 @@ companynr count(*)
|
||||
58 23
|
||||
53 4
|
||||
50 11
|
||||
select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 where companynr = 34 and fld4<>"";
|
||||
count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1)
|
||||
70 absentee vest 17788966 254128.0857 3272.5940
|
||||
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 group by companynr limit 3;
|
||||
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1)
|
||||
00 82 Anthony windmills 10355753 126289.6707 115550.9757
|
||||
29 95 abut wetness 14473298 152350.5053 8368.5480
|
||||
34 70 absentee vest 17788966 254128.0857 3272.5940
|
||||
select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
|
||||
count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
|
||||
70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
|
||||
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
|
||||
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
|
||||
00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
|
||||
29 95 abut wetness 14473298 152350.5053 8368.5480 70032594.9026
|
||||
34 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
|
||||
select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
|
||||
companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
|
||||
37 1 1 5987435 5987435 5987435 5987435.0000
|
||||
|
@ -598,3 +598,105 @@ INSERT INTO t1 values (1),(1);
|
||||
UPDATE t SET id=(SELECT * FROM t1);
|
||||
Subselect returns more than 1 record
|
||||
drop table t;
|
||||
create table t (a int);
|
||||
insert into t values (1),(2),(3);
|
||||
select 1 IN (SELECT * from t);
|
||||
1 IN (SELECT * from t)
|
||||
1
|
||||
select 10 IN (SELECT * from t);
|
||||
10 IN (SELECT * from t)
|
||||
0
|
||||
select NULL IN (SELECT * from t);
|
||||
NULL IN (SELECT * from t)
|
||||
NULL
|
||||
update t set a=NULL where a=2;
|
||||
select 1 IN (SELECT * from t);
|
||||
1 IN (SELECT * from t)
|
||||
1
|
||||
select 3 IN (SELECT * from t);
|
||||
3 IN (SELECT * from t)
|
||||
1
|
||||
select 10 IN (SELECT * from t);
|
||||
10 IN (SELECT * from t)
|
||||
NULL
|
||||
select 1 > ALL (SELECT * from t);
|
||||
1 > ALL (SELECT * from t)
|
||||
0
|
||||
select 10 > ALL (SELECT * from t);
|
||||
10 > ALL (SELECT * from t)
|
||||
NULL
|
||||
select 1 > ANY (SELECT * from t);
|
||||
1 > ANY (SELECT * from t)
|
||||
NULL
|
||||
select 10 > ANY (SELECT * from t);
|
||||
10 > ANY (SELECT * from t)
|
||||
1
|
||||
drop table t;
|
||||
create table t (a varchar(20));
|
||||
insert into t values ('A'),('BC'),('DEF');
|
||||
select 'A' IN (SELECT * from t);
|
||||
'A' IN (SELECT * from t)
|
||||
1
|
||||
select 'XYZS' IN (SELECT * from t);
|
||||
'XYZS' IN (SELECT * from t)
|
||||
0
|
||||
select NULL IN (SELECT * from t);
|
||||
NULL IN (SELECT * from t)
|
||||
NULL
|
||||
update t set a=NULL where a='BC';
|
||||
select 'A' IN (SELECT * from t);
|
||||
'A' IN (SELECT * from t)
|
||||
1
|
||||
select 'DEF' IN (SELECT * from t);
|
||||
'DEF' IN (SELECT * from t)
|
||||
1
|
||||
select 'XYZS' IN (SELECT * from t);
|
||||
'XYZS' IN (SELECT * from t)
|
||||
NULL
|
||||
select 'A' > ALL (SELECT * from t);
|
||||
'A' > ALL (SELECT * from t)
|
||||
0
|
||||
select 'XYZS' > ALL (SELECT * from t);
|
||||
'XYZS' > ALL (SELECT * from t)
|
||||
NULL
|
||||
select 'A' > ANY (SELECT * from t);
|
||||
'A' > ANY (SELECT * from t)
|
||||
NULL
|
||||
select 'XYZS' > ANY (SELECT * from t);
|
||||
'XYZS' > ANY (SELECT * from t)
|
||||
1
|
||||
drop table t;
|
||||
create table t (a float);
|
||||
insert into t values (1.5),(2.5),(3.5);
|
||||
select 1.5 IN (SELECT * from t);
|
||||
1.5 IN (SELECT * from t)
|
||||
1
|
||||
select 10.5 IN (SELECT * from t);
|
||||
10.5 IN (SELECT * from t)
|
||||
0
|
||||
select NULL IN (SELECT * from t);
|
||||
NULL IN (SELECT * from t)
|
||||
NULL
|
||||
update t set a=NULL where a=2.5;
|
||||
select 1.5 IN (SELECT * from t);
|
||||
1.5 IN (SELECT * from t)
|
||||
1
|
||||
select 3.5 IN (SELECT * from t);
|
||||
3.5 IN (SELECT * from t)
|
||||
1
|
||||
select 10.5 IN (SELECT * from t);
|
||||
10.5 IN (SELECT * from t)
|
||||
NULL
|
||||
select 1.5 > ALL (SELECT * from t);
|
||||
1.5 > ALL (SELECT * from t)
|
||||
0
|
||||
select 10.5 > ALL (SELECT * from t);
|
||||
10.5 > ALL (SELECT * from t)
|
||||
NULL
|
||||
select 1.5 > ANY (SELECT * from t);
|
||||
1.5 > ANY (SELECT * from t)
|
||||
NULL
|
||||
select 10.5 > ANY (SELECT * from t);
|
||||
10.5 > ANY (SELECT * from t)
|
||||
1
|
||||
drop table t;
|
||||
|
@ -21,9 +21,9 @@ select count(distinct a),count(distinct grp) from t1;
|
||||
insert into t1 values (null,null,'');
|
||||
select count(distinct a),count(distinct grp) from t1;
|
||||
|
||||
select sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1;
|
||||
select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp;
|
||||
select grp, sum(a)+count(a)+avg(a)+std(a)+bit_or(a)+bit_and(a)+min(a)+max(a)+min(c)+max(c) as sum from t1 group by grp;
|
||||
select sum(a),count(a),avg(a),std(a),variance(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1;
|
||||
select grp, sum(a),count(a),avg(a),std(a),variance(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp;
|
||||
select grp, sum(a)+count(a)+avg(a)+std(a)+variance(a)+bit_or(a)+bit_and(a)+min(a)+max(a)+min(c)+max(c) as sum from t1 group by grp;
|
||||
|
||||
create table t2 (grp int, a bigint unsigned, c char(10));
|
||||
insert into t2 select grp,max(a)+max(grp),max(c) from t1 group by grp;
|
||||
@ -40,8 +40,8 @@ CREATE TABLE t1 (id int(11),value1 float(10,2));
|
||||
INSERT INTO t1 VALUES (1,0.00),(1,1.00), (1,2.00), (2,10.00), (2,11.00), (2,12.00);
|
||||
CREATE TABLE t2 (id int(11),name char(20));
|
||||
INSERT INTO t2 VALUES (1,'Set One'),(2,'Set Two');
|
||||
select id, avg(value1), std(value1) from t1 group by id;
|
||||
select name, avg(value1), std(value1) from t1, t2 where t1.id = t2.id group by t1.id;
|
||||
select id, avg(value1), std(value1), variance(value1) from t1 group by id;
|
||||
select name, avg(value1), std(value1), variance(value1) from t1, t2 where t1.id = t2.id group by t1.id;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
|
@ -2,7 +2,39 @@
|
||||
# test of IN (NULL)
|
||||
#
|
||||
|
||||
select 1 in (1,2,3);
|
||||
select 10 in (1,2,3);
|
||||
select NULL in (1,2,3);
|
||||
select 1 in (1,NULL,3);
|
||||
select 3 in (1,NULL,3);
|
||||
select 10 in (1,NULL,3);
|
||||
select 1.5 in (1.5,2.5,3.5);
|
||||
select 10.5 in (1.5,2.5,3.5);
|
||||
select NULL in (1.5,2.5,3.5);
|
||||
select 1.5 in (1.5,NULL,3.5);
|
||||
select 3.5 in (1.5,NULL,3.5);
|
||||
select 10.5 in (1.5,NULL,3.5);
|
||||
drop table if exists t1;
|
||||
CREATE TABLE t1 (a int, b int, c int);
|
||||
insert into t1 values (1,2,3), (1,NULL,3);
|
||||
select 1 in (a,b,c) from t1;
|
||||
select 3 in (a,b,c) from t1;
|
||||
select 10 in (a,b,c) from t1;
|
||||
select NULL in (a,b,c) from t1;
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a float, b float, c float);
|
||||
insert into t1 values (1.5,2.5,3.5), (1.5,NULL,3.5);
|
||||
select 1.5 in (a,b,c) from t1;
|
||||
select 3.5 in (a,b,c) from t1;
|
||||
select 10.5 in (a,b,c) from t1;
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a varchar(10), b varchar(10), c varchar(10));
|
||||
insert into t1 values ('A','BC','EFD'), ('A',NULL,'EFD');
|
||||
select 'A' in (a,b,c) from t1;
|
||||
select 'EFD' in (a,b,c) from t1;
|
||||
select 'XSFGGHF' in (a,b,c) from t1;
|
||||
drop table t1;
|
||||
|
||||
CREATE TABLE t1 (field char(1));
|
||||
INSERT INTO t1 VALUES ('A'),(NULL);
|
||||
SELECT * from t1 WHERE field IN (NULL);
|
||||
|
@ -36,6 +36,11 @@ select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
|
||||
select replace('aaaa','a','b'),replace('aaaa','aa','b'),replace('aaaa','a','bb'),replace('aaaa','','b'),replace('bbbb','a','c');
|
||||
select replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
|
||||
select soundex(''),soundex('he'),soundex('hello all folks');
|
||||
select 'mood' sounds like 'mud';
|
||||
select 'Glazgo' sounds like 'Liverpool';
|
||||
select null sounds like 'null';
|
||||
select 'null' sounds like null;
|
||||
select null sounds like null;
|
||||
select md5('hello');
|
||||
select sha('abc');
|
||||
select sha1('abc');
|
||||
|
@ -59,4 +59,5 @@ select Fld1, max(Fld2) as q from t1 group by Fld1 having q is not null;
|
||||
select Fld1, max(Fld2) from t1 group by Fld1 having max(Fld2) is not null;
|
||||
select Fld1, max(Fld2) from t1 group by Fld1 having avg(Fld2) is not null;
|
||||
select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null;
|
||||
select Fld1, max(Fld2) from t1 group by Fld1 having variance(Fld2) is not null;
|
||||
drop table t1;
|
||||
|
61
mysql-test/t/row.test
Normal file
61
mysql-test/t/row.test
Normal file
@ -0,0 +1,61 @@
|
||||
select row(1,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
|
||||
select row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
|
||||
select row(1,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3));
|
||||
select row(10,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3));
|
||||
select row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a'));
|
||||
select row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3));
|
||||
select row('a',0,3) IN (row(3,2,3), row('a','a','3'), row(1,3,3));
|
||||
select row('a',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3));
|
||||
select row('b',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3));
|
||||
select row('b',1.5,3) IN (row('b',NULL,3), row('a',1.5,3), row(1,3,3));
|
||||
select row('b',1.5,3) IN (row('b',NULL,4), row('a',1.5,3), row(1,3,3));
|
||||
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,4)));
|
||||
-- error 1239
|
||||
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,4));
|
||||
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,NULL)));
|
||||
|
||||
SELECT ROW(1,2,3)=ROW(1,2,3);
|
||||
SELECT ROW(2,2,3)=ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)=ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)<ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)>ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)<=ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)>=ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)<>ROW(1+1,2,3);
|
||||
SELECT ROW(NULL,2,3)=ROW(NULL,2,3);
|
||||
SELECT ROW(NULL,2,3)<=>ROW(NULL,2,3);
|
||||
SELECT ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5));
|
||||
SELECT ROW('test',2,3.33)=ROW('test',2,3.33);
|
||||
-- error 1239
|
||||
SELECT ROW('test',2,3.33)=ROW('test',2,3.33,4);
|
||||
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,33));
|
||||
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,3));
|
||||
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,NULL));
|
||||
-- error 1239
|
||||
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,4);
|
||||
drop table if exists t1;
|
||||
create table t1 ( a int, b int, c int);
|
||||
insert into t1 values (1,2,3), (2,3,1), (3,2,1), (1,2,NULL);
|
||||
select * from t1 where ROW(1,2,3)=ROW(a,b,c);
|
||||
select * from t1 where ROW(0,2,3)=ROW(a,b,c);
|
||||
select * from t1 where ROW(1,2,3)<ROW(a,b,c);
|
||||
select ROW(a,2,3) IN(row(1,b,c), row(2,3,1)) from t1;
|
||||
select ROW(c,2,3) IN(row(1,b,a), row(2,3,1)) from t1;
|
||||
select ROW(a,b,c) IN(row(1,2,3), row(3,2,1)) from t1;
|
||||
select ROW(1,2,3) IN(row(a,b,c), row(1,2,3)) from t1;
|
||||
drop table t1;
|
||||
|
||||
-- error 1239
|
||||
select ROW(1,1);
|
||||
drop table if exists t1;
|
||||
create table t1 (i int);
|
||||
-- error 1239
|
||||
select 1 from t1 where ROW(1,1);
|
||||
-- error 1239
|
||||
select count(*) from t1 order by ROW(1,1);
|
||||
#TODO remove comments after parser fixing
|
||||
#-- error 1239
|
||||
#select count(*) from t1 order by i having (1,1);
|
||||
#-- error 1239
|
||||
#select 1 from t1 limit (1,1), (1,1);
|
||||
drop table t1;
|
@ -1,36 +0,0 @@
|
||||
SELECT ROW(1,2,3)=ROW(1,2,3);
|
||||
SELECT ROW(2,2,3)=ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)=ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)<ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)>ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)<=ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)>=ROW(1+1,2,3);
|
||||
SELECT ROW(1,2,3)<>ROW(1+1,2,3);
|
||||
SELECT ROW(NULL,2,3)=ROW(NULL,2,3);
|
||||
SELECT ROW(NULL,2,3)<=>ROW(NULL,2,3);
|
||||
SELECT ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5));
|
||||
SELECT ROW('test',2,3.33)=ROW('test',2,3.33);
|
||||
-- error 1239
|
||||
SELECT ROW('test',2,3.33)=ROW('test',2,3.33,4);
|
||||
drop table if exists t1;
|
||||
create table t1 ( a int, b int, c int);
|
||||
insert into t1 values (1,2,3), (2,3,1), (3,2,1);
|
||||
select * from t1 where ROW(1,2,3)=ROW(a,b,c);
|
||||
select * from t1 where ROW(0,2,3)=ROW(a,b,c);
|
||||
select * from t1 where ROW(1,2,3)<ROW(a,b,c);
|
||||
drop table t1;
|
||||
|
||||
-- error 1239
|
||||
select ROW(1,1);
|
||||
drop table if exists t1;
|
||||
create table t1 (i int);
|
||||
-- error 1239
|
||||
select 1 from t1 where ROW(1,1);
|
||||
-- error 1239
|
||||
select count(*) from t1 order by ROW(1,1);
|
||||
#TODO remove comments after parser fixing
|
||||
#-- error 1239
|
||||
#select count(*) from t1 order by i having (1,1);
|
||||
#-- error 1239
|
||||
#select 1 from t1 limit (1,1), (1,1);
|
||||
drop table t1;
|
@ -1577,8 +1577,8 @@ select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld
|
||||
select count(*) from t1;
|
||||
select companynr,count(*),sum(fld1) from t2 group by companynr;
|
||||
select companynr,count(*) from t2 group by companynr order by companynr desc limit 5;
|
||||
select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 where companynr = 34 and fld4<>"";
|
||||
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 group by companynr limit 3;
|
||||
select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
|
||||
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
|
||||
select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
|
||||
select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
|
||||
select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ;
|
||||
|
@ -362,3 +362,48 @@ INSERT INTO t1 values (1),(1);
|
||||
-- error 1240
|
||||
UPDATE t SET id=(SELECT * FROM t1);
|
||||
drop table t;
|
||||
|
||||
|
||||
#NULL test
|
||||
create table t (a int);
|
||||
insert into t values (1),(2),(3);
|
||||
select 1 IN (SELECT * from t);
|
||||
select 10 IN (SELECT * from t);
|
||||
select NULL IN (SELECT * from t);
|
||||
update t set a=NULL where a=2;
|
||||
select 1 IN (SELECT * from t);
|
||||
select 3 IN (SELECT * from t);
|
||||
select 10 IN (SELECT * from t);
|
||||
select 1 > ALL (SELECT * from t);
|
||||
select 10 > ALL (SELECT * from t);
|
||||
select 1 > ANY (SELECT * from t);
|
||||
select 10 > ANY (SELECT * from t);
|
||||
drop table t;
|
||||
create table t (a varchar(20));
|
||||
insert into t values ('A'),('BC'),('DEF');
|
||||
select 'A' IN (SELECT * from t);
|
||||
select 'XYZS' IN (SELECT * from t);
|
||||
select NULL IN (SELECT * from t);
|
||||
update t set a=NULL where a='BC';
|
||||
select 'A' IN (SELECT * from t);
|
||||
select 'DEF' IN (SELECT * from t);
|
||||
select 'XYZS' IN (SELECT * from t);
|
||||
select 'A' > ALL (SELECT * from t);
|
||||
select 'XYZS' > ALL (SELECT * from t);
|
||||
select 'A' > ANY (SELECT * from t);
|
||||
select 'XYZS' > ANY (SELECT * from t);
|
||||
drop table t;
|
||||
create table t (a float);
|
||||
insert into t values (1.5),(2.5),(3.5);
|
||||
select 1.5 IN (SELECT * from t);
|
||||
select 10.5 IN (SELECT * from t);
|
||||
select NULL IN (SELECT * from t);
|
||||
update t set a=NULL where a=2.5;
|
||||
select 1.5 IN (SELECT * from t);
|
||||
select 3.5 IN (SELECT * from t);
|
||||
select 10.5 IN (SELECT * from t);
|
||||
select 1.5 > ALL (SELECT * from t);
|
||||
select 10.5 > ALL (SELECT * from t);
|
||||
select 1.5 > ANY (SELECT * from t);
|
||||
select 10.5 > ANY (SELECT * from t);
|
||||
drop table t;
|
||||
|
45
sql/item.cc
45
sql/item.cc
@ -46,6 +46,12 @@ Item::Item():
|
||||
loop_id= 0;
|
||||
}
|
||||
|
||||
Item_ref_in_optimizer::Item_ref_in_optimizer(Item_in_optimizer *master,
|
||||
char *table_name_par,
|
||||
char *field_name_par):
|
||||
Item_ref(master->args, table_name_par, field_name_par), owner(master) {}
|
||||
|
||||
|
||||
bool Item::check_loop(uint id)
|
||||
{
|
||||
DBUG_ENTER("Item::check_loop");
|
||||
@ -436,6 +442,20 @@ String *Item_copy_string::val_str(String *str)
|
||||
return &str_value;
|
||||
}
|
||||
|
||||
double Item_ref_in_optimizer::val()
|
||||
{
|
||||
return owner->get_cache();
|
||||
}
|
||||
longlong Item_ref_in_optimizer::val_int()
|
||||
{
|
||||
return owner->get_cache_int();
|
||||
}
|
||||
String* Item_ref_in_optimizer::val_str(String* s)
|
||||
{
|
||||
return owner->get_cache_str(s);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Functions to convert item to field (for send_fields)
|
||||
*/
|
||||
@ -511,10 +531,31 @@ bool Item_asterisk_remover::fix_fields(THD *thd,
|
||||
res= item->fix_fields(thd, list, &item);
|
||||
else
|
||||
thd->fatal_error= 1; // no item given => out of memory
|
||||
*ref= item;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
double Item_ref_null_helper::val()
|
||||
{
|
||||
double tmp= (*ref)->val_result();
|
||||
owner->was_null|= null_value= (*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
longlong Item_ref_null_helper::val_int()
|
||||
{
|
||||
longlong tmp= (*ref)->val_int_result();
|
||||
owner->was_null|= null_value= (*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
String* Item_ref_null_helper::val_str(String* s)
|
||||
{
|
||||
String* tmp= (*ref)->str_result(s);
|
||||
owner->was_null|= null_value= (*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate)
|
||||
{
|
||||
return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate));
|
||||
}
|
||||
|
||||
bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
@ -686,7 +727,7 @@ void Item_avg_field::make_field(Send_field *tmp_field)
|
||||
init_make_field(tmp_field,FIELD_TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
void Item_std_field::make_field(Send_field *tmp_field)
|
||||
void Item_variance_field::make_field(Send_field *tmp_field)
|
||||
{
|
||||
init_make_field(tmp_field,FIELD_TYPE_DOUBLE);
|
||||
}
|
||||
|
103
sql/item.h
103
sql/item.h
@ -33,7 +33,8 @@ public:
|
||||
enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM,
|
||||
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM,
|
||||
COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_ITEM,
|
||||
PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM,
|
||||
PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM,
|
||||
FIELD_VARIANCE_ITEM,CONST_ITEM,
|
||||
SUBSELECT_ITEM, ROW_ITEM};
|
||||
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
||||
|
||||
@ -72,7 +73,6 @@ public:
|
||||
virtual double val_result() { return val(); }
|
||||
virtual longlong val_int_result() { return val_int(); }
|
||||
virtual String *str_result(String* tmp) { return val_str(tmp); }
|
||||
virtual bool is_null_result() { return is_null(); }
|
||||
virtual table_map used_tables() const { return (table_map) 0L; }
|
||||
virtual bool basic_const_item() const { return 0; }
|
||||
virtual Item *new_item() { return 0; } /* Only for const items */
|
||||
@ -100,6 +100,8 @@ public:
|
||||
virtual Item* el(uint i) { return this; }
|
||||
virtual Item** addr(uint i) { return 0; }
|
||||
virtual bool check_cols(uint c);
|
||||
// It is not row => null inside is impossible
|
||||
virtual bool null_inside() { return 0; };
|
||||
};
|
||||
|
||||
|
||||
@ -122,6 +124,25 @@ public:
|
||||
String* val_str(String* s) { return item->val_str(s); }
|
||||
void make_field(Send_field* f) { item->make_field(f); }
|
||||
bool check_cols(uint col) { return item->check_cols(col); }
|
||||
bool eq(const Item *item, bool binary_cmp) const
|
||||
{ return item->eq(item, binary_cmp); }
|
||||
bool is_null()
|
||||
{
|
||||
item->val_int();
|
||||
return item->null_value;
|
||||
}
|
||||
bool get_date(TIME *ltime, bool fuzzydate)
|
||||
{
|
||||
return (null_value=item->get_date(ltime, fuzzydate));
|
||||
}
|
||||
bool send(THD *thd, String *tmp) { return item->send(thd, tmp); }
|
||||
int save_in_field(Field *field, bool no_conversions)
|
||||
{
|
||||
return item->save_in_field(field, no_conversions);
|
||||
}
|
||||
void save_org_in_field(Field *field) { item->save_org_in_field(field); }
|
||||
enum Item_result result_type () const { return item->result_type(); }
|
||||
table_map used_tables() const { return item->used_tables(); }
|
||||
};
|
||||
|
||||
|
||||
@ -138,19 +159,6 @@ public:
|
||||
bool fix_fields(THD *, struct st_table_list *, Item ** ref);
|
||||
};
|
||||
|
||||
/*
|
||||
To resolve '*' field moved to condition
|
||||
*/
|
||||
class Item_asterisk_remover :public Item_wrapper
|
||||
{
|
||||
public:
|
||||
Item_asterisk_remover(Item *it)
|
||||
{
|
||||
item= it;
|
||||
}
|
||||
bool fix_fields(THD *, struct st_table_list *, Item ** ref);
|
||||
};
|
||||
|
||||
class st_select_lex;
|
||||
class Item_ident :public Item
|
||||
{
|
||||
@ -188,7 +196,6 @@ public:
|
||||
double val_result();
|
||||
longlong val_int_result();
|
||||
String *str_result(String* tmp);
|
||||
bool is_null_result() { return result_field->is_null(); }
|
||||
bool send(THD *thd, String *str_arg)
|
||||
{
|
||||
return result_field->send(thd,str_arg);
|
||||
@ -384,9 +391,13 @@ public:
|
||||
enum Item_result result_type () const { return STRING_RESULT; }
|
||||
bool basic_const_item() const { return 1; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
Item *new_item() { return new Item_string(name,str_value.ptr(),max_length,default_charset_info); }
|
||||
Item *new_item()
|
||||
{
|
||||
return new Item_string(name, str_value.ptr(), max_length,
|
||||
default_charset_info);
|
||||
}
|
||||
String *const_string() { return &str_value; }
|
||||
inline void append(char *str,uint length) { str_value.append(str,length); }
|
||||
inline void append(char *str, uint length) { str_value.append(str, length); }
|
||||
void print(String *str);
|
||||
};
|
||||
|
||||
@ -470,25 +481,25 @@ public:
|
||||
double val()
|
||||
{
|
||||
double tmp=(*ref)->val_result();
|
||||
null_value=(*ref)->is_null_result();
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
longlong tmp=(*ref)->val_int_result();
|
||||
null_value=(*ref)->is_null_result();
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
String *val_str(String* tmp)
|
||||
{
|
||||
tmp=(*ref)->str_result(tmp);
|
||||
null_value=(*ref)->is_null_result();
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
bool is_null()
|
||||
{
|
||||
(void) (*ref)->val_int_result();
|
||||
return (*ref)->is_null_result();
|
||||
return (*ref)->null_value;
|
||||
}
|
||||
bool get_date(TIME *ltime,bool fuzzydate)
|
||||
{
|
||||
@ -505,6 +516,54 @@ public:
|
||||
bool check_loop(uint id);
|
||||
};
|
||||
|
||||
class Item_in_subselect;
|
||||
class Item_ref_null_helper: public Item_ref
|
||||
{
|
||||
protected:
|
||||
Item_in_subselect* owner;
|
||||
public:
|
||||
Item_ref_null_helper(Item_in_subselect* master, Item **item,
|
||||
char *table_name_par,char *field_name_par):
|
||||
Item_ref(item, table_name_par, field_name_par), owner(master) {}
|
||||
double val();
|
||||
longlong val_int();
|
||||
String* val_str(String* s);
|
||||
bool get_date(TIME *ltime, bool fuzzydate);
|
||||
};
|
||||
|
||||
/*
|
||||
To resolve '*' field moved to condition
|
||||
and register NULL values
|
||||
*/
|
||||
class Item_asterisk_remover :public Item_ref_null_helper
|
||||
{
|
||||
Item *item;
|
||||
public:
|
||||
Item_asterisk_remover(Item_in_subselect *master, Item *it,
|
||||
char *table, char *field):
|
||||
Item_ref_null_helper(master, &item, table, field),
|
||||
item(it)
|
||||
{}
|
||||
bool fix_fields(THD *, struct st_table_list *, Item ** ref);
|
||||
};
|
||||
|
||||
class Item_in_optimizer;
|
||||
class Item_ref_in_optimizer: public Item_ref
|
||||
{
|
||||
protected:
|
||||
Item_in_optimizer* owner;
|
||||
public:
|
||||
Item_ref_in_optimizer(Item_in_optimizer* master,
|
||||
char *table_name_par,char *field_name_par);
|
||||
double val();
|
||||
longlong val_int();
|
||||
String* val_str(String* s);
|
||||
bool fix_fields(THD *, struct st_table_list *, Item ** ref)
|
||||
{
|
||||
fixed= 1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
The following class is used to optimize comparing of date columns
|
||||
|
@ -90,7 +90,7 @@ static bool convert_constant_item(Field *field, Item **item)
|
||||
|
||||
void Item_bool_func2::fix_length_and_dec()
|
||||
{
|
||||
max_length=1; // Function returns 0 or 1
|
||||
max_length= 1; // Function returns 0 or 1
|
||||
|
||||
/*
|
||||
As some compare functions are generated after sql_yacc,
|
||||
@ -144,7 +144,14 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
|
||||
}
|
||||
if ((comparators= (Arg_comparator *) sql_alloc(sizeof(Arg_comparator)*n)))
|
||||
for (uint i=0; i < n; i++)
|
||||
{
|
||||
if ((*a)->el(i)->cols() != (*b)->el(i)->cols())
|
||||
{
|
||||
my_error(ER_CARDINALITY_COL, MYF(0), (*a)->el(i)->cols());
|
||||
return 1;
|
||||
}
|
||||
comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
@ -263,6 +270,61 @@ int Arg_comparator::compare_e_row()
|
||||
return 1;
|
||||
}
|
||||
|
||||
longlong Item_in_optimizer::val_int()
|
||||
{
|
||||
int_cache_ok= 1;
|
||||
flt_cache_ok= 0;
|
||||
str_cache_ok= 0;
|
||||
int_cache= args[0]->val_int_result();
|
||||
if (args[0]->null_value)
|
||||
{
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
longlong tmp= args[1]->val_int_result();
|
||||
null_value= args[1]->null_value;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
longlong Item_in_optimizer::get_cache_int()
|
||||
{
|
||||
if (!int_cache_ok)
|
||||
{
|
||||
int_cache_ok= 1;
|
||||
flt_cache_ok= 0;
|
||||
str_cache_ok= 0;
|
||||
int_cache= args[0]->val_int_result();
|
||||
null_value= args[0]->null_value;
|
||||
}
|
||||
return int_cache;
|
||||
}
|
||||
|
||||
double Item_in_optimizer::get_cache()
|
||||
{
|
||||
if (!flt_cache_ok)
|
||||
{
|
||||
flt_cache_ok= 1;
|
||||
int_cache_ok= 0;
|
||||
str_cache_ok= 0;
|
||||
flt_cache= args[0]->val_result();
|
||||
null_value= args[0]->null_value;
|
||||
}
|
||||
return flt_cache;
|
||||
}
|
||||
|
||||
String *Item_in_optimizer::get_cache_str(String *s)
|
||||
{
|
||||
if (!str_cache_ok)
|
||||
{
|
||||
str_cache_ok= 1;
|
||||
int_cache_ok= 0;
|
||||
flt_cache_ok= 0;
|
||||
str_value.set(buffer, sizeof(buffer), s->charset());
|
||||
str_cache= args[0]->str_result(&str_value);
|
||||
null_value= args[0]->null_value;
|
||||
}
|
||||
return str_cache;
|
||||
}
|
||||
|
||||
longlong Item_func_eq::val_int()
|
||||
{
|
||||
@ -356,7 +418,8 @@ void Item_func_interval::fix_length_and_dec()
|
||||
intervals[i]=args[i]->val();
|
||||
}
|
||||
}
|
||||
maybe_null=0; max_length=2;
|
||||
maybe_null= 0;
|
||||
max_length= 2;
|
||||
used_tables_cache|=item->used_tables();
|
||||
}
|
||||
|
||||
@ -415,7 +478,7 @@ bool Item_func_interval::check_loop(uint id)
|
||||
|
||||
void Item_func_between::fix_length_and_dec()
|
||||
{
|
||||
max_length=1;
|
||||
max_length= 1;
|
||||
|
||||
/*
|
||||
As some compare functions are generated after sql_yacc,
|
||||
@ -968,8 +1031,8 @@ double Item_func_coalesce::val()
|
||||
|
||||
void Item_func_coalesce::fix_length_and_dec()
|
||||
{
|
||||
max_length=0;
|
||||
decimals=0;
|
||||
max_length= 0;
|
||||
decimals= 0;
|
||||
cached_result_type = args[0]->result_type();
|
||||
for (uint i=0 ; i < arg_count ; i++)
|
||||
{
|
||||
@ -992,6 +1055,11 @@ static int cmp_double(double *a,double *b)
|
||||
return *a < *b ? -1 : *a == *b ? 0 : 1;
|
||||
}
|
||||
|
||||
static int cmp_row(cmp_item_row* a, cmp_item_row* b)
|
||||
{
|
||||
return a->compare(b);
|
||||
}
|
||||
|
||||
int in_vector::find(Item *item)
|
||||
{
|
||||
byte *result=get_value(item);
|
||||
@ -1014,7 +1082,6 @@ int in_vector::find(Item *item)
|
||||
return (int) ((*compare)(base+start*size,result) == 0);
|
||||
}
|
||||
|
||||
|
||||
in_string::in_string(uint elements,qsort_cmp cmp_func)
|
||||
:in_vector(elements,sizeof(String),cmp_func),tmp(buff,sizeof(buff),default_charset_info)
|
||||
{}
|
||||
@ -1041,6 +1108,29 @@ byte *in_string::get_value(Item *item)
|
||||
return (byte*) item->val_str(&tmp);
|
||||
}
|
||||
|
||||
in_row::in_row(uint elements, Item * item)
|
||||
{
|
||||
DBUG_ENTER("in_row::in_row");
|
||||
base= (char*) new cmp_item_row[elements];
|
||||
size= sizeof(cmp_item_row);
|
||||
compare= (qsort_cmp) cmp_row;
|
||||
tmp.store_value(item);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
byte *in_row::get_value(Item *item)
|
||||
{
|
||||
tmp.store_value(item);
|
||||
return (byte *)&tmp;
|
||||
}
|
||||
|
||||
void in_row::set(uint pos, Item *item)
|
||||
{
|
||||
DBUG_ENTER("in_row::set");
|
||||
DBUG_PRINT("enter", ("pos %u item 0x%lx", pos, (ulong) item));
|
||||
((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
in_longlong::in_longlong(uint elements)
|
||||
:in_vector(elements,sizeof(longlong),(qsort_cmp) cmp_longlong)
|
||||
@ -1053,13 +1143,12 @@ void in_longlong::set(uint pos,Item *item)
|
||||
|
||||
byte *in_longlong::get_value(Item *item)
|
||||
{
|
||||
tmp=item->val_int();
|
||||
tmp= item->val_int();
|
||||
if (item->null_value)
|
||||
return 0; /* purecov: inspected */
|
||||
return 0;
|
||||
return (byte*) &tmp;
|
||||
}
|
||||
|
||||
|
||||
in_double::in_double(uint elements)
|
||||
:in_vector(elements,sizeof(double),(qsort_cmp) cmp_double)
|
||||
{}
|
||||
@ -1071,21 +1160,173 @@ void in_double::set(uint pos,Item *item)
|
||||
|
||||
byte *in_double::get_value(Item *item)
|
||||
{
|
||||
tmp=item->val();
|
||||
tmp= item->val();
|
||||
if (item->null_value)
|
||||
return 0; /* purecov: inspected */
|
||||
return (byte*) &tmp;
|
||||
}
|
||||
|
||||
cmp_item* cmp_item::get_comparator (Item *item)
|
||||
{
|
||||
switch (item->result_type()) {
|
||||
case STRING_RESULT:
|
||||
if (item->binary())
|
||||
return new cmp_item_binary_string;
|
||||
else
|
||||
return new cmp_item_sort_string;
|
||||
break;
|
||||
case INT_RESULT:
|
||||
return new cmp_item_int;
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
return new cmp_item_real;
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
return new cmp_item_row;
|
||||
break;
|
||||
}
|
||||
return 0; // to satisfy compiler :)
|
||||
}
|
||||
|
||||
cmp_item* cmp_item_sort_string::make_same()
|
||||
{
|
||||
return new cmp_item_sort_string_in_static();
|
||||
}
|
||||
|
||||
cmp_item* cmp_item_binary_string::make_same()
|
||||
{
|
||||
return new cmp_item_binary_string_in_static();
|
||||
}
|
||||
|
||||
cmp_item* cmp_item_int::make_same()
|
||||
{
|
||||
return new cmp_item_int();
|
||||
}
|
||||
|
||||
cmp_item* cmp_item_real::make_same()
|
||||
{
|
||||
return new cmp_item_real();
|
||||
}
|
||||
|
||||
cmp_item* cmp_item_row::make_same()
|
||||
{
|
||||
return new cmp_item_row();
|
||||
}
|
||||
|
||||
void cmp_item_row::store_value(Item *item)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
n= item->cols();
|
||||
if ((comparators= (cmp_item **) thd->alloc(sizeof(cmp_item *)*n)))
|
||||
{
|
||||
item->null_value= 0;
|
||||
for (uint i=0; i < n; i++)
|
||||
if ((comparators[i]= cmp_item::get_comparator(item->el(i))))
|
||||
{
|
||||
comparators[i]->store_value(item->el(i));
|
||||
item->null_value|= item->el(i)->null_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cmp_item_row::store_value_by_template(cmp_item *t, Item *item)
|
||||
{
|
||||
cmp_item_row *tmpl= (cmp_item_row*) t;
|
||||
if (tmpl->n != item->cols())
|
||||
{
|
||||
my_error(ER_CARDINALITY_COL, MYF(0), tmpl->n);
|
||||
return;
|
||||
}
|
||||
n= tmpl->n;
|
||||
if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
|
||||
{
|
||||
item->null_value= 0;
|
||||
for (uint i=0; i < n; i++)
|
||||
if ((comparators[i]= tmpl->comparators[i]->make_same()))
|
||||
{
|
||||
comparators[i]->store_value_by_template(tmpl->comparators[i],
|
||||
item->el(i));
|
||||
item->null_value|= item->el(i)->null_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int cmp_item_row::cmp(Item *arg)
|
||||
{
|
||||
arg->null_value= 0;
|
||||
if (arg->cols() != n)
|
||||
{
|
||||
my_error(ER_CARDINALITY_COL, MYF(0), n);
|
||||
return 1;
|
||||
}
|
||||
bool was_null= 0;
|
||||
for (uint i=0; i < n; i++)
|
||||
if (comparators[i]->cmp(arg->el(i)))
|
||||
{
|
||||
if (!arg->el(i)->null_value)
|
||||
return 1;
|
||||
was_null= 1;
|
||||
}
|
||||
return (arg->null_value= was_null);
|
||||
}
|
||||
|
||||
int cmp_item_row::compare(cmp_item *c)
|
||||
{
|
||||
int res;
|
||||
cmp_item_row *cmp= (cmp_item_row *) c;
|
||||
for (uint i=0; i < n; i++)
|
||||
if ((res= comparators[i]->compare(cmp->comparators[i])))
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Item_func_in::nulls_in_row()
|
||||
{
|
||||
Item **arg,**arg_end;
|
||||
for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
|
||||
{
|
||||
if ((*arg)->null_inside())
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Item_func_in::fix_length_and_dec()
|
||||
{
|
||||
if (const_item())
|
||||
/*
|
||||
Row item with NULLs inside can return NULL or FALSE =>
|
||||
they can't be processed as static
|
||||
*/
|
||||
if (const_item() && !nulls_in_row())
|
||||
{
|
||||
switch (item->result_type()) {
|
||||
case STRING_RESULT:
|
||||
if (item->binary())
|
||||
array=new in_string(arg_count,(qsort_cmp) stringcmp); /* purecov: inspected */
|
||||
array=new in_string(arg_count,(qsort_cmp) stringcmp);
|
||||
else
|
||||
array=new in_string(arg_count,(qsort_cmp) sortcmp);
|
||||
break;
|
||||
@ -1096,8 +1337,7 @@ void Item_func_in::fix_length_and_dec()
|
||||
array= new in_double(arg_count);
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
// This case should never be choosen
|
||||
DBUG_ASSERT(0);
|
||||
array= new in_row(arg_count, item);
|
||||
break;
|
||||
}
|
||||
uint j=0;
|
||||
@ -1106,33 +1346,18 @@ void Item_func_in::fix_length_and_dec()
|
||||
array->set(j,args[i]);
|
||||
if (!args[i]->null_value) // Skip NULL values
|
||||
j++;
|
||||
else
|
||||
have_null= 1;
|
||||
}
|
||||
if ((array->used_count=j))
|
||||
array->sort();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (item->result_type()) {
|
||||
case STRING_RESULT:
|
||||
if (item->binary())
|
||||
in_item= new cmp_item_binary_string;
|
||||
else
|
||||
in_item= new cmp_item_sort_string;
|
||||
break;
|
||||
case INT_RESULT:
|
||||
in_item= new cmp_item_int;
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
in_item= new cmp_item_real;
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
// This case should never be choosen
|
||||
DBUG_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
in_item= cmp_item:: get_comparator(item);
|
||||
}
|
||||
maybe_null= item->maybe_null;
|
||||
max_length=2;
|
||||
max_length= 1;
|
||||
used_tables_cache|=item->used_tables();
|
||||
const_item_cache&=item->const_item();
|
||||
}
|
||||
@ -1152,17 +1377,20 @@ longlong Item_func_in::val_int()
|
||||
if (array)
|
||||
{
|
||||
int tmp=array->find(item);
|
||||
null_value=item->null_value;
|
||||
null_value=item->null_value || (!tmp && have_null);
|
||||
return tmp;
|
||||
}
|
||||
in_item->store_value(item);
|
||||
if ((null_value=item->null_value))
|
||||
return 0;
|
||||
have_null= 0;
|
||||
for (uint i=0 ; i < arg_count ; i++)
|
||||
{
|
||||
if (!in_item->cmp(args[i]) && !args[i]->null_value)
|
||||
return 1; // Would maybe be nice with i ?
|
||||
have_null|= args[i]->null_value;
|
||||
}
|
||||
null_value= have_null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1452,7 +1680,8 @@ longlong Item_func_isnotnull::val_int()
|
||||
|
||||
void Item_func_like::fix_length_and_dec()
|
||||
{
|
||||
decimals=0; max_length=1;
|
||||
decimals= 0;
|
||||
max_length= 1;
|
||||
// cmp_type=STRING_RESULT; // For quick select
|
||||
}
|
||||
|
||||
@ -1559,7 +1788,8 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
args[1]->fix_fields(thd,tables, args + 1))
|
||||
return 1; /* purecov: inspected */
|
||||
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
|
||||
max_length=1; decimals=0;
|
||||
max_length= 1;
|
||||
decimals= 0;
|
||||
if (args[0]->binary() || args[1]->binary())
|
||||
set_charset(my_charset_bin);
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
/* compare and test functions */
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
@ -38,16 +40,12 @@ public:
|
||||
Arg_comparator() {};
|
||||
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2) {};
|
||||
|
||||
inline void seta(Item **item) { a= item; }
|
||||
inline void setb(Item **item) { b= item; }
|
||||
|
||||
int set_compare_func(Item_bool_func2 *owner, Item_result type);
|
||||
inline int set_compare_func(Item_bool_func2 *owner)
|
||||
{
|
||||
return set_compare_func(owner, item_cmp_type((*a)->result_type(),
|
||||
(*b)->result_type()));
|
||||
}
|
||||
|
||||
inline int set_cmp_func(Item_bool_func2 *owner,
|
||||
Item **a1, Item **a2,
|
||||
Item_result type)
|
||||
@ -87,6 +85,27 @@ public:
|
||||
void fix_length_and_dec() { decimals=0; max_length=1; }
|
||||
};
|
||||
|
||||
class Item_in_optimizer: public Item_bool_func
|
||||
{
|
||||
protected:
|
||||
char buffer[80];
|
||||
longlong int_cache;
|
||||
double flt_cache;
|
||||
String *str_cache;
|
||||
bool int_cache_ok, flt_cache_ok, str_cache_ok;
|
||||
public:
|
||||
Item_in_optimizer(Item *a,Item *b):
|
||||
Item_bool_func(a,b), int_cache_ok(0), flt_cache_ok(0), str_cache_ok(0) {}
|
||||
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
|
||||
longlong val_int();
|
||||
|
||||
double get_cache();
|
||||
longlong get_cache_int();
|
||||
String *get_cache_str(String *s);
|
||||
|
||||
friend class Item_ref_in_optimizer;
|
||||
};
|
||||
|
||||
class Item_bool_func2 :public Item_int_func
|
||||
{ /* Bool with 2 string args */
|
||||
protected:
|
||||
@ -358,6 +377,7 @@ class in_vector :public Sql_alloc
|
||||
uint count;
|
||||
public:
|
||||
uint used_count;
|
||||
in_vector() {}
|
||||
in_vector(uint elements,uint element_length,qsort_cmp cmp_func)
|
||||
:base((char*) sql_calloc(elements*element_length)),
|
||||
size(element_length), compare(cmp_func), count(elements),
|
||||
@ -372,7 +392,6 @@ public:
|
||||
int find(Item *item);
|
||||
};
|
||||
|
||||
|
||||
class in_string :public in_vector
|
||||
{
|
||||
char buff[80];
|
||||
@ -384,7 +403,6 @@ public:
|
||||
byte *get_value(Item *item);
|
||||
};
|
||||
|
||||
|
||||
class in_longlong :public in_vector
|
||||
{
|
||||
longlong tmp;
|
||||
@ -394,7 +412,6 @@ public:
|
||||
byte *get_value(Item *item);
|
||||
};
|
||||
|
||||
|
||||
class in_double :public in_vector
|
||||
{
|
||||
double tmp;
|
||||
@ -404,7 +421,6 @@ public:
|
||||
byte *get_value(Item *item);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Classes for easy comparing of non const items
|
||||
*/
|
||||
@ -414,88 +430,201 @@ class cmp_item :public Sql_alloc
|
||||
public:
|
||||
cmp_item() {}
|
||||
virtual ~cmp_item() {}
|
||||
virtual void store_value(Item *item)=0;
|
||||
virtual int cmp(Item *item)=0;
|
||||
virtual void store_value(Item *item)= 0;
|
||||
virtual int cmp(Item *item)= 0;
|
||||
// for optimized IN with row
|
||||
virtual int compare(cmp_item *item)= 0;
|
||||
static cmp_item* get_comparator(Item *);
|
||||
virtual cmp_item *make_same()= 0;
|
||||
virtual void store_value_by_template(cmp_item *tmpl, Item *item)
|
||||
{
|
||||
store_value(item);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class cmp_item_sort_string :public cmp_item {
|
||||
protected:
|
||||
char value_buff[80];
|
||||
String value,*value_res;
|
||||
typedef int (*str_cmp_func_pointer)(const String *, const String *);
|
||||
class cmp_item_string :public cmp_item
|
||||
{
|
||||
protected:
|
||||
str_cmp_func_pointer str_cmp_func;
|
||||
String *value_res;
|
||||
public:
|
||||
cmp_item_sort_string() :value(value_buff,sizeof(value_buff),default_charset_info) {}
|
||||
cmp_item_string (str_cmp_func_pointer cmp): str_cmp_func(cmp) {}
|
||||
friend class cmp_item_sort_string;
|
||||
friend class cmp_item_binary_string;
|
||||
friend class cmp_item_sort_string_in_static;
|
||||
friend class cmp_item_binary_string_in_static;
|
||||
};
|
||||
|
||||
class cmp_item_sort_string :public cmp_item_string
|
||||
{
|
||||
protected:
|
||||
char value_buff[80];
|
||||
String value;
|
||||
public:
|
||||
cmp_item_sort_string(str_cmp_func_pointer cmp):
|
||||
cmp_item_string(cmp),
|
||||
value(value_buff, sizeof(value_buff), default_charset_info) {}
|
||||
cmp_item_sort_string():
|
||||
cmp_item_string(&sortcmp),
|
||||
value(value_buff, sizeof(value_buff), default_charset_info) {}
|
||||
void store_value(Item *item)
|
||||
{
|
||||
value_res=item->val_str(&value);
|
||||
}
|
||||
{
|
||||
value_res= item->val_str(&value);
|
||||
}
|
||||
int cmp(Item *arg)
|
||||
{
|
||||
char buff[80];
|
||||
String tmp(buff,sizeof(buff),default_charset_info),*res;
|
||||
if (!(res=arg->val_str(&tmp)))
|
||||
return 1; /* Can't be right */
|
||||
return sortcmp(value_res,res);
|
||||
}
|
||||
{
|
||||
char buff[80];
|
||||
String tmp(buff, sizeof(buff), default_charset_info), *res;
|
||||
if (!(res= arg->val_str(&tmp)))
|
||||
return 1; /* Can't be right */
|
||||
return (*str_cmp_func)(value_res, res);
|
||||
}
|
||||
int compare(cmp_item *c)
|
||||
{
|
||||
cmp_item_string *cmp= (cmp_item_string *)c;
|
||||
return (*str_cmp_func)(value_res, cmp->value_res);
|
||||
}
|
||||
cmp_item *make_same();
|
||||
};
|
||||
|
||||
class cmp_item_binary_string :public cmp_item_sort_string {
|
||||
public:
|
||||
cmp_item_binary_string() {}
|
||||
int cmp(Item *arg)
|
||||
{
|
||||
char buff[80];
|
||||
String tmp(buff,sizeof(buff),default_charset_info),*res;
|
||||
if (!(res=arg->val_str(&tmp)))
|
||||
return 1; /* Can't be right */
|
||||
return stringcmp(value_res,res);
|
||||
}
|
||||
cmp_item_binary_string(): cmp_item_sort_string(&stringcmp) {}
|
||||
cmp_item *make_same();
|
||||
};
|
||||
|
||||
|
||||
class cmp_item_int :public cmp_item
|
||||
{
|
||||
longlong value;
|
||||
public:
|
||||
void store_value(Item *item)
|
||||
{
|
||||
value=item->val_int();
|
||||
}
|
||||
{
|
||||
value= item->val_int();
|
||||
}
|
||||
int cmp(Item *arg)
|
||||
{
|
||||
return value != arg->val_int();
|
||||
}
|
||||
{
|
||||
return value != arg->val_int();
|
||||
}
|
||||
int compare(cmp_item *c)
|
||||
{
|
||||
cmp_item_int *cmp= (cmp_item_int *)c;
|
||||
return (value < cmp->value) ? -1 : ((value == cmp->value) ? 0 : 1);
|
||||
}
|
||||
cmp_item *make_same();
|
||||
};
|
||||
|
||||
|
||||
class cmp_item_real :public cmp_item
|
||||
{
|
||||
double value;
|
||||
public:
|
||||
void store_value(Item *item)
|
||||
{
|
||||
value= item->val();
|
||||
}
|
||||
{
|
||||
value= item->val();
|
||||
}
|
||||
int cmp(Item *arg)
|
||||
{
|
||||
return value != arg->val();
|
||||
}
|
||||
{
|
||||
return value != arg->val();
|
||||
}
|
||||
int compare(cmp_item *c)
|
||||
{
|
||||
cmp_item_real *cmp= (cmp_item_real *)c;
|
||||
return (value < cmp->value)? -1 : ((value == cmp->value) ? 0 : 1);
|
||||
}
|
||||
cmp_item *make_same();
|
||||
};
|
||||
|
||||
class cmp_item_row :public cmp_item
|
||||
{
|
||||
cmp_item **comparators;
|
||||
uint n;
|
||||
public:
|
||||
cmp_item_row(): comparators(0), n(0) {}
|
||||
~cmp_item_row()
|
||||
{
|
||||
if(comparators)
|
||||
for(uint i= 0; i < n; i++)
|
||||
if (comparators[i])
|
||||
delete comparators[i];
|
||||
}
|
||||
void store_value(Item *item);
|
||||
int cmp(Item *arg);
|
||||
int compare(cmp_item *arg);
|
||||
cmp_item *make_same();
|
||||
void store_value_by_template(cmp_item *tmpl, Item *);
|
||||
};
|
||||
|
||||
|
||||
class in_row :public in_vector
|
||||
{
|
||||
cmp_item_row tmp;
|
||||
public:
|
||||
in_row(uint elements, Item *);
|
||||
void set(uint pos,Item *item);
|
||||
byte *get_value(Item *item);
|
||||
};
|
||||
|
||||
/*
|
||||
cmp_item for optimized IN with row (right part string, which never
|
||||
be changed)
|
||||
*/
|
||||
|
||||
class cmp_item_sort_string_in_static :public cmp_item_string
|
||||
{
|
||||
protected:
|
||||
String value;
|
||||
public:
|
||||
cmp_item_sort_string_in_static(str_cmp_func_pointer cmp):
|
||||
cmp_item_string(cmp) {}
|
||||
cmp_item_sort_string_in_static(): cmp_item_string(&sortcmp) {}
|
||||
void store_value(Item *item)
|
||||
{
|
||||
value_res= item->val_str(&value);
|
||||
}
|
||||
int cmp(Item *item)
|
||||
{
|
||||
// Should never be called
|
||||
DBUG_ASSERT(0);
|
||||
return 1;
|
||||
}
|
||||
int compare(cmp_item *c)
|
||||
{
|
||||
cmp_item_string *cmp= (cmp_item_string *)c;
|
||||
return (*str_cmp_func)(value_res, cmp->value_res);
|
||||
}
|
||||
cmp_item * make_same()
|
||||
{
|
||||
return new cmp_item_sort_string_in_static();
|
||||
}
|
||||
};
|
||||
|
||||
class cmp_item_binary_string_in_static :public cmp_item_sort_string_in_static {
|
||||
public:
|
||||
cmp_item_binary_string_in_static():
|
||||
cmp_item_sort_string_in_static(&stringcmp) {}
|
||||
cmp_item * make_same()
|
||||
{
|
||||
return new cmp_item_binary_string_in_static();
|
||||
}
|
||||
};
|
||||
|
||||
class Item_func_in :public Item_int_func
|
||||
{
|
||||
Item *item;
|
||||
in_vector *array;
|
||||
cmp_item *in_item;
|
||||
bool have_null;
|
||||
public:
|
||||
Item_func_in(Item *a,List<Item> &list)
|
||||
:Item_int_func(list),item(a),array(0),in_item(0) {}
|
||||
:Item_int_func(list), item(a), array(0), in_item(0), have_null(0)
|
||||
{
|
||||
allowed_arg_cols= item->cols();
|
||||
}
|
||||
longlong val_int();
|
||||
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
|
||||
{
|
||||
bool res=(item->check_cols(1) ||
|
||||
item->fix_fields(thd, tlist, &item) ||
|
||||
// We do not check item->cols(), because allowed_arg_cols assigned from it
|
||||
bool res=(item->fix_fields(thd, tlist, &item) ||
|
||||
Item_func::fix_fields(thd, tlist, ref));
|
||||
with_sum_func= with_sum_func || item->with_sum_func;
|
||||
return res;
|
||||
@ -517,10 +646,9 @@ class Item_func_in :public Item_int_func
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(item->check_loop(id));
|
||||
}
|
||||
bool nulls_in_row();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Functions used by where clause */
|
||||
|
||||
class Item_func_isnull :public Item_bool_func
|
||||
|
@ -18,8 +18,10 @@
|
||||
#include "assert.h"
|
||||
|
||||
Item_row::Item_row(List<Item> &arg):
|
||||
Item(), array_holder(1)
|
||||
Item(), array_holder(1), used_tables_cache(0), const_item_cache(1)
|
||||
{
|
||||
|
||||
//TODO: think placing 2-3 component items in item (as it done for function)
|
||||
if ((arg_count= arg.elements))
|
||||
items= (Item**) sql_alloc(sizeof(Item*)*arg_count);
|
||||
else
|
||||
@ -45,16 +47,31 @@ void Item_row::illegal_method_call(const char *method)
|
||||
|
||||
bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
|
||||
{
|
||||
tables= 0;
|
||||
null_value= 0;
|
||||
maybe_null= 0;
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
if (items[i]->fix_fields(thd, tabl, items+i))
|
||||
return 1;
|
||||
tables |= items[i]->used_tables();
|
||||
used_tables_cache |= items[i]->used_tables();
|
||||
const_item_cache&= items[i]->const_item();
|
||||
maybe_null|= items[i]->maybe_null;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Item_row::update_used_tables()
|
||||
{
|
||||
used_tables_cache= 0;
|
||||
const_item_cache= 1;
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
items[i]->update_used_tables();
|
||||
used_tables_cache|= items[i]->used_tables();
|
||||
const_item_cache&= items[i]->const_item();
|
||||
}
|
||||
}
|
||||
|
||||
bool Item_row::check_cols(uint c)
|
||||
{
|
||||
if (c != arg_count)
|
||||
@ -64,3 +81,22 @@ bool Item_row::check_cols(uint c)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Item_row::null_inside()
|
||||
{
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
if (items[i]->cols() > 1)
|
||||
{
|
||||
if (items[i]->null_inside())
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
items[i]->val_int();
|
||||
if (items[i]->null_value)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,13 +17,17 @@
|
||||
class Item_row: public Item
|
||||
{
|
||||
bool array_holder;
|
||||
table_map tables;
|
||||
table_map used_tables_cache;
|
||||
bool const_item_cache;
|
||||
uint arg_count;
|
||||
Item **items;
|
||||
public:
|
||||
Item_row(List<Item> &);
|
||||
Item_row(Item_row *item):
|
||||
Item(), array_holder(0), tables(item->tables), arg_count(item->arg_count),
|
||||
Item(), array_holder(0),
|
||||
used_tables_cache(item->used_tables_cache),
|
||||
const_item_cache(item->const_item_cache),
|
||||
arg_count(item->arg_count),
|
||||
items(item->items)
|
||||
{}
|
||||
|
||||
@ -56,11 +60,14 @@ public:
|
||||
return 0;
|
||||
};
|
||||
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
||||
table_map used_tables() const { return tables; };
|
||||
table_map used_tables() const { return used_tables_cache; };
|
||||
bool const_item() const { return const_item_cache; };
|
||||
enum Item_result result_type() const { return ROW_RESULT; }
|
||||
void update_used_tables();
|
||||
|
||||
virtual uint cols() { return arg_count; }
|
||||
virtual Item* el(uint i) { return items[i]; }
|
||||
virtual Item** addr(uint i) { return items + i; }
|
||||
virtual bool check_cols(uint c);
|
||||
uint cols() { return arg_count; }
|
||||
Item* el(uint i) { return items[i]; }
|
||||
Item** addr(uint i) { return items + i; }
|
||||
bool check_cols(uint c);
|
||||
bool null_inside();
|
||||
};
|
||||
|
@ -33,9 +33,10 @@ SUBSELECT TODO:
|
||||
#include "sql_select.h"
|
||||
|
||||
Item_subselect::Item_subselect():
|
||||
Item_result_field(), engine_owner(1), value_assigned(0), substitution(0)
|
||||
Item_result_field(), engine_owner(1), value_assigned(0), substitution(0),
|
||||
have_to_be_excluded(0)
|
||||
{
|
||||
assign_null();
|
||||
reset();
|
||||
/*
|
||||
item value is NULL if select_subselect not changed this value
|
||||
(i.e. some rows will be found returned)
|
||||
@ -93,8 +94,10 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
(*ref)= substitution;
|
||||
substitution->name= name;
|
||||
engine->exclude();
|
||||
return substitution->fix_fields(thd, tables, ref);
|
||||
if (have_to_be_excluded)
|
||||
engine->exclude();
|
||||
substitution= 0;
|
||||
return (*ref)->fix_fields(thd, tables, ref);
|
||||
}
|
||||
|
||||
char const *save_where= thd->where;
|
||||
@ -159,7 +162,7 @@ double Item_singleval_subselect::val ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
return real_value;
|
||||
@ -169,7 +172,7 @@ longlong Item_singleval_subselect::val_int ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
return int_value;
|
||||
@ -179,7 +182,7 @@ String *Item_singleval_subselect::val_str (String *str)
|
||||
{
|
||||
if (engine->exec() || null_value)
|
||||
{
|
||||
assign_null();
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
return &string_value;
|
||||
@ -208,9 +211,8 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
|
||||
left_expr= left_exp;
|
||||
init(thd, select_lex, new select_exists_subselect(this));
|
||||
max_columns= UINT_MAX;
|
||||
null_value= 0; //can't be NULL
|
||||
maybe_null= 0; //can't be NULL
|
||||
value= 0;
|
||||
maybe_null= 1;
|
||||
reset();
|
||||
// We need only 1 row to determinate existence
|
||||
select_lex->master_unit()->global_parameters->select_limit= 1;
|
||||
DBUG_VOID_RETURN;
|
||||
@ -226,9 +228,7 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
|
||||
func= f;
|
||||
init(thd, select_lex, new select_exists_subselect(this));
|
||||
max_columns= UINT_MAX;
|
||||
null_value= 0; //can't be NULL
|
||||
maybe_null= 0; //can't be NULL
|
||||
value= 0;
|
||||
reset();
|
||||
// We need only 1 row to determinate existence
|
||||
select_lex->master_unit()->global_parameters->select_limit= 1;
|
||||
DBUG_VOID_RETURN;
|
||||
@ -237,14 +237,15 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
|
||||
|
||||
void Item_exists_subselect::fix_length_and_dec()
|
||||
{
|
||||
max_length= 1;
|
||||
decimals=0;
|
||||
max_length= 1;
|
||||
}
|
||||
|
||||
double Item_exists_subselect::val ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
return (double) value;
|
||||
@ -254,7 +255,7 @@ longlong Item_exists_subselect::val_int ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
@ -264,7 +265,50 @@ String *Item_exists_subselect::val_str(String *str)
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
assign_null();
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
str->set(value,thd_charset());
|
||||
return str;
|
||||
}
|
||||
|
||||
double Item_in_subselect::val ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
reset();
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
if (was_null && !value)
|
||||
null_value= 1;
|
||||
return (double) value;
|
||||
}
|
||||
|
||||
longlong Item_in_subselect::val_int ()
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
reset();
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
if (was_null && !value)
|
||||
null_value= 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
String *Item_in_subselect::val_str(String *str)
|
||||
{
|
||||
if (engine->exec())
|
||||
{
|
||||
reset();
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
if (was_null && !value)
|
||||
{
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
str->set(value,thd_charset());
|
||||
@ -288,8 +332,23 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
|
||||
compare_func_creator func)
|
||||
{
|
||||
DBUG_ENTER("Item_in_subselect::single_value_transformer");
|
||||
Item_in_optimizer *optimizer;
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
if (!optimizer)
|
||||
{
|
||||
current_thd->fatal_error= 1;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/*
|
||||
As far as Item_ref_in_optimizer do not substitude itself on fix_fields
|
||||
we can use same item for all selects.
|
||||
*/
|
||||
Item *expr= new Item_ref_in_optimizer(optimizer, (char *)"<no matter>",
|
||||
(char*)"<left expr>");
|
||||
select_lex->master_unit()->dependent= 1;
|
||||
for (SELECT_LEX * sl= select_lex; sl; sl= sl->next_select())
|
||||
{
|
||||
select_lex->dependent= 1;
|
||||
Item *item;
|
||||
if (sl->item_list.elements > 1)
|
||||
{
|
||||
@ -299,14 +358,14 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
|
||||
else
|
||||
item= (Item*) sl->item_list.pop();
|
||||
|
||||
Item *expr= new Item_outer_select_context_saver(left_expr);
|
||||
|
||||
if (sl->having || sl->with_sum_func || sl->group_list.first ||
|
||||
sl->order_list.first)
|
||||
{
|
||||
sl->item_list.push_back(item);
|
||||
item= (*func)(expr, new Item_ref(sl->item_list.head_ref(),
|
||||
0, (char*)"<result>"));
|
||||
item= (*func)(expr, new Item_ref_null_helper(this,
|
||||
sl->item_list.head_ref(),
|
||||
(char *)"<no matter>",
|
||||
(char*)"<result>"));
|
||||
if (sl->having || sl->with_sum_func || sl->group_list.first)
|
||||
if (sl->having)
|
||||
sl->having= new Item_cond_and(sl->having, item);
|
||||
@ -324,7 +383,9 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
|
||||
sl->item_list.push_back(new Item_int(1));
|
||||
if (sl->table_list.elements)
|
||||
{
|
||||
item= (*func)(expr, new Item_asterisk_remover(item));
|
||||
item= (*func)(expr, new Item_asterisk_remover(this, item,
|
||||
(char *)"<no matter>",
|
||||
(char*)"<result>"));
|
||||
if (sl->where)
|
||||
sl->where= new Item_cond_and(sl->where, item);
|
||||
else
|
||||
@ -340,14 +401,21 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
|
||||
}
|
||||
if (select_lex->next_select())
|
||||
{
|
||||
// it is in union => we should perform it
|
||||
sl->having= (*func)(expr, item);
|
||||
/*
|
||||
It is in union => we should perform it.
|
||||
Item_asterisk_remover used only as wrapper to receine NULL value
|
||||
*/
|
||||
sl->having= (*func)(expr,
|
||||
new Item_asterisk_remover(this, item,
|
||||
(char *)"<no matter>",
|
||||
(char*)"<result>"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// it is single select without tables => possible optimization
|
||||
item= (*func)(left_expr, item);
|
||||
substitution= item;
|
||||
have_to_be_excluded= 1;
|
||||
THD *thd= current_thd;
|
||||
if (thd->lex.describe)
|
||||
{
|
||||
@ -489,7 +557,7 @@ int subselect_single_select_engine::exec()
|
||||
join->thd->where= save_where;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
item->assign_null();
|
||||
item->reset();
|
||||
item->assigned((executed= 0));
|
||||
}
|
||||
if (!executed)
|
||||
|
@ -42,6 +42,8 @@ protected:
|
||||
subselect_engine *engine;
|
||||
/* allowed number of columns (1 for single value subqueries) */
|
||||
uint max_columns;
|
||||
/* work with 'substitution' */
|
||||
bool have_to_be_excluded;
|
||||
|
||||
public:
|
||||
Item_subselect();
|
||||
@ -65,7 +67,7 @@ public:
|
||||
select_subselect *result);
|
||||
|
||||
~Item_subselect();
|
||||
virtual void assign_null()
|
||||
virtual void reset()
|
||||
{
|
||||
null_value= 1;
|
||||
}
|
||||
@ -110,7 +112,7 @@ public:
|
||||
decimals= item->decimals;
|
||||
res_type= item->res_type;
|
||||
}
|
||||
virtual void assign_null()
|
||||
virtual void reset()
|
||||
{
|
||||
null_value= 1;
|
||||
int_value= 0;
|
||||
@ -144,7 +146,7 @@ public:
|
||||
}
|
||||
Item_exists_subselect(): Item_subselect() {}
|
||||
|
||||
virtual void assign_null()
|
||||
virtual void reset()
|
||||
{
|
||||
value= 0;
|
||||
}
|
||||
@ -155,6 +157,7 @@ public:
|
||||
double val();
|
||||
String *val_str(String*);
|
||||
void fix_length_and_dec();
|
||||
|
||||
friend class select_exists_subselect;
|
||||
};
|
||||
|
||||
@ -164,14 +167,26 @@ class Item_in_subselect :public Item_exists_subselect
|
||||
{
|
||||
protected:
|
||||
Item * left_expr;
|
||||
|
||||
bool was_null;
|
||||
public:
|
||||
Item_in_subselect(THD *thd, Item * left_expr, st_select_lex *select_lex);
|
||||
Item_in_subselect(Item_in_subselect *item);
|
||||
Item_in_subselect(): Item_exists_subselect() {}
|
||||
void reset()
|
||||
{
|
||||
value= 0;
|
||||
null_value= 0;
|
||||
was_null= 0;
|
||||
}
|
||||
virtual void select_transformer(st_select_lex *select_lex);
|
||||
void single_value_transformer(st_select_lex *select_lex,
|
||||
Item *left_expr, compare_func_creator func);
|
||||
longlong val_int();
|
||||
double val();
|
||||
String *val_str(String*);
|
||||
|
||||
friend class Item_asterisk_remover;
|
||||
friend class Item_ref_null_helper;
|
||||
};
|
||||
|
||||
/* ALL/ANY/SOME subselect */
|
||||
|
@ -253,12 +253,24 @@ double Item_sum_avg::val()
|
||||
** Standard deviation
|
||||
*/
|
||||
|
||||
void Item_sum_std::reset()
|
||||
double Item_sum_std::val()
|
||||
{
|
||||
sum=sum_sqr=0.0; count=0; (void) Item_sum_std::add();
|
||||
double tmp= Item_sum_variance::val();
|
||||
return tmp <= 0.0 ? 0.0 : sqrt(tmp);
|
||||
}
|
||||
|
||||
bool Item_sum_std::add()
|
||||
/*
|
||||
** variance
|
||||
*/
|
||||
|
||||
void Item_sum_variance::reset()
|
||||
{
|
||||
sum=sum_sqr=0.0;
|
||||
count=0;
|
||||
(void) Item_sum_variance::add();
|
||||
}
|
||||
|
||||
bool Item_sum_variance::add()
|
||||
{
|
||||
double nr=args[0]->val();
|
||||
if (!args[0]->null_value)
|
||||
@ -270,7 +282,7 @@ bool Item_sum_std::add()
|
||||
return 0;
|
||||
}
|
||||
|
||||
double Item_sum_std::val()
|
||||
double Item_sum_variance::val()
|
||||
{
|
||||
if (!count)
|
||||
{
|
||||
@ -281,11 +293,10 @@ double Item_sum_std::val()
|
||||
/* Avoid problems when the precision isn't good enough */
|
||||
double tmp=ulonglong2double(count);
|
||||
double tmp2=(sum_sqr - sum*sum/tmp)/tmp;
|
||||
return tmp2 <= 0.0 ? 0.0 : sqrt(tmp2);
|
||||
return tmp2 <= 0.0 ? 0.0 : tmp2;
|
||||
}
|
||||
|
||||
|
||||
void Item_sum_std::reset_field()
|
||||
void Item_sum_variance::reset_field()
|
||||
{
|
||||
double nr=args[0]->val();
|
||||
char *res=result_field->ptr;
|
||||
@ -302,7 +313,7 @@ void Item_sum_std::reset_field()
|
||||
}
|
||||
}
|
||||
|
||||
void Item_sum_std::update_field(int offset)
|
||||
void Item_sum_variance::update_field(int offset)
|
||||
{
|
||||
double nr,old_nr,old_sqr;
|
||||
longlong field_count;
|
||||
@ -836,6 +847,17 @@ String *Item_avg_field::val_str(String *str)
|
||||
}
|
||||
|
||||
Item_std_field::Item_std_field(Item_sum_std *item)
|
||||
: Item_variance_field(item)
|
||||
{
|
||||
}
|
||||
|
||||
double Item_std_field::val()
|
||||
{
|
||||
double tmp= Item_variance_field::val();
|
||||
return tmp <= 0.0 ? 0.0 : sqrt(tmp);
|
||||
}
|
||||
|
||||
Item_variance_field::Item_variance_field(Item_sum_variance *item)
|
||||
{
|
||||
name=item->name;
|
||||
decimals=item->decimals;
|
||||
@ -844,7 +866,7 @@ Item_std_field::Item_std_field(Item_sum_std *item)
|
||||
maybe_null=1;
|
||||
}
|
||||
|
||||
double Item_std_field::val()
|
||||
double Item_variance_field::val()
|
||||
{
|
||||
double sum,sum_sqr;
|
||||
longlong count;
|
||||
@ -860,10 +882,10 @@ double Item_std_field::val()
|
||||
null_value=0;
|
||||
double tmp= (double) count;
|
||||
double tmp2=(sum_sqr - sum*sum/tmp)/tmp;
|
||||
return tmp2 <= 0.0 ? 0.0 : sqrt(tmp2);
|
||||
return tmp2 <= 0.0 ? 0.0 : tmp2;
|
||||
}
|
||||
|
||||
String *Item_std_field::val_str(String *str)
|
||||
String *Item_variance_field::val_str(String *str)
|
||||
{
|
||||
double nr=val();
|
||||
if (null_value)
|
||||
|
@ -27,7 +27,7 @@ class Item_sum :public Item_result_field
|
||||
{
|
||||
public:
|
||||
enum Sumfunctype {COUNT_FUNC,COUNT_DISTINCT_FUNC,SUM_FUNC,AVG_FUNC,MIN_FUNC,
|
||||
MAX_FUNC, UNIQUE_USERS_FUNC,STD_FUNC,SUM_BIT_FUNC,
|
||||
MAX_FUNC, UNIQUE_USERS_FUNC,STD_FUNC,VARIANCE_FUNC,SUM_BIT_FUNC,
|
||||
UDF_SUM_FUNC };
|
||||
|
||||
Item **args,*tmp_args[2];
|
||||
@ -235,14 +235,14 @@ class Item_sum_avg :public Item_sum_num
|
||||
const char *func_name() const { return "avg"; }
|
||||
};
|
||||
|
||||
class Item_sum_std;
|
||||
class Item_sum_variance;
|
||||
|
||||
class Item_std_field :public Item_result_field
|
||||
class Item_variance_field :public Item_result_field
|
||||
{
|
||||
public:
|
||||
Field *field;
|
||||
Item_std_field(Item_sum_std *item);
|
||||
enum Type type() const { return FIELD_STD_ITEM; }
|
||||
Item_variance_field(Item_sum_variance *item);
|
||||
enum Type type() const {return FIELD_VARIANCE_ITEM; }
|
||||
double val();
|
||||
longlong val_int() { return (longlong) val(); }
|
||||
String *val_str(String*);
|
||||
@ -251,26 +251,63 @@ public:
|
||||
void fix_length_and_dec() {}
|
||||
};
|
||||
|
||||
class Item_sum_std :public Item_sum_num
|
||||
/*
|
||||
|
||||
variance(a) =
|
||||
|
||||
= sum (ai - avg(a))^2 / count(a) )
|
||||
= sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a)
|
||||
= (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) =
|
||||
= (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) =
|
||||
= (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
|
||||
= (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
|
||||
= (sum(ai^2) - sum(a)^2/count(a))/count(a)
|
||||
|
||||
*/
|
||||
|
||||
class Item_sum_variance : public Item_sum_num
|
||||
{
|
||||
double sum;
|
||||
double sum_sqr;
|
||||
double sum, sum_sqr;
|
||||
ulonglong count;
|
||||
void fix_length_and_dec() { decimals+=4; maybe_null=1; }
|
||||
|
||||
public:
|
||||
Item_sum_std(Item *item_par) :Item_sum_num(item_par),count(0) {}
|
||||
enum Sumfunctype sum_func () const { return STD_FUNC; }
|
||||
Item_sum_variance(Item *item_par) :Item_sum_num(item_par),count(0) {}
|
||||
enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
|
||||
void reset();
|
||||
bool add();
|
||||
double val();
|
||||
void reset_field();
|
||||
void update_field(int offset);
|
||||
Item *result_item(Field *field)
|
||||
{ return new Item_std_field(this); }
|
||||
const char *func_name() const { return "std"; }
|
||||
{ return new Item_variance_field(this); }
|
||||
const char *func_name() const { return "variance"; }
|
||||
};
|
||||
|
||||
class Item_sum_std;
|
||||
|
||||
class Item_std_field :public Item_variance_field
|
||||
{
|
||||
public:
|
||||
Item_std_field(Item_sum_std *item);
|
||||
enum Type type() const { return FIELD_STD_ITEM; }
|
||||
double val();
|
||||
};
|
||||
|
||||
/*
|
||||
standard_deviation(a) = sqrt(variance(a))
|
||||
*/
|
||||
|
||||
class Item_sum_std :public Item_sum_variance
|
||||
{
|
||||
public:
|
||||
Item_sum_std(Item *item_par) :Item_sum_variance(item_par){}
|
||||
enum Sumfunctype sum_func () const { return STD_FUNC; }
|
||||
double val();
|
||||
Item *result_item(Field *field)
|
||||
{ return new Item_std_field(this); }
|
||||
const char *func_name() const { return "std"; }
|
||||
};
|
||||
|
||||
// This class is a string or number function depending on num_func
|
||||
|
||||
|
@ -344,6 +344,7 @@ static SYMBOL symbols[] = {
|
||||
{ "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
|
||||
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
|
||||
{ "SQL_THREAD", SYM(SQL_THREAD),0,0},
|
||||
{ "SOUNDS", SYM(SOUNDS_SYM),0,0},
|
||||
{ "SSL", SYM(SSL_SYM),0,0},
|
||||
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
|
||||
{ "START", SYM(START_SYM),0,0},
|
||||
@ -584,6 +585,7 @@ static SYMBOL sql_functions[] = {
|
||||
{ "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP),0,0},
|
||||
{ "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
|
||||
{ "USER", SYM(USER),0,0},
|
||||
{ "VARIANCE", SYM(VARIANCE_SYM),0,0},
|
||||
{ "VERSION", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)},
|
||||
{ "WEEK", SYM(WEEK_SYM),0,0},
|
||||
{ "WEEKDAY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)},
|
||||
|
@ -184,7 +184,6 @@ static uint handler_count;
|
||||
static bool opt_enable_named_pipe = 0;
|
||||
#endif
|
||||
#ifdef __WIN__
|
||||
static bool opt_console=0,start_mode=0;
|
||||
static pthread_cond_t COND_handler_count;
|
||||
static uint handler_count;
|
||||
static bool opt_console=0, start_mode=0, use_opt_args;
|
||||
@ -2160,7 +2159,7 @@ The server will not act as a slave.");
|
||||
(void) thr_setconcurrency(concurrency); // 10 by default
|
||||
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) //IRENA
|
||||
{
|
||||
hEventShutdown=CreateEvent(0, FALSE, FALSE, event_name);
|
||||
hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
|
||||
pthread_t hThread;
|
||||
if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
|
||||
sql_print_error("Warning: Can't create thread to handle shutdown requests");
|
||||
|
@ -933,9 +933,9 @@ bool select_singleval_subselect::send_data(List<Item> &items)
|
||||
calculate value on it & determinate "is it NULL?".
|
||||
*/
|
||||
it->real_value= val_item->val_result();
|
||||
if ((it->null_value= val_item->is_null_result()))
|
||||
if ((it->null_value= val_item->null_value))
|
||||
{
|
||||
it->assign_null();
|
||||
it->reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -25,8 +25,16 @@
|
||||
class Sql_alloc
|
||||
{
|
||||
public:
|
||||
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
|
||||
static void *operator new(size_t size)
|
||||
{
|
||||
return (void*) sql_alloc((uint) size);
|
||||
}
|
||||
static void *operator new[](size_t size)
|
||||
{
|
||||
return (void*) sql_alloc((uint) size);
|
||||
}
|
||||
static void operator delete(void *ptr, size_t size) {} /*lint -e715 */
|
||||
static void operator delete[](void *ptr, size_t size) {}
|
||||
#ifdef HAVE_purify
|
||||
bool dummy;
|
||||
inline Sql_alloc() :dummy(0) {}
|
||||
|
@ -793,6 +793,16 @@ JOIN::exec()
|
||||
HA_POS_ERROR)))
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
/*
|
||||
We don't have to store rows in temp table that doesn't match HAVING if:
|
||||
- we are sorting the table and writing complete group rows to the
|
||||
temp table.
|
||||
- We are using DISTINCT without resolving the distinct as a GROUP BY
|
||||
on all columns.
|
||||
|
||||
If having is not handled here, it will be checked before the row
|
||||
is sent to the client.
|
||||
*/
|
||||
if (having_list &&
|
||||
(sort_and_group || (exec_tmp_table->distinct && !group_list)))
|
||||
having=having_list;
|
||||
@ -3775,13 +3785,14 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||
else
|
||||
return new Field_double(item_sum->max_length,maybe_null,
|
||||
item->name, table, item_sum->decimals);
|
||||
case Item_sum::STD_FUNC: /* Place for sum & count */
|
||||
case Item_sum::VARIANCE_FUNC: /* Place for sum & count */
|
||||
case Item_sum::STD_FUNC:
|
||||
if (group)
|
||||
return new Field_string(sizeof(double)*2+sizeof(longlong),
|
||||
maybe_null, item->name,table,my_charset_bin);
|
||||
else
|
||||
return new Field_double(item_sum->max_length, maybe_null,
|
||||
item->name,table,item_sum->decimals);
|
||||
item->name,table,item_sum->decimals);
|
||||
case Item_sum::UNIQUE_USERS_FUNC:
|
||||
return new Field_long(9,maybe_null,item->name,table,1);
|
||||
default:
|
||||
|
@ -216,7 +216,7 @@ int st_select_lex_unit::exec()
|
||||
if (optimized && item && item->assigned())
|
||||
{
|
||||
item->assigned(0); // We will reinit & rexecute unit
|
||||
item->assign_null();
|
||||
item->reset();
|
||||
table->file->delete_all_rows();
|
||||
}
|
||||
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||
|
@ -100,6 +100,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
%token DIV_SYM
|
||||
%token EQ
|
||||
%token EQUAL_SYM
|
||||
%token SOUNDS_SYM
|
||||
%token GE
|
||||
%token GT_SYM
|
||||
%token LE
|
||||
@ -158,6 +159,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
%token SQL_THREAD
|
||||
%token START_SYM
|
||||
%token STD_SYM
|
||||
%token VARIANCE_SYM
|
||||
%token STOP_SYM
|
||||
%token SUM_SYM
|
||||
%token SUPER_SYM
|
||||
@ -1833,6 +1835,7 @@ expr_expr:
|
||||
| expr OR expr { $$= new Item_cond_or($1,$3); }
|
||||
| expr XOR expr { $$= new Item_cond_xor($1,$3); }
|
||||
| expr AND expr { $$= new Item_cond_and($1,$3); }
|
||||
| expr SOUNDS_SYM LIKE expr { $$= Item_bool_func2::eq_creator(new Item_func_soundex($1), new Item_func_soundex($4));}
|
||||
| expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
|
||||
| expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5));}
|
||||
| expr REGEXP expr { $$= new Item_func_regex($1,$3); }
|
||||
@ -1879,6 +1882,7 @@ no_in_expr:
|
||||
| no_in_expr OR expr { $$= new Item_cond_or($1,$3); }
|
||||
| no_in_expr XOR expr { $$= new Item_cond_xor($1,$3); }
|
||||
| no_in_expr AND expr { $$= new Item_cond_and($1,$3); }
|
||||
| no_in_expr SOUNDS_SYM LIKE expr { $$= Item_bool_func2::eq_creator(new Item_func_soundex($1), new Item_func_soundex($4));}
|
||||
| no_in_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
|
||||
| no_in_expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
|
||||
| no_in_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
|
||||
@ -1933,6 +1937,7 @@ no_and_expr:
|
||||
| no_and_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
|
||||
| no_and_expr OR expr { $$= new Item_cond_or($1,$3); }
|
||||
| no_and_expr XOR expr { $$= new Item_cond_xor($1,$3); }
|
||||
| no_and_expr SOUNDS_SYM LIKE expr { $$= Item_bool_func2::eq_creator(new Item_func_soundex($1), new Item_func_soundex($4));}
|
||||
| no_and_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
|
||||
| no_and_expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
|
||||
| no_and_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
|
||||
@ -2335,6 +2340,8 @@ sum_expr:
|
||||
{ $$=new Item_sum_max($3); }
|
||||
| STD_SYM '(' in_sum_expr ')'
|
||||
{ $$=new Item_sum_std($3); }
|
||||
| VARIANCE_SYM '(' in_sum_expr ')'
|
||||
{ $$=new Item_sum_variance($3); }
|
||||
| SUM_SYM '(' in_sum_expr ')'
|
||||
{ $$=new Item_sum_sum($3); };
|
||||
|
||||
@ -3870,6 +3877,7 @@ keyword:
|
||||
| VALUE_SYM {}
|
||||
| WORK_SYM {}
|
||||
| YEAR_SYM {}
|
||||
| SOUNDS_SYM {}
|
||||
;
|
||||
|
||||
/* Option functions */
|
||||
|
Loading…
x
Reference in New Issue
Block a user