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