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
|
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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
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
|
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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -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);
|
||||||
|
@ -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');
|
||||||
|
@ -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
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 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 ;
|
||||||
|
@ -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;
|
||||||
|
45
sql/item.cc
45
sql/item.cc
@ -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);
|
||||||
}
|
}
|
||||||
|
103
sql/item.h
103
sql/item.h
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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();
|
||||||
};
|
};
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)},
|
||||||
|
@ -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");
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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) {}
|
||||||
|
@ -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);
|
||||||
|
@ -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())
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user