Merge sinisa@work.mysql.com:/home/bk/mysql-4.1

into sinisa.nasamreza.org:/mnt/work/mysql-4.1
This commit is contained in:
Sinisa@sinisa.nasamreza.org 2002-12-14 15:15:23 +02:00
commit ab70ad7c1e
35 changed files with 1382 additions and 316 deletions

View File

@ -90,6 +90,7 @@ tonu@x153.internalnet
tonu@x3.internalnet tonu@x3.internalnet
venu@myvenu.com venu@myvenu.com
venu@work.mysql.com venu@work.mysql.com
vva@eagle.mysql.r18.ru
vva@genie.(none) vva@genie.(none)
walrus@mysql.com walrus@mysql.com
wax@mysql.com wax@mysql.com

View File

@ -32040,6 +32040,10 @@ a single backslash to be matched).
@item expr NOT LIKE pat [ESCAPE 'escape-char'] @item expr NOT LIKE pat [ESCAPE 'escape-char']
Same as @code{NOT (expr 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 mSQL compatibility
@cindex compatibility, with mSQL @cindex compatibility, with mSQL
@findex REGEXP @findex REGEXP

View File

@ -42,21 +42,21 @@ insert into t1 values (null,null,'');
select count(distinct a),count(distinct grp) from t1; select count(distinct a),count(distinct grp) from t1;
count(distinct a) count(distinct grp) count(distinct a) count(distinct grp)
6 3 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; 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) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c) 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 7 0 1 6 E 21 6 3.5000 1.7078 2.9167 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; 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) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c) 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 0 0 NULL NULL NULL 0 0 NULL NULL NULL 0 0 NULL NULL
1 1 1 1.0000 0.0000 1 1 1 1 a a 1 1 1 1.0000 0.0000 0.0000 1 1 1 1 a a
2 5 2 2.5000 0.5000 3 2 2 3 b c 2 5 2 2.5000 0.5000 0.2500 3 2 2 3 b c
3 15 3 5.0000 0.8165 7 4 4 6 C E 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)+bit_or(a)+bit_and(a)+min(a)+max(a)+min(c)+max(c) as sum 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;
grp sum grp sum
NULL NULL NULL NULL
1 7 1 7
2 20 2 20.25
3 44.816496580928 3 45.483163247594
create table t2 (grp int, a bigint unsigned, c char(10)); 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; 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; 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); 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)); CREATE TABLE t2 (id int(11),name char(20));
INSERT INTO t2 VALUES (1,'Set One'),(2,'Set Two'); INSERT INTO t2 VALUES (1,'Set One'),(2,'Set Two');
select id, avg(value1), std(value1) from t1 group by id; select id, avg(value1), std(value1), variance(value1) from t1 group by id;
id avg(value1) std(value1) id avg(value1) std(value1) variance(value1)
1 1.000000 0.816497 1 1.000000 0.816497 0.666667
2 11.000000 0.816497 2 11.000000 0.816497 0.666667
select name, avg(value1), std(value1) from t1, t2 where t1.id = t2.id group by t1.id; 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) name avg(value1) std(value1) variance(value1)
Set One 1.000000 0.816497 Set One 1.000000 0.816497 0.666667
Set Two 11.000000 0.816497 Set Two 11.000000 0.816497 0.666667
drop table t1,t2; drop table t1,t2;
create table t1 (id int not null); create table t1 (id int not null);
create table t2 (id int not null,rating int null); create table t2 (id int not null,rating int null);

View File

@ -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; 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)); CREATE TABLE t1 (field char(1));
INSERT INTO t1 VALUES ('A'),(NULL); INSERT INTO t1 VALUES ('A'),(NULL);
SELECT * from t1 WHERE field IN (NULL); SELECT * from t1 WHERE field IN (NULL);
field field
SELECT * from t1 WHERE field NOT IN (NULL); SELECT * from t1 WHERE field NOT IN (NULL);
field field
A
SELECT * from t1 where field = field; SELECT * from t1 where field = field;
field field
A A
@ -16,6 +100,7 @@ NULL
DELETE FROM t1 WHERE field NOT IN (NULL); DELETE FROM t1 WHERE field NOT IN (NULL);
SELECT * FROM t1; SELECT * FROM t1;
field field
A
NULL NULL
drop table t1; drop table t1;
create table t1 (id int(10) primary key); create table t1 (id int(10) primary key);

View File

@ -80,6 +80,21 @@ this is a REAL test
select soundex(''),soundex('he'),soundex('hello all folks'); select soundex(''),soundex('he'),soundex('hello all folks');
soundex('') soundex('he') soundex('hello all folks') soundex('') soundex('he') soundex('hello all folks')
H000 H4142 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'); select md5('hello');
md5('hello') md5('hello')
5d41402abc4b2a76b9719d911017c592 5d41402abc4b2a76b9719d911017c592

View File

@ -62,4 +62,8 @@ select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null;
Fld1 max(Fld2) Fld1 max(Fld2)
1 20 1 20
3 50 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; drop table t1;

136
mysql-test/r/row.result Normal file
View 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;

View File

@ -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;

View File

@ -2656,14 +2656,14 @@ companynr count(*)
58 23 58 23
53 4 53 4
50 11 50 11
select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 where companynr = 34 and fld4<>""; 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) count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
70 absentee vest 17788966 254128.0857 3272.5940 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 group by companynr limit 3; 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) companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757 00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
29 95 abut wetness 14473298 152350.5053 8368.5480 29 95 abut wetness 14473298 152350.5053 8368.5480 70032594.9026
34 70 absentee vest 17788966 254128.0857 3272.5940 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; 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) companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 1 1 5987435 5987435 5987435 5987435.0000 37 1 1 5987435 5987435 5987435 5987435.0000

View File

@ -598,3 +598,105 @@ INSERT INTO t1 values (1),(1);
UPDATE t SET id=(SELECT * FROM t1); UPDATE t SET id=(SELECT * FROM t1);
Subselect returns more than 1 record Subselect returns more than 1 record
drop table t; 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;

View File

@ -21,9 +21,9 @@ select count(distinct a),count(distinct grp) from t1;
insert into t1 values (null,null,''); insert into t1 values (null,null,'');
select count(distinct a),count(distinct grp) from t1; 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 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),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) 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 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)); 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; 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); 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)); CREATE TABLE t2 (id int(11),name char(20));
INSERT INTO t2 VALUES (1,'Set One'),(2,'Set Two'); INSERT INTO t2 VALUES (1,'Set One'),(2,'Set Two');
select id, avg(value1), std(value1) from t1 group by id; select id, avg(value1), std(value1), variance(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 name, avg(value1), std(value1), variance(value1) from t1, t2 where t1.id = t2.id group by t1.id;
drop table t1,t2; drop table t1,t2;
# #

View File

@ -2,7 +2,39 @@
# test of IN (NULL) # 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; 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)); CREATE TABLE t1 (field char(1));
INSERT INTO t1 VALUES ('A'),(NULL); INSERT INTO t1 VALUES ('A'),(NULL);
SELECT * from t1 WHERE field IN (NULL); SELECT * from t1 WHERE field IN (NULL);

View File

@ -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('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 replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
select soundex(''),soundex('he'),soundex('hello all folks'); 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 md5('hello');
select sha('abc'); select sha('abc');
select sha1('abc'); select sha1('abc');

View File

@ -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 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 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 std(Fld2) is not null;
select Fld1, max(Fld2) from t1 group by Fld1 having variance(Fld2) is not null;
drop table t1; drop table t1;

61
mysql-test/t/row.test Normal file
View 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;

View File

@ -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;

View File

@ -1577,8 +1577,8 @@ select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld
select count(*) from t1; select count(*) from t1;
select companynr,count(*),sum(fld1) from t2 group by companynr; 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 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 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) from t2 group by companynr limit 3; 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 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 /*! 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 ; select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ;

View File

@ -362,3 +362,48 @@ INSERT INTO t1 values (1),(1);
-- error 1240 -- error 1240
UPDATE t SET id=(SELECT * FROM t1); UPDATE t SET id=(SELECT * FROM t1);
drop table t; 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;

View File

@ -46,6 +46,12 @@ Item::Item():
loop_id= 0; 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) bool Item::check_loop(uint id)
{ {
DBUG_ENTER("Item::check_loop"); DBUG_ENTER("Item::check_loop");
@ -436,6 +442,20 @@ String *Item_copy_string::val_str(String *str)
return &str_value; 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) 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); res= item->fix_fields(thd, list, &item);
else else
thd->fatal_error= 1; // no item given => out of memory thd->fatal_error= 1; // no item given => out of memory
*ref= item;
DBUG_RETURN(res); 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) 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); 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); init_make_field(tmp_field,FIELD_TYPE_DOUBLE);
} }

View File

@ -33,7 +33,8 @@ public:
enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM, enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM,
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM, INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM,
COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_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}; SUBSELECT_ITEM, ROW_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@ -72,7 +73,6 @@ public:
virtual double val_result() { return val(); } virtual double val_result() { return val(); }
virtual longlong val_int_result() { return val_int(); } virtual longlong val_int_result() { return val_int(); }
virtual String *str_result(String* tmp) { return val_str(tmp); } 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 table_map used_tables() const { return (table_map) 0L; }
virtual bool basic_const_item() const { return 0; } virtual bool basic_const_item() const { return 0; }
virtual Item *new_item() { return 0; } /* Only for const items */ virtual Item *new_item() { return 0; } /* Only for const items */
@ -100,6 +100,8 @@ public:
virtual Item* el(uint i) { return this; } virtual Item* el(uint i) { return this; }
virtual Item** addr(uint i) { return 0; } virtual Item** addr(uint i) { return 0; }
virtual bool check_cols(uint c); 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); } String* val_str(String* s) { return item->val_str(s); }
void make_field(Send_field* f) { item->make_field(f); } void make_field(Send_field* f) { item->make_field(f); }
bool check_cols(uint col) { return item->check_cols(col); } 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); 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 st_select_lex;
class Item_ident :public Item class Item_ident :public Item
{ {
@ -188,7 +196,6 @@ public:
double val_result(); double val_result();
longlong val_int_result(); longlong val_int_result();
String *str_result(String* tmp); String *str_result(String* tmp);
bool is_null_result() { return result_field->is_null(); }
bool send(THD *thd, String *str_arg) bool send(THD *thd, String *str_arg)
{ {
return result_field->send(thd,str_arg); return result_field->send(thd,str_arg);
@ -384,9 +391,13 @@ public:
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
bool basic_const_item() const { return 1; } bool basic_const_item() const { return 1; }
bool eq(const Item *item, bool binary_cmp) const; 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; } 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); void print(String *str);
}; };
@ -470,25 +481,25 @@ public:
double val() double val()
{ {
double tmp=(*ref)->val_result(); double tmp=(*ref)->val_result();
null_value=(*ref)->is_null_result(); null_value=(*ref)->null_value;
return tmp; return tmp;
} }
longlong val_int() longlong val_int()
{ {
longlong tmp=(*ref)->val_int_result(); longlong tmp=(*ref)->val_int_result();
null_value=(*ref)->is_null_result(); null_value=(*ref)->null_value;
return tmp; return tmp;
} }
String *val_str(String* tmp) String *val_str(String* tmp)
{ {
tmp=(*ref)->str_result(tmp); tmp=(*ref)->str_result(tmp);
null_value=(*ref)->is_null_result(); null_value=(*ref)->null_value;
return tmp; return tmp;
} }
bool is_null() bool is_null()
{ {
(void) (*ref)->val_int_result(); (void) (*ref)->val_int_result();
return (*ref)->is_null_result(); return (*ref)->null_value;
} }
bool get_date(TIME *ltime,bool fuzzydate) bool get_date(TIME *ltime,bool fuzzydate)
{ {
@ -505,6 +516,54 @@ public:
bool check_loop(uint id); 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 The following class is used to optimize comparing of date columns

View File

@ -90,7 +90,7 @@ static bool convert_constant_item(Field *field, Item **item)
void Item_bool_func2::fix_length_and_dec() 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, 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))) if ((comparators= (Arg_comparator *) sql_alloc(sizeof(Arg_comparator)*n)))
for (uint i=0; i < n; i++) 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)); comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
}
else else
{ {
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); 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; 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() longlong Item_func_eq::val_int()
{ {
@ -356,7 +418,8 @@ void Item_func_interval::fix_length_and_dec()
intervals[i]=args[i]->val(); intervals[i]=args[i]->val();
} }
} }
maybe_null=0; max_length=2; maybe_null= 0;
max_length= 2;
used_tables_cache|=item->used_tables(); 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() void Item_func_between::fix_length_and_dec()
{ {
max_length=1; max_length= 1;
/* /*
As some compare functions are generated after sql_yacc, 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() void Item_func_coalesce::fix_length_and_dec()
{ {
max_length=0; max_length= 0;
decimals=0; decimals= 0;
cached_result_type = args[0]->result_type(); cached_result_type = args[0]->result_type();
for (uint i=0 ; i < arg_count ; i++) 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; 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) int in_vector::find(Item *item)
{ {
byte *result=get_value(item); byte *result=get_value(item);
@ -1014,7 +1082,6 @@ int in_vector::find(Item *item)
return (int) ((*compare)(base+start*size,result) == 0); return (int) ((*compare)(base+start*size,result) == 0);
} }
in_string::in_string(uint elements,qsort_cmp cmp_func) in_string::in_string(uint elements,qsort_cmp cmp_func)
:in_vector(elements,sizeof(String),cmp_func),tmp(buff,sizeof(buff),default_charset_info) :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); 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_longlong::in_longlong(uint elements)
:in_vector(elements,sizeof(longlong),(qsort_cmp) cmp_longlong) :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) byte *in_longlong::get_value(Item *item)
{ {
tmp=item->val_int(); tmp= item->val_int();
if (item->null_value) if (item->null_value)
return 0; /* purecov: inspected */ return 0;
return (byte*) &tmp; return (byte*) &tmp;
} }
in_double::in_double(uint elements) in_double::in_double(uint elements)
:in_vector(elements,sizeof(double),(qsort_cmp) cmp_double) :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) byte *in_double::get_value(Item *item)
{ {
tmp=item->val(); tmp= item->val();
if (item->null_value) if (item->null_value)
return 0; /* purecov: inspected */ return 0; /* purecov: inspected */
return (byte*) &tmp; 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() 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()) { switch (item->result_type()) {
case STRING_RESULT: case STRING_RESULT:
if (item->binary()) if (item->binary())
array=new in_string(arg_count,(qsort_cmp) stringcmp); /* purecov: inspected */ array=new in_string(arg_count,(qsort_cmp) stringcmp);
else else
array=new in_string(arg_count,(qsort_cmp) sortcmp); array=new in_string(arg_count,(qsort_cmp) sortcmp);
break; break;
@ -1096,8 +1337,7 @@ void Item_func_in::fix_length_and_dec()
array= new in_double(arg_count); array= new in_double(arg_count);
break; break;
case ROW_RESULT: case ROW_RESULT:
// This case should never be choosen array= new in_row(arg_count, item);
DBUG_ASSERT(0);
break; break;
} }
uint j=0; uint j=0;
@ -1106,33 +1346,18 @@ void Item_func_in::fix_length_and_dec()
array->set(j,args[i]); array->set(j,args[i]);
if (!args[i]->null_value) // Skip NULL values if (!args[i]->null_value) // Skip NULL values
j++; j++;
else
have_null= 1;
} }
if ((array->used_count=j)) if ((array->used_count=j))
array->sort(); array->sort();
} }
else else
{ {
switch (item->result_type()) { in_item= cmp_item:: get_comparator(item);
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;
}
} }
maybe_null= item->maybe_null; maybe_null= item->maybe_null;
max_length=2; max_length= 1;
used_tables_cache|=item->used_tables(); used_tables_cache|=item->used_tables();
const_item_cache&=item->const_item(); const_item_cache&=item->const_item();
} }
@ -1152,17 +1377,20 @@ longlong Item_func_in::val_int()
if (array) if (array)
{ {
int tmp=array->find(item); int tmp=array->find(item);
null_value=item->null_value; null_value=item->null_value || (!tmp && have_null);
return tmp; return tmp;
} }
in_item->store_value(item); in_item->store_value(item);
if ((null_value=item->null_value)) if ((null_value=item->null_value))
return 0; return 0;
have_null= 0;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
if (!in_item->cmp(args[i]) && !args[i]->null_value) if (!in_item->cmp(args[i]) && !args[i]->null_value)
return 1; // Would maybe be nice with i ? return 1; // Would maybe be nice with i ?
have_null|= args[i]->null_value;
} }
null_value= have_null;
return 0; return 0;
} }
@ -1452,7 +1680,8 @@ longlong Item_func_isnotnull::val_int()
void Item_func_like::fix_length_and_dec() 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 // 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)) args[1]->fix_fields(thd,tables, args + 1))
return 1; /* purecov: inspected */ return 1; /* purecov: inspected */
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func; 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()) if (args[0]->binary() || args[1]->binary())
set_charset(my_charset_bin); set_charset(my_charset_bin);

View File

@ -17,6 +17,8 @@
/* compare and test functions */ /* compare and test functions */
#include "assert.h"
#ifdef __GNUC__ #ifdef __GNUC__
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
#endif #endif
@ -38,16 +40,12 @@ public:
Arg_comparator() {}; Arg_comparator() {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2) {}; 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); int set_compare_func(Item_bool_func2 *owner, Item_result type);
inline int set_compare_func(Item_bool_func2 *owner) inline int set_compare_func(Item_bool_func2 *owner)
{ {
return set_compare_func(owner, item_cmp_type((*a)->result_type(), return set_compare_func(owner, item_cmp_type((*a)->result_type(),
(*b)->result_type())); (*b)->result_type()));
} }
inline int set_cmp_func(Item_bool_func2 *owner, inline int set_cmp_func(Item_bool_func2 *owner,
Item **a1, Item **a2, Item **a1, Item **a2,
Item_result type) Item_result type)
@ -87,6 +85,27 @@ public:
void fix_length_and_dec() { decimals=0; max_length=1; } 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 class Item_bool_func2 :public Item_int_func
{ /* Bool with 2 string args */ { /* Bool with 2 string args */
protected: protected:
@ -358,6 +377,7 @@ class in_vector :public Sql_alloc
uint count; uint count;
public: public:
uint used_count; uint used_count;
in_vector() {}
in_vector(uint elements,uint element_length,qsort_cmp cmp_func) in_vector(uint elements,uint element_length,qsort_cmp cmp_func)
:base((char*) sql_calloc(elements*element_length)), :base((char*) sql_calloc(elements*element_length)),
size(element_length), compare(cmp_func), count(elements), size(element_length), compare(cmp_func), count(elements),
@ -372,7 +392,6 @@ public:
int find(Item *item); int find(Item *item);
}; };
class in_string :public in_vector class in_string :public in_vector
{ {
char buff[80]; char buff[80];
@ -384,7 +403,6 @@ public:
byte *get_value(Item *item); byte *get_value(Item *item);
}; };
class in_longlong :public in_vector class in_longlong :public in_vector
{ {
longlong tmp; longlong tmp;
@ -394,7 +412,6 @@ public:
byte *get_value(Item *item); byte *get_value(Item *item);
}; };
class in_double :public in_vector class in_double :public in_vector
{ {
double tmp; double tmp;
@ -404,7 +421,6 @@ public:
byte *get_value(Item *item); byte *get_value(Item *item);
}; };
/* /*
** Classes for easy comparing of non const items ** Classes for easy comparing of non const items
*/ */
@ -414,60 +430,90 @@ class cmp_item :public Sql_alloc
public: public:
cmp_item() {} cmp_item() {}
virtual ~cmp_item() {} virtual ~cmp_item() {}
virtual void store_value(Item *item)=0; virtual void store_value(Item *item)= 0;
virtual int cmp(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);
}
}; };
typedef int (*str_cmp_func_pointer)(const String *, const String *);
class cmp_item_sort_string :public cmp_item { class cmp_item_string :public cmp_item
protected: {
char value_buff[80]; protected:
String value,*value_res; str_cmp_func_pointer str_cmp_func;
String *value_res;
public: 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) void store_value(Item *item)
{ {
value_res=item->val_str(&value); value_res= item->val_str(&value);
} }
int cmp(Item *arg) int cmp(Item *arg)
{ {
char buff[80]; char buff[80];
String tmp(buff,sizeof(buff),default_charset_info),*res; String tmp(buff, sizeof(buff), default_charset_info), *res;
if (!(res=arg->val_str(&tmp))) if (!(res= arg->val_str(&tmp)))
return 1; /* Can't be right */ return 1; /* Can't be right */
return sortcmp(value_res,res); 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 { class cmp_item_binary_string :public cmp_item_sort_string {
public: public:
cmp_item_binary_string() {} cmp_item_binary_string(): cmp_item_sort_string(&stringcmp) {}
int cmp(Item *arg) cmp_item *make_same();
{
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);
}
}; };
class cmp_item_int :public cmp_item class cmp_item_int :public cmp_item
{ {
longlong value; longlong value;
public: public:
void store_value(Item *item) void store_value(Item *item)
{ {
value=item->val_int(); value= item->val_int();
} }
int cmp(Item *arg) 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 class cmp_item_real :public cmp_item
{ {
double value; double value;
@ -480,22 +526,105 @@ public:
{ {
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 class Item_func_in :public Item_int_func
{ {
Item *item; Item *item;
in_vector *array; in_vector *array;
cmp_item *in_item; cmp_item *in_item;
bool have_null;
public: public:
Item_func_in(Item *a,List<Item> &list) 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(); longlong val_int();
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref) bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
{ {
bool res=(item->check_cols(1) || // We do not check item->cols(), because allowed_arg_cols assigned from it
item->fix_fields(thd, tlist, &item) || bool res=(item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref)); Item_func::fix_fields(thd, tlist, ref));
with_sum_func= with_sum_func || item->with_sum_func; with_sum_func= with_sum_func || item->with_sum_func;
return res; return res;
@ -517,10 +646,9 @@ class Item_func_in :public Item_int_func
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_RETURN(item->check_loop(id)); DBUG_RETURN(item->check_loop(id));
} }
bool nulls_in_row();
}; };
/* Functions used by where clause */ /* Functions used by where clause */
class Item_func_isnull :public Item_bool_func class Item_func_isnull :public Item_bool_func

View File

@ -18,8 +18,10 @@
#include "assert.h" #include "assert.h"
Item_row::Item_row(List<Item> &arg): 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)) if ((arg_count= arg.elements))
items= (Item**) sql_alloc(sizeof(Item*)*arg_count); items= (Item**) sql_alloc(sizeof(Item*)*arg_count);
else 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) 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++) for (uint i= 0; i < arg_count; i++)
{ {
if (items[i]->fix_fields(thd, tabl, items+i)) if (items[i]->fix_fields(thd, tabl, items+i))
return 1; 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; 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) bool Item_row::check_cols(uint c)
{ {
if (c != arg_count) if (c != arg_count)
@ -64,3 +81,22 @@ bool Item_row::check_cols(uint c)
} }
return 0; 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;
}

View File

@ -17,13 +17,17 @@
class Item_row: public Item class Item_row: public Item
{ {
bool array_holder; bool array_holder;
table_map tables; table_map used_tables_cache;
bool const_item_cache;
uint arg_count; uint arg_count;
Item **items; Item **items;
public: public:
Item_row(List<Item> &); Item_row(List<Item> &);
Item_row(Item_row *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) items(item->items)
{} {}
@ -56,11 +60,14 @@ public:
return 0; return 0;
}; };
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); 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; } enum Item_result result_type() const { return ROW_RESULT; }
void update_used_tables();
virtual uint cols() { return arg_count; } uint cols() { return arg_count; }
virtual Item* el(uint i) { return items[i]; } Item* el(uint i) { return items[i]; }
virtual Item** addr(uint i) { return items + i; } Item** addr(uint i) { return items + i; }
virtual bool check_cols(uint c); bool check_cols(uint c);
bool null_inside();
}; };

View File

@ -33,9 +33,10 @@ SUBSELECT TODO:
#include "sql_select.h" #include "sql_select.h"
Item_subselect::Item_subselect(): 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 item value is NULL if select_subselect not changed this value
(i.e. some rows will be found returned) (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; (*ref)= substitution;
substitution->name= name; substitution->name= name;
if (have_to_be_excluded)
engine->exclude(); engine->exclude();
return substitution->fix_fields(thd, tables, ref); substitution= 0;
return (*ref)->fix_fields(thd, tables, ref);
} }
char const *save_where= thd->where; char const *save_where= thd->where;
@ -159,7 +162,7 @@ double Item_singleval_subselect::val ()
{ {
if (engine->exec()) if (engine->exec())
{ {
assign_null(); reset();
return 0; return 0;
} }
return real_value; return real_value;
@ -169,7 +172,7 @@ longlong Item_singleval_subselect::val_int ()
{ {
if (engine->exec()) if (engine->exec())
{ {
assign_null(); reset();
return 0; return 0;
} }
return int_value; return int_value;
@ -179,7 +182,7 @@ String *Item_singleval_subselect::val_str (String *str)
{ {
if (engine->exec() || null_value) if (engine->exec() || null_value)
{ {
assign_null(); reset();
return 0; return 0;
} }
return &string_value; return &string_value;
@ -208,9 +211,8 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
left_expr= left_exp; left_expr= left_exp;
init(thd, select_lex, new select_exists_subselect(this)); init(thd, select_lex, new select_exists_subselect(this));
max_columns= UINT_MAX; max_columns= UINT_MAX;
null_value= 0; //can't be NULL maybe_null= 1;
maybe_null= 0; //can't be NULL reset();
value= 0;
// We need only 1 row to determinate existence // We need only 1 row to determinate existence
select_lex->master_unit()->global_parameters->select_limit= 1; select_lex->master_unit()->global_parameters->select_limit= 1;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -226,9 +228,7 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
func= f; func= f;
init(thd, select_lex, new select_exists_subselect(this)); init(thd, select_lex, new select_exists_subselect(this));
max_columns= UINT_MAX; max_columns= UINT_MAX;
null_value= 0; //can't be NULL reset();
maybe_null= 0; //can't be NULL
value= 0;
// We need only 1 row to determinate existence // We need only 1 row to determinate existence
select_lex->master_unit()->global_parameters->select_limit= 1; select_lex->master_unit()->global_parameters->select_limit= 1;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -237,6 +237,7 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
void Item_exists_subselect::fix_length_and_dec() void Item_exists_subselect::fix_length_and_dec()
{ {
decimals=0;
max_length= 1; max_length= 1;
} }
@ -244,7 +245,7 @@ double Item_exists_subselect::val ()
{ {
if (engine->exec()) if (engine->exec())
{ {
assign_null(); reset();
return 0; return 0;
} }
return (double) value; return (double) value;
@ -254,7 +255,7 @@ longlong Item_exists_subselect::val_int ()
{ {
if (engine->exec()) if (engine->exec())
{ {
assign_null(); reset();
return 0; return 0;
} }
return value; return value;
@ -264,7 +265,50 @@ String *Item_exists_subselect::val_str(String *str)
{ {
if (engine->exec()) 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; return 0;
} }
str->set(value,thd_charset()); 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) compare_func_creator func)
{ {
DBUG_ENTER("Item_in_subselect::single_value_transformer"); 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()) for (SELECT_LEX * sl= select_lex; sl; sl= sl->next_select())
{ {
select_lex->dependent= 1;
Item *item; Item *item;
if (sl->item_list.elements > 1) if (sl->item_list.elements > 1)
{ {
@ -299,14 +358,14 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
else else
item= (Item*) sl->item_list.pop(); 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 || if (sl->having || sl->with_sum_func || sl->group_list.first ||
sl->order_list.first) sl->order_list.first)
{ {
sl->item_list.push_back(item); sl->item_list.push_back(item);
item= (*func)(expr, new Item_ref(sl->item_list.head_ref(), item= (*func)(expr, new Item_ref_null_helper(this,
0, (char*)"<result>")); 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->with_sum_func || sl->group_list.first)
if (sl->having) if (sl->having)
sl->having= new Item_cond_and(sl->having, item); 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)); sl->item_list.push_back(new Item_int(1));
if (sl->table_list.elements) 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) if (sl->where)
sl->where= new Item_cond_and(sl->where, item); sl->where= new Item_cond_and(sl->where, item);
else else
@ -340,14 +401,21 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
} }
if (select_lex->next_select()) 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 else
{ {
// it is single select without tables => possible optimization // it is single select without tables => possible optimization
item= (*func)(left_expr, item); item= (*func)(left_expr, item);
substitution= item; substitution= item;
have_to_be_excluded= 1;
THD *thd= current_thd; THD *thd= current_thd;
if (thd->lex.describe) if (thd->lex.describe)
{ {
@ -489,7 +557,7 @@ int subselect_single_select_engine::exec()
join->thd->where= save_where; join->thd->where= save_where;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
item->assign_null(); item->reset();
item->assigned((executed= 0)); item->assigned((executed= 0));
} }
if (!executed) if (!executed)

View File

@ -42,6 +42,8 @@ protected:
subselect_engine *engine; subselect_engine *engine;
/* allowed number of columns (1 for single value subqueries) */ /* allowed number of columns (1 for single value subqueries) */
uint max_columns; uint max_columns;
/* work with 'substitution' */
bool have_to_be_excluded;
public: public:
Item_subselect(); Item_subselect();
@ -65,7 +67,7 @@ public:
select_subselect *result); select_subselect *result);
~Item_subselect(); ~Item_subselect();
virtual void assign_null() virtual void reset()
{ {
null_value= 1; null_value= 1;
} }
@ -110,7 +112,7 @@ public:
decimals= item->decimals; decimals= item->decimals;
res_type= item->res_type; res_type= item->res_type;
} }
virtual void assign_null() virtual void reset()
{ {
null_value= 1; null_value= 1;
int_value= 0; int_value= 0;
@ -144,7 +146,7 @@ public:
} }
Item_exists_subselect(): Item_subselect() {} Item_exists_subselect(): Item_subselect() {}
virtual void assign_null() virtual void reset()
{ {
value= 0; value= 0;
} }
@ -155,6 +157,7 @@ public:
double val(); double val();
String *val_str(String*); String *val_str(String*);
void fix_length_and_dec(); void fix_length_and_dec();
friend class select_exists_subselect; friend class select_exists_subselect;
}; };
@ -164,14 +167,26 @@ class Item_in_subselect :public Item_exists_subselect
{ {
protected: protected:
Item * left_expr; Item * left_expr;
bool was_null;
public: public:
Item_in_subselect(THD *thd, Item * left_expr, st_select_lex *select_lex); Item_in_subselect(THD *thd, Item * left_expr, st_select_lex *select_lex);
Item_in_subselect(Item_in_subselect *item); Item_in_subselect(Item_in_subselect *item);
Item_in_subselect(): Item_exists_subselect() {} 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); virtual void select_transformer(st_select_lex *select_lex);
void single_value_transformer(st_select_lex *select_lex, void single_value_transformer(st_select_lex *select_lex,
Item *left_expr, compare_func_creator func); 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 */ /* ALL/ANY/SOME subselect */

View File

@ -253,12 +253,24 @@ double Item_sum_avg::val()
** Standard deviation ** 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(); double nr=args[0]->val();
if (!args[0]->null_value) if (!args[0]->null_value)
@ -270,7 +282,7 @@ bool Item_sum_std::add()
return 0; return 0;
} }
double Item_sum_std::val() double Item_sum_variance::val()
{ {
if (!count) if (!count)
{ {
@ -281,11 +293,10 @@ double Item_sum_std::val()
/* Avoid problems when the precision isn't good enough */ /* Avoid problems when the precision isn't good enough */
double tmp=ulonglong2double(count); double tmp=ulonglong2double(count);
double tmp2=(sum_sqr - sum*sum/tmp)/tmp; 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_variance::reset_field()
void Item_sum_std::reset_field()
{ {
double nr=args[0]->val(); double nr=args[0]->val();
char *res=result_field->ptr; 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; double nr,old_nr,old_sqr;
longlong field_count; 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_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; name=item->name;
decimals=item->decimals; decimals=item->decimals;
@ -844,7 +866,7 @@ Item_std_field::Item_std_field(Item_sum_std *item)
maybe_null=1; maybe_null=1;
} }
double Item_std_field::val() double Item_variance_field::val()
{ {
double sum,sum_sqr; double sum,sum_sqr;
longlong count; longlong count;
@ -860,10 +882,10 @@ double Item_std_field::val()
null_value=0; null_value=0;
double tmp= (double) count; double tmp= (double) count;
double tmp2=(sum_sqr - sum*sum/tmp)/tmp; 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(); double nr=val();
if (null_value) if (null_value)

View File

@ -27,7 +27,7 @@ class Item_sum :public Item_result_field
{ {
public: public:
enum Sumfunctype {COUNT_FUNC,COUNT_DISTINCT_FUNC,SUM_FUNC,AVG_FUNC,MIN_FUNC, 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 }; UDF_SUM_FUNC };
Item **args,*tmp_args[2]; Item **args,*tmp_args[2];
@ -235,14 +235,14 @@ class Item_sum_avg :public Item_sum_num
const char *func_name() const { return "avg"; } 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: public:
Field *field; Field *field;
Item_std_field(Item_sum_std *item); Item_variance_field(Item_sum_variance *item);
enum Type type() const { return FIELD_STD_ITEM; } enum Type type() const {return FIELD_VARIANCE_ITEM; }
double val(); double val();
longlong val_int() { return (longlong) val(); } longlong val_int() { return (longlong) val(); }
String *val_str(String*); String *val_str(String*);
@ -251,27 +251,64 @@ public:
void fix_length_and_dec() {} 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, sum_sqr;
double sum_sqr;
ulonglong count; ulonglong count;
void fix_length_and_dec() { decimals+=4; maybe_null=1; } void fix_length_and_dec() { decimals+=4; maybe_null=1; }
public: public:
Item_sum_std(Item *item_par) :Item_sum_num(item_par),count(0) {} Item_sum_variance(Item *item_par) :Item_sum_num(item_par),count(0) {}
enum Sumfunctype sum_func () const { return STD_FUNC; } enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
void reset(); void reset();
bool add(); bool add();
double val(); double val();
void reset_field(); void reset_field();
void update_field(int offset); void update_field(int offset);
Item *result_item(Field *field)
{ 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) Item *result_item(Field *field)
{ return new Item_std_field(this); } { return new Item_std_field(this); }
const char *func_name() const { return "std"; } const char *func_name() const { return "std"; }
}; };
// This class is a string or number function depending on num_func // This class is a string or number function depending on num_func
class Item_sum_hybrid :public Item_sum class Item_sum_hybrid :public Item_sum

View File

@ -344,6 +344,7 @@ static SYMBOL symbols[] = {
{ "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0}, { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0}, { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
{ "SQL_THREAD", SYM(SQL_THREAD),0,0}, { "SQL_THREAD", SYM(SQL_THREAD),0,0},
{ "SOUNDS", SYM(SOUNDS_SYM),0,0},
{ "SSL", SYM(SSL_SYM),0,0}, { "SSL", SYM(SSL_SYM),0,0},
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0}, { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
{ "START", SYM(START_SYM),0,0}, { "START", SYM(START_SYM),0,0},
@ -584,6 +585,7 @@ static SYMBOL sql_functions[] = {
{ "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP),0,0}, { "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP),0,0},
{ "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, { "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
{ "USER", SYM(USER),0,0}, { "USER", SYM(USER),0,0},
{ "VARIANCE", SYM(VARIANCE_SYM),0,0},
{ "VERSION", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)}, { "VERSION", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)},
{ "WEEK", SYM(WEEK_SYM),0,0}, { "WEEK", SYM(WEEK_SYM),0,0},
{ "WEEKDAY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)}, { "WEEKDAY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)},

View File

@ -184,7 +184,6 @@ static uint handler_count;
static bool opt_enable_named_pipe = 0; static bool opt_enable_named_pipe = 0;
#endif #endif
#ifdef __WIN__ #ifdef __WIN__
static bool opt_console=0,start_mode=0;
static pthread_cond_t COND_handler_count; static pthread_cond_t COND_handler_count;
static uint handler_count; static uint handler_count;
static bool opt_console=0, start_mode=0, use_opt_args; 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 (void) thr_setconcurrency(concurrency); // 10 by default
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) //IRENA #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; pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
sql_print_error("Warning: Can't create thread to handle shutdown requests"); sql_print_error("Warning: Can't create thread to handle shutdown requests");

View File

@ -933,9 +933,9 @@ bool select_singleval_subselect::send_data(List<Item> &items)
calculate value on it & determinate "is it NULL?". calculate value on it & determinate "is it NULL?".
*/ */
it->real_value= val_item->val_result(); 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 else
{ {

View File

@ -25,8 +25,16 @@
class Sql_alloc class Sql_alloc
{ {
public: 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) {} /*lint -e715 */
static void operator delete[](void *ptr, size_t size) {}
#ifdef HAVE_purify #ifdef HAVE_purify
bool dummy; bool dummy;
inline Sql_alloc() :dummy(0) {} inline Sql_alloc() :dummy(0) {}

View File

@ -793,6 +793,16 @@ JOIN::exec()
HA_POS_ERROR))) HA_POS_ERROR)))
DBUG_VOID_RETURN; 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 && if (having_list &&
(sort_and_group || (exec_tmp_table->distinct && !group_list))) (sort_and_group || (exec_tmp_table->distinct && !group_list)))
having=having_list; having=having_list;
@ -3775,7 +3785,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
else else
return new Field_double(item_sum->max_length,maybe_null, 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::STD_FUNC: /* Place for sum & count */ case Item_sum::VARIANCE_FUNC: /* Place for sum & count */
case Item_sum::STD_FUNC:
if (group) if (group)
return new Field_string(sizeof(double)*2+sizeof(longlong), return new Field_string(sizeof(double)*2+sizeof(longlong),
maybe_null, item->name,table,my_charset_bin); maybe_null, item->name,table,my_charset_bin);

View File

@ -216,7 +216,7 @@ int st_select_lex_unit::exec()
if (optimized && item && item->assigned()) if (optimized && item && item->assigned())
{ {
item->assigned(0); // We will reinit & rexecute unit item->assigned(0); // We will reinit & rexecute unit
item->assign_null(); item->reset();
table->file->delete_all_rows(); table->file->delete_all_rows();
} }
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())

View File

@ -100,6 +100,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DIV_SYM %token DIV_SYM
%token EQ %token EQ
%token EQUAL_SYM %token EQUAL_SYM
%token SOUNDS_SYM
%token GE %token GE
%token GT_SYM %token GT_SYM
%token LE %token LE
@ -158,6 +159,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SQL_THREAD %token SQL_THREAD
%token START_SYM %token START_SYM
%token STD_SYM %token STD_SYM
%token VARIANCE_SYM
%token STOP_SYM %token STOP_SYM
%token SUM_SYM %token SUM_SYM
%token SUPER_SYM %token SUPER_SYM
@ -1833,6 +1835,7 @@ expr_expr:
| expr OR expr { $$= new Item_cond_or($1,$3); } | expr OR expr { $$= new Item_cond_or($1,$3); }
| expr XOR expr { $$= new Item_cond_xor($1,$3); } | expr XOR expr { $$= new Item_cond_xor($1,$3); }
| expr AND expr { $$= new Item_cond_and($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 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 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); } | 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 OR expr { $$= new Item_cond_or($1,$3); }
| no_in_expr XOR expr { $$= new Item_cond_xor($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 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 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 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); } | 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_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| no_and_expr OR expr { $$= new Item_cond_or($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 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 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 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); } | no_and_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
@ -2335,6 +2340,8 @@ sum_expr:
{ $$=new Item_sum_max($3); } { $$=new Item_sum_max($3); }
| STD_SYM '(' in_sum_expr ')' | STD_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_std($3); } { $$=new Item_sum_std($3); }
| VARIANCE_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_variance($3); }
| SUM_SYM '(' in_sum_expr ')' | SUM_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_sum($3); }; { $$=new Item_sum_sum($3); };
@ -3870,6 +3877,7 @@ keyword:
| VALUE_SYM {} | VALUE_SYM {}
| WORK_SYM {} | WORK_SYM {}
| YEAR_SYM {} | YEAR_SYM {}
| SOUNDS_SYM {}
; ;
/* Option functions */ /* Option functions */