merge 4.1->5.0

This commit is contained in:
bell@sanja.is.com.ua 2005-03-31 10:39:48 +03:00
commit 05d4ed14e4
24 changed files with 2028 additions and 554 deletions

View File

@ -240,40 +240,52 @@ if (defined $opt_changelog)
# the last tagged ChangeSet (this relies heavily on our current tagging # the last tagged ChangeSet (this relies heavily on our current tagging
# practice!) # practice!)
# #
my $revision= ""; $opt_changelog=~ s/^=//; # Sometimes, a leading '=' was not stripped.
my $log_base= $opt_changelog;
my $changelogfile;
if ($target_dir =~ m:^/:) # we need an absolute path, as we change directory
{
$changelogfile= $target_dir. "/ChangeLog";
}
else
{
$changelogfile= cwd() . "/" . $target_dir . "/ChangeLog";
}
if ($opt_changelog eq "last") if ($opt_changelog eq "last")
{ {
if (!$opt_revision) if (!$opt_revision)
{ {
$revision= `bk changes -t -d':REV:::TAG:' -n $REPO | grep mysql-$major.$minor | head -1 | cut -f1 -d ":"`; $log_base= `bk changes -t -d':REV:::TAG:' -n $REPO | grep mysql-$major.$minor | head -1 | cut -f1 -d ":"`;
} }
else else
{ {
$revision= `bk changes -r..$opt_revision -t -d':REV:' -n $REPO | head -2 | tail -1`; $log_base= `bk changes -r..$opt_revision -t -d':REV:' -n $REPO | head -2 | tail -1`;
} }
chomp($revision); chomp($log_base);
$opt_changelog= $revision;
} }
$msg= "Adding $target_dir/ChangeLog"; $msg= "Adding $changelogfile";
$msg.= " (down to revision $opt_changelog)" if $opt_changelog ne ""; $msg.= " (down to revision $log_base)" if $log_base ne "";
&logger($msg); &logger($msg);
$command= "bk changes -v"; # Due to a BK error, "bk changes" must be run in $REPO !
$command.= " -r" if ($opt_changelog ne "" || $opt_revision); $command= "cd $REPO ; ";
$command.= $opt_changelog if $opt_changelog ne ""; $command.= "bk changes -v";
$command.= ".." if ($opt_changelog ne "" && !$opt_revision); $command.= " -r" if ($log_base ne "" || $opt_revision);
$command.= $log_base if $log_base ne "";
$command.= ".." if ($log_base ne "" && !$opt_revision);
$command.= ".." . $opt_revision if $opt_revision; $command.= ".." . $opt_revision if $opt_revision;
$command.= " " . $REPO . " > $target_dir/ChangeLog"; $command.= " > $changelogfile";
&logger($command); &logger($command);
# We cannot use run_command here because of output redirection # We cannot use run_command here because of output redirection
unless ($opt_dry_run) unless ($opt_dry_run)
{ {
system($command) == 0 or &abort("Could not create $target_dir/ChangeLog!"); system($command) == 0 or &abort("Could not create $changelogfile!");
} }
} }
# #
# Add the latest manual from the mysqldoc tree # Add the latest manual and tool from the mysqldoc tree
# #
unless ($opt_skip_manual) unless ($opt_skip_manual)
{ {
@ -283,6 +295,8 @@ unless ($opt_skip_manual)
system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0 system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0
or &abort("Could not update $file.texi in $target_dir/Docs/!"); or &abort("Could not update $file.texi in $target_dir/Docs/!");
} }
&run_command("cp $opt_docdir/Docs/Support/texi2html $target_dir/Docs/Support",
"Could not copy $opt_docdir/Docs/Support/texi2html!");
&run_command("rm -f $target_dir/Docs/Images/Makefile*", &run_command("rm -f $target_dir/Docs/Images/Makefile*",
"Could not remove Makefiles in $target_dir/Docs/Images/!"); "Could not remove Makefiles in $target_dir/Docs/Images/!");

View File

@ -783,7 +783,7 @@ insert into t1 values (now());
create table t2 select f2 from (select max(now()) f2 from t1) a; create table t2 select f2 from (select max(now()) f2 from t1) a;
show columns from t2; show columns from t2;
Field Type Null Key Default Extra Field Type Null Key Default Extra
f2 datetime NO 0000-00-00 00:00:00 f2 datetime YES NULL
drop table t2; drop table t2;
create table t2 select f2 from (select now() f2 from t1) a; create table t2 select f2 from (select now() f2 from t1) a;
show columns from t2; show columns from t2;

View File

@ -677,3 +677,28 @@ select sum(a)*sum(b) as d from t1 where a=1 group by c having d > 0;
d d
10 10
drop table t1; drop table t1;
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(8),(9);
create table t2 (
a int,
b varchar(200) NOT NULL,
c varchar(50) NOT NULL,
d varchar(100) NOT NULL,
primary key (a,b(132),c,d),
key a (a,b)
) charset=utf8;
insert into t2 select
x3.a, -- 3
concat('val-', x3.a + 3*x4.a), -- 12
concat('val-', @a:=x3.a + 3*x4.a + 12*C.a), -- 120
concat('val-', @a + 120*D.a)
from t1 x3, t1 x4, t1 C, t1 D where x3.a < 3 and x4.a < 4 and D.a < 4;
delete from t2 where a = 2 and b = 'val-2' limit 30;
explain select c from t2 where a = 2 and b = 'val-2' group by c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref PRIMARY,a PRIMARY 400 const,const 6 Using where
select c from t2 where a = 2 and b = 'val-2' group by c;
c
val-74
val-98
drop table t1,t2;

View File

@ -55,8 +55,33 @@ id data data
2 female no 2 female no
select t1.id from t1 union select t2.id from t2; select t1.id from t1 union select t2.id from t2;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t1 t1 id id 1 3 1 Y 32768 0 63 def id id 1 4 1 Y 32768 0 63
id id
1 1
2 2
drop table t1,t2; drop table t1,t2;
create table t1 ( a int, b varchar(30), primary key(a));
insert into t1 values (1,'one');
insert into t1 values (2,'two');
set @arg00=1 ;
select @arg00 FROM t1 where a=1 union distinct select 1 FROM t1 where a=1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def @arg00 @arg00 8 20 1 Y 32768 0 63
@arg00
1
select * from (select @arg00) aaa;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def aaa @arg00 @arg00 8 20 1 Y 32768 0 63
@arg00
1
select 1 union select 1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def 1 1 8 20 1 N 32769 0 63
1
1
select * from (select 1 union select 1) aaa;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def aaa 1 1 8 20 1 N 32769 0 63
1
1
drop table t1;

View File

@ -1883,6 +1883,380 @@ SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
a a
1 1
3 3
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2);
a
3
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2);
a
1
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2);
a
2
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2);
a
2
3
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2);
a
1
2
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2);
a
1
3
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2);
a
3
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2);
a
1
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2);
a
2
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2);
a
2
3
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2);
a
1
2
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2);
a
1
3
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
3
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
1
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
2
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
2
3
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
1
2
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
1
3
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
3
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
1
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
2
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
2
3
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
1
2
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
a
1
3
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
3
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
1
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
2
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
2
3
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
1
2
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
1
3
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
3
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
1
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
2
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
2
3
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
1
2
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
a
1
3
SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE a > ANY (SELECT a,2 FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a,2 FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE a > ALL (SELECT a,2 FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a,2 FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE (1,2) = ALL (SELECT a,2 FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE (1,2) <> ANY (SELECT a,2 FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 2 column(s)
SELECT a FROM t1 WHERE a = ANY (SELECT a,2 FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a,2 FROM t1 WHERE b = 2);
a
SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 2 column(s)
SELECT a FROM t1 WHERE a <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
ERROR 21000: Operand should contain 1 column(s)
SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
a
1
2
3
SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2);
a
2
SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2);
a
1
3
SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2);
a
2
SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2);
a
1
3
SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
a
2
SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
a
1
3
SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
a
2
SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
a
1
3
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 group by a);
a
3
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 group by a);
a
1
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 group by a);
a
2
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
a
2
3
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
a
1
2
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 group by a);
a
1
3
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 group by a);
a
3
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 group by a);
a
1
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 group by a);
a
2
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
a
2
3
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
a
1
2
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 group by a);
a
1
3
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 group by a HAVING a = 2);
a
3
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 group by a HAVING a = 2);
a
1
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 group by a HAVING a = 2);
a
2
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 group by a HAVING a = 2);
a
2
3
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 group by a HAVING a = 2);
a
1
2
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 group by a HAVING a = 2);
a
1
3
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 group by a HAVING a = 2);
a
3
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 group by a HAVING a = 2);
a
1
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 group by a HAVING a = 2);
a
2
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 group by a HAVING a = 2);
a
2
3
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 group by a HAVING a = 2);
a
1
2
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 group by a HAVING a = 2);
a
1
3
SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-') from t1 a;
concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-')
0-
0-
1-
SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-') from t1 a;
concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-')
1-
0-
0-
SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-') from t1 a;
concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-')
0-
1-
0-
DROP TABLE t1;
CREATE TABLE t1 ( a double, b double );
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2e0);
a
3
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2e0);
a
1
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2e0);
a
2
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2e0);
a
2
3
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2e0);
a
1
2
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2e0);
a
1
3
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2e0);
a
3
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2e0);
a
1
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2e0);
a
2
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2e0);
a
2
3
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2e0);
a
1
2
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2e0);
a
1
3
DROP TABLE t1;
CREATE TABLE t1 ( a char(1), b char(1));
INSERT INTO t1 VALUES ('1','1'),('2','2'),('3','3');
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = '2');
a
3
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = '2');
a
1
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = '2');
a
2
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = '2');
a
2
3
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = '2');
a
1
2
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = '2');
a
1
3
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = '2');
a
3
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = '2');
a
1
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = '2');
a
2
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = '2');
a
2
3
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = '2');
a
1
2
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2');
a
1
3
DROP TABLE t1; DROP TABLE t1;
create table t1 (a int, b int); create table t1 (a int, b int);
insert into t1 values (1,2),(3,4); insert into t1 values (1,2),(3,4);
@ -2138,7 +2512,7 @@ drop table t1;
create table t1 (a1 int); create table t1 (a1 int);
create table t2 (b1 int); create table t2 (b1 int);
select * from t1 where a2 > any(select b1 from t2); select * from t1 where a2 > any(select b1 from t2);
ERROR 42S22: Unknown column 'a2' in 'scalar IN/ALL/ANY subquery' ERROR 42S22: Unknown column 'a2' in 'IN/ALL/ANY subquery'
select * from t1 where a1 > any(select b1 from t2); select * from t1 where a1 > any(select b1 from t2);
a1 a1
drop table t1,t2; drop table t1,t2;
@ -2277,7 +2651,63 @@ pass userid parentid parentgroup childid groupname grouptypeid crse categoryid c
1 5141 12 group2 12 group2 5 1 1 87 Oct04 1 5141 12 group2 12 group2 5 1 1 87 Oct04
1 5141 12 group2 12 group2 5 1 2 88 Oct04 1 5141 12 group2 12 group2 5 1 2 88 Oct04
1 5141 12 group2 12 group2 5 1 2 89 Oct04 1 5141 12 group2 12 group2 5 1 2 89 Oct04
drop table if exists t1, t2, t3, t4, t5; drop table t1, t2, t3, t4, t5;
create table t1 (a int);
insert into t1 values (1), (2), (3);
SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
1
1
1
1
drop table t1;
create table t1 (a int);
create table t2 (a int);
insert into t1 values (1),(2);
insert into t2 values (0),(1),(2),(3);
select a from t2 where a in (select a from t1);
a
1
2
select a from t2 having a in (select a from t1);
a
1
2
prepare stmt1 from "select a from t2 where a in (select a from t1)";
execute stmt1;
a
1
2
execute stmt1;
a
1
2
deallocate prepare stmt1;
prepare stmt1 from "select a from t2 having a in (select a from t1)";
execute stmt1;
a
1
2
execute stmt1;
a
1
2
deallocate prepare stmt1;
drop table t1, t2;
create table t1 (a int, b int);
insert into t1 values (1,2);
select 1 = (select * from t1);
ERROR 21000: Operand should contain 1 column(s)
select (select * from t1) = 1;
ERROR 21000: Operand should contain 2 column(s)
select (1,2) = (select a from t1);
ERROR 21000: Operand should contain 2 column(s)
select (select a from t1) = (1,2);
ERROR 21000: Operand should contain 1 column(s)
select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
ERROR 21000: Operand should contain 2 column(s)
drop table t1;
create table t1 (df decimal(5,1)); create table t1 (df decimal(5,1));
insert into t1 values(1.1); insert into t1 values(1.1);
insert into t1 values(2.2); insert into t1 values(2.2);

View File

@ -732,7 +732,7 @@ tetetetetest
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`dt` blob `dt` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
create table t1 SELECT sv from t2 UNION select b from t2; create table t1 SELECT sv from t2 UNION select b from t2;
@ -755,7 +755,7 @@ tetetetetest
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`i` blob `i` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
create table t1 SELECT sv from t2 UNION select tx from t2; create table t1 SELECT sv from t2 UNION select tx from t2;
@ -766,7 +766,7 @@ teeeeeeeeeeeest
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`sv` text `sv` longtext
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
create table t1 SELECT b from t2 UNION select tx from t2; create table t1 SELECT b from t2 UNION select tx from t2;
@ -1200,3 +1200,38 @@ select concat('value is: ', @val) union select 'some text';
concat('value is: ', @val) concat('value is: ', @val)
value is: 6 value is: 6
some text some text
CREATE TABLE t1 (
a ENUM('ä','ö','ü') character set utf8 not null default 'ü',
b ENUM("one", "two") character set utf8,
c ENUM("one", "two")
);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('ä','ö','ü') character set utf8 NOT NULL default 'ü',
`b` enum('one','two') character set utf8 default NULL,
`c` enum('one','two') default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('ä', 'one', 'one'), ('ö', 'two', 'one'), ('ü', NULL, NULL);
create table t2 select NULL union select a from t1;
show columns from t2;
Field Type Null Key Default Extra
NULL enum('ä','ö','ü') YES NULL
drop table t2;
create table t2 select a from t1 union select NULL;
show columns from t2;
Field Type Null Key Default Extra
a enum('ä','ö','ü') YES NULL
drop table t2;
create table t2 select a from t1 union select a from t1;
show columns from t2;
Field Type Null Key Default Extra
a char(1)
drop table t2;
create table t2 select a from t1 union select c from t1;
ERROR HY000: Illegal mix of collations (utf8_general_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation 'UNION'
create table t2 select a from t1 union select b from t1;
show columns from t2;
Field Type Null Key Default Extra
a varchar(3) YES NULL
drop table t2, t1;

View File

@ -489,3 +489,28 @@ select a,sum(b) from t1 where a=1 group by c having a=1;
select a as d,sum(b) from t1 where a=1 group by c having d=1; select a as d,sum(b) from t1 where a=1 group by c having d=1;
select sum(a)*sum(b) as d from t1 where a=1 group by c having d > 0; select sum(a)*sum(b) as d from t1 where a=1 group by c having d > 0;
drop table t1; drop table t1;
# Test for BUG#9213 GROUP BY query on utf-8 key returns wrong results
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(8),(9);
create table t2 (
a int,
b varchar(200) NOT NULL,
c varchar(50) NOT NULL,
d varchar(100) NOT NULL,
primary key (a,b(132),c,d),
key a (a,b)
) charset=utf8;
insert into t2 select
x3.a, -- 3
concat('val-', x3.a + 3*x4.a), -- 12
concat('val-', @a:=x3.a + 3*x4.a + 12*C.a), -- 120
concat('val-', @a + 120*D.a)
from t1 x3, t1 x4, t1 C, t1 D where x3.a < 3 and x4.a < 4 and D.a < 4;
delete from t2 where a = 2 and b = 'val-2' limit 30;
explain select c from t2 where a = 2 and b = 'val-2' group by c;
select c from t2 where a = 2 and b = 'val-2' group by c;
drop table t1,t2;

View File

@ -34,4 +34,17 @@ select t1.id, t1.data, t2.data from t1, t2 where t1.id = t2.id order by t1.id;
select t1.id from t1 union select t2.id from t2; select t1.id from t1 union select t2.id from t2;
drop table t1,t2; drop table t1,t2;
#
# variables union and derived tables metadata test
#
create table t1 ( a int, b varchar(30), primary key(a));
insert into t1 values (1,'one');
insert into t1 values (2,'two');
set @arg00=1 ;
select @arg00 FROM t1 where a=1 union distinct select 1 FROM t1 where a=1;
select * from (select @arg00) aaa;
select 1 union select 1;
select * from (select 1 union select 1) aaa;
drop table t1;
--disable_metadata --disable_metadata

View File

@ -1153,6 +1153,7 @@ SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 ); SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 ); SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 ); SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
# with index
ALTER TABLE t1 ADD INDEX (a); ALTER TABLE t1 ADD INDEX (a);
SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 ); SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 ); SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
@ -1166,7 +1167,144 @@ SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 ); SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 ); SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 ); SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
# having clause test
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2);
# union test
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
# union + having test
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
# row tests
# < > >= <= and = ALL/ <> ANY do not support row operation
-- error 1241
SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE a > ANY (SELECT a,2 FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a,2 FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE a > ALL (SELECT a,2 FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a,2 FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE (1,2) = ALL (SELECT a,2 FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE (1,2) <> ANY (SELECT a,2 FROM t1 WHERE b = 2);
# following should be converted to IN
-- error 1241
SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE a = ANY (SELECT a,2 FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a,2 FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a FROM t1 WHERE b = 2);
-- error 1241
SELECT a FROM t1 WHERE a <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
# without optimisation
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 group by a);
# without optimisation + having
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 group by a HAVING a = 2);
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 group by a HAVING a = 2);
# EXISTS in string contence
SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-') from t1 a;
SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-') from t1 a;
SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-') from t1 a;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 ( a double, b double );
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2e0);
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2e0);
DROP TABLE t1;
CREATE TABLE t1 ( a char(1), b char(1));
INSERT INTO t1 VALUES ('1','1'),('2','2'),('3','3');
SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = '2');
SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2');
DROP TABLE t1;
# #
# SELECT(EXISTS * ...)optimisation # SELECT(EXISTS * ...)optimisation
@ -1443,8 +1581,9 @@ select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL; select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
drop table t1; drop table t1;
#
# Test for BUG#8218 # Test for BUG#8218
#
CREATE TABLE t1 ( CREATE TABLE t1 (
categoryId int(11) NOT NULL, categoryId int(11) NOT NULL,
courseId int(11) NOT NULL, courseId int(11) NOT NULL,
@ -1541,10 +1680,57 @@ join
group by group by
groupstuff.groupname, colhead , t2.courseid; groupstuff.groupname, colhead , t2.courseid;
drop table if exists t1, t2, t3, t4, t5; drop table t1, t2, t3, t4, t5;
#
# Transformation in left expression of subquery (BUG#8888)
#
create table t1 (a int);
insert into t1 values (1), (2), (3);
SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
drop table t1;
#
# subselect into HAVING clause (code covarage improvement)
#
create table t1 (a int);
create table t2 (a int);
insert into t1 values (1),(2);
insert into t2 values (0),(1),(2),(3);
select a from t2 where a in (select a from t1);
select a from t2 having a in (select a from t1);
prepare stmt1 from "select a from t2 where a in (select a from t1)";
execute stmt1;
execute stmt1;
deallocate prepare stmt1;
prepare stmt1 from "select a from t2 having a in (select a from t1)";
execute stmt1;
execute stmt1;
deallocate prepare stmt1;
drop table t1, t2;
#
# single row subqueries and row operations (code covarage improvement)
#
create table t1 (a int, b int);
insert into t1 values (1,2);
-- error 1241
select 1 = (select * from t1);
-- error 1241
select (select * from t1) = 1;
-- error 1241
select (1,2) = (select a from t1);
-- error 1241
select (select a from t1) = (1,2);
-- error 1241
select (1,2,3) = (select * from t1);
-- error 1241
select (select * from t1) = (1,2,3);
drop table t1
#
#decimal-related tests #decimal-related tests
#
create table t1 (df decimal(5,1)); create table t1 (df decimal(5,1));
insert into t1 values(1.1); insert into t1 values(1.1);
insert into t1 values(2.2); insert into t1 values(2.2);

View File

@ -735,3 +735,28 @@ drop table t1;
# #
set @val:=6; set @val:=6;
select concat('value is: ', @val) union select 'some text'; select concat('value is: ', @val) union select 'some text';
#
# Enum merging test
#
CREATE TABLE t1 (
a ENUM('ä','ö','ü') character set utf8 not null default 'ü',
b ENUM("one", "two") character set utf8,
c ENUM("one", "two")
);
show create table t1;
insert into t1 values ('ä', 'one', 'one'), ('ö', 'two', 'one'), ('ü', NULL, NULL);
create table t2 select NULL union select a from t1;
show columns from t2;
drop table t2;
create table t2 select a from t1 union select NULL;
show columns from t2;
drop table t2;
create table t2 select a from t1 union select a from t1;
show columns from t2;
drop table t2;
-- error 1267
create table t2 select a from t1 union select c from t1;
create table t2 select a from t1 union select b from t1;
show columns from t2;
drop table t2, t1;

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,17 @@ class Protocol;
struct st_cache_field; struct st_cache_field;
void field_conv(Field *to,Field *from); void field_conv(Field *to,Field *from);
inline uint get_enum_pack_length(int elements)
{
return elements < 256 ? 1 : 2;
}
inline uint get_set_pack_length(int elements)
{
uint len= (elements + 7) / 8;
return len > 4 ? 8 : len;
}
class Field class Field
{ {
Field(const Item &); /* Prevent use of these */ Field(const Item &); /* Prevent use of these */
@ -71,18 +82,6 @@ public:
GEOM_GEOMETRYCOLLECTION = 7 GEOM_GEOMETRYCOLLECTION = 7
}; };
enum imagetype { itRAW, itMBR}; enum imagetype { itRAW, itMBR};
enum field_cast_enum
{
FIELD_CAST_STOP, FIELD_CAST_DECIMAL, FIELD_CAST_TINY, FIELD_CAST_SHORT,
FIELD_CAST_MEDIUM, FIELD_CAST_LONG, FIELD_CAST_LONGLONG,
FIELD_CAST_FLOAT, FIELD_CAST_DOUBLE,
FIELD_CAST_NULL,
FIELD_CAST_TIMESTAMP, FIELD_CAST_YEAR, FIELD_CAST_DATE, FIELD_CAST_NEWDATE,
FIELD_CAST_TIME, FIELD_CAST_DATETIME,
FIELD_CAST_STRING, FIELD_CAST_VARSTRING, FIELD_CAST_BLOB,
FIELD_CAST_GEOM, FIELD_CAST_ENUM, FIELD_CAST_SET, FIELD_CAST_BIT,
FIELD_CAST_NEWDECIMAL
};
utype unireg_check; utype unireg_check;
uint32 field_length; // Length of field uint32 field_length; // Length of field
@ -119,6 +118,8 @@ public:
String *val_int_as_str(String *val_buffer, my_bool unsigned_flag); String *val_int_as_str(String *val_buffer, my_bool unsigned_flag);
virtual Item_result result_type () const=0; virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); } virtual Item_result cmp_type () const { return result_type(); }
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
static Item_result result_merge_type(enum_field_types);
bool eq(Field *field) bool eq(Field *field)
{ {
return (ptr == field->ptr && null_ptr == field->null_ptr && return (ptr == field->ptr && null_ptr == field->null_ptr &&
@ -296,8 +297,6 @@ public:
return (op_result == E_DEC_OVERFLOW); return (op_result == E_DEC_OVERFLOW);
} }
int warn_if_overflow(int op_result); int warn_if_overflow(int op_result);
virtual field_cast_enum field_cast_type()= 0;
bool field_cast_compatible(field_cast_enum type);
/* maximum possible display length */ /* maximum possible display length */
virtual uint32 max_length()= 0; virtual uint32 max_length()= 0;
/* length of field value symbolic representation (in bytes) */ /* length of field value symbolic representation (in bytes) */
@ -432,7 +431,6 @@ public:
bool zero_pack() const { return 0; } bool zero_pack() const { return 0; }
void sql_type(String &str) const; void sql_type(String &str) const;
uint32 max_length() { return field_length; } uint32 max_length() { return field_length; }
field_cast_enum field_cast_type() { return FIELD_CAST_DECIMAL; }
}; };
@ -504,7 +502,6 @@ public:
uint32 pack_length() const { return 1; } uint32 pack_length() const { return 1; }
void sql_type(String &str) const; void sql_type(String &str) const;
uint32 max_length() { return 4; } uint32 max_length() { return 4; }
field_cast_enum field_cast_type() { return FIELD_CAST_TINY; }
}; };
@ -541,7 +538,6 @@ public:
uint32 pack_length() const { return 2; } uint32 pack_length() const { return 2; }
void sql_type(String &str) const; void sql_type(String &str) const;
uint32 max_length() { return 6; } uint32 max_length() { return 6; }
field_cast_enum field_cast_type() { return FIELD_CAST_SHORT; }
}; };
@ -573,7 +569,6 @@ public:
uint32 pack_length() const { return 3; } uint32 pack_length() const { return 3; }
void sql_type(String &str) const; void sql_type(String &str) const;
uint32 max_length() { return 8; } uint32 max_length() { return 8; }
field_cast_enum field_cast_type() { return FIELD_CAST_MEDIUM; }
}; };
@ -610,7 +605,6 @@ public:
uint32 pack_length() const { return 4; } uint32 pack_length() const { return 4; }
void sql_type(String &str) const; void sql_type(String &str) const;
uint32 max_length() { return 11; } uint32 max_length() { return 11; }
field_cast_enum field_cast_type() { return FIELD_CAST_LONG; }
}; };
@ -650,7 +644,6 @@ public:
void sql_type(String &str) const; void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; } bool can_be_compared_as_longlong() const { return TRUE; }
uint32 max_length() { return 20; } uint32 max_length() { return 20; }
field_cast_enum field_cast_type() { return FIELD_CAST_LONGLONG; }
}; };
#endif #endif
@ -686,7 +679,6 @@ public:
uint32 pack_length() const { return sizeof(float); } uint32 pack_length() const { return sizeof(float); }
void sql_type(String &str) const; void sql_type(String &str) const;
uint32 max_length() { return 24; } uint32 max_length() { return 24; }
field_cast_enum field_cast_type() { return FIELD_CAST_FLOAT; }
}; };
@ -721,7 +713,6 @@ public:
uint32 pack_length() const { return sizeof(double); } uint32 pack_length() const { return sizeof(double); }
void sql_type(String &str) const; void sql_type(String &str) const;
uint32 max_length() { return 53; } uint32 max_length() { return 53; }
field_cast_enum field_cast_type() { return FIELD_CAST_DOUBLE; }
}; };
@ -754,7 +745,6 @@ public:
void sql_type(String &str) const; void sql_type(String &str) const;
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
uint32 max_length() { return 4; } uint32 max_length() { return 4; }
field_cast_enum field_cast_type() { return FIELD_CAST_NULL; }
}; };
@ -806,7 +796,6 @@ public:
} }
bool get_date(TIME *ltime,uint fuzzydate); bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime); bool get_time(TIME *ltime);
field_cast_enum field_cast_type() { return FIELD_CAST_TIMESTAMP; }
timestamp_auto_set_type get_auto_set_type() const; timestamp_auto_set_type get_auto_set_type() const;
}; };
@ -830,7 +819,6 @@ public:
bool send_binary(Protocol *protocol); bool send_binary(Protocol *protocol);
void sql_type(String &str) const; void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; } bool can_be_compared_as_longlong() const { return TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_YEAR; }
}; };
@ -863,7 +851,6 @@ public:
void sql_type(String &str) const; void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; } bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; } bool zero_pack() const { return 1; }
field_cast_enum field_cast_type() { return FIELD_CAST_DATE; }
}; };
class Field_newdate :public Field_str { class Field_newdate :public Field_str {
@ -895,7 +882,6 @@ public:
bool zero_pack() const { return 1; } bool zero_pack() const { return 1; }
bool get_date(TIME *ltime,uint fuzzydate); bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime); bool get_time(TIME *ltime);
field_cast_enum field_cast_type() { return FIELD_CAST_NEWDATE; }
}; };
@ -931,7 +917,6 @@ public:
void sql_type(String &str) const; void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; } bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; } bool zero_pack() const { return 1; }
field_cast_enum field_cast_type() { return FIELD_CAST_TIME; }
}; };
@ -969,7 +954,6 @@ public:
bool zero_pack() const { return 1; } bool zero_pack() const { return 1; }
bool get_date(TIME *ltime,uint fuzzydate); bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime); bool get_time(TIME *ltime);
field_cast_enum field_cast_type() { return FIELD_CAST_DATETIME; }
}; };
@ -1019,7 +1003,6 @@ public:
bool has_charset(void) const bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; } { return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_STRING; } field_cast_enum field_cast_type() { return FIELD_CAST_STRING; }
Field *new_field(MEM_ROOT *root, struct st_table *new_table);
}; };
@ -1085,7 +1068,6 @@ public:
enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; } enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
bool has_charset(void) const bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; } { return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; }
Field *new_field(MEM_ROOT *root, struct st_table *new_table); Field *new_field(MEM_ROOT *root, struct st_table *new_table);
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table, Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
char *new_ptr, uchar *new_null_ptr, char *new_ptr, uchar *new_null_ptr,
@ -1183,7 +1165,6 @@ public:
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
bool has_charset(void) const bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; } { return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_BLOB; }
uint32 max_length(); uint32 max_length();
}; };
@ -1213,7 +1194,6 @@ public:
int store(longlong nr) { return 1; } int store(longlong nr) { return 1; }
int store_decimal(const my_decimal *) { return 1; } int store_decimal(const my_decimal *) { return 1; }
void get_key_image(char *buff,uint length,imagetype type); void get_key_image(char *buff,uint length,imagetype type);
field_cast_enum field_cast_type() { return FIELD_CAST_GEOM; }
}; };
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
@ -1258,7 +1238,6 @@ public:
bool has_charset(void) const { return TRUE; } bool has_charset(void) const { return TRUE; }
/* enum and set are sorted as integers */ /* enum and set are sorted as integers */
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
field_cast_enum field_cast_type() { return FIELD_CAST_ENUM; }
}; };
@ -1284,7 +1263,6 @@ public:
void sql_type(String &str) const; void sql_type(String &str) const;
enum_field_types real_type() const { return FIELD_TYPE_SET; } enum_field_types real_type() const { return FIELD_TYPE_SET; }
bool has_charset(void) const { return TRUE; } bool has_charset(void) const { return TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_SET; }
}; };
@ -1424,7 +1402,6 @@ enum_field_types get_blob_type_from_length(ulong length);
uint32 calc_pack_length(enum_field_types type,uint32 length); uint32 calc_pack_length(enum_field_types type,uint32 length);
int set_field_to_null(Field *field); int set_field_to_null(Field *field);
int set_field_to_null_with_conversions(Field *field, bool no_conversions); int set_field_to_null_with_conversions(Field *field, bool no_conversions);
bool field_types_to_be_kept(enum_field_types field_type);
/* /*
The following are for the interface with the .frm file The following are for the interface with the .frm file

View File

@ -3041,10 +3041,10 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
case MYSQL_TYPE_NULL: case MYSQL_TYPE_NULL:
return new Field_null((char*) 0, max_length, Field::NONE, return new Field_null((char*) 0, max_length, Field::NONE,
name, table, &my_charset_bin); name, table, &my_charset_bin);
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_INT24: case MYSQL_TYPE_INT24:
return new Field_medium((char*) 0, max_length, null_ptr, 0, Field::NONE, return new Field_medium((char*) 0, max_length, null_ptr, 0, Field::NONE,
name, table, 0, unsigned_flag); name, table, 0, unsigned_flag);
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATE:
return new Field_date(maybe_null, name, table, &my_charset_bin); return new Field_date(maybe_null, name, table, &my_charset_bin);
case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIME:
@ -4681,225 +4681,274 @@ void Item_cache_row::bring_value()
} }
/* Item_type_holder::Item_type_holder(THD *thd, Item *item)
Returns field for temporary table dependind on item type :Item(thd, item), enum_set_typelib(0), fld_type(get_real_type(item))
SYNOPSIS
get_holder_example_field()
thd - thread handler
item - pointer to item
table - empty table object
NOTE
It is possible to return field for Item_func
items only if field type of this item is
date or time or datetime type.
also see function field_types_to_be_kept() from
field.cc
RETURN
# - field
0 - no field
*/
Field *get_holder_example_field(THD *thd, Item *item, TABLE *table)
{
DBUG_ASSERT(table != 0);
Item_func *tmp_item= 0;
if (item->type() == Item::FIELD_ITEM)
return (((Item_field*) item)->field);
if (item->type() == Item::FUNC_ITEM)
tmp_item= (Item_func *) item;
else if (item->type() == Item::SUM_FUNC_ITEM)
{
Item_sum *item_sum= (Item_sum *) item;
if (item_sum->keep_field_type())
{
if (item_sum->args[0]->type() == Item::FIELD_ITEM)
return (((Item_field*) item_sum->args[0])->field);
if (item_sum->args[0]->type() == Item::FUNC_ITEM)
tmp_item= (Item_func *) item_sum->args[0];
}
}
return (tmp_item && field_types_to_be_kept(tmp_item->field_type()) ?
tmp_item->tmp_table_field(table) : 0);
}
Item_type_holder::Item_type_holder(THD *thd, Item *item, TABLE *table)
:Item(thd, item), item_type(item->result_type()),
orig_type(item_type)
{ {
DBUG_ASSERT(item->fixed); DBUG_ASSERT(item->fixed);
/* max_length= display_length(item);
It is safe assign pointer on field, because it will be used just after
all JOIN::prepare calls and before any SELECT execution
*/
field_example= get_holder_example_field(thd, item, table);
max_length= real_length(item);
maybe_null= item->maybe_null; maybe_null= item->maybe_null;
collation.set(item->collation); collation.set(item->collation);
get_full_info(item);
} }
/* /*
STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT DECIMAL_RESULT Return expression type of Item_type_holder
ROW_RESULT should never appear in Item_type_holder::join_types,
but it is included in following table just to make table full
(there DBUG_ASSERT in function to catch ROW_RESULT)
*/
static Item_result type_convertor[5][5]=
{{STRING_RESULT, STRING_RESULT, STRING_RESULT, ROW_RESULT, STRING_RESULT},
{STRING_RESULT, REAL_RESULT, REAL_RESULT, ROW_RESULT, REAL_RESULT},
{STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT},
{ROW_RESULT, ROW_RESULT, ROW_RESULT, ROW_RESULT, ROW_RESULT},
{STRING_RESULT, REAL_RESULT, DECIMAL_RESULT, ROW_RESULT, DECIMAL_RESULT}};
/*
Values of 'from' field can be stored in 'to' field.
SYNOPSIS SYNOPSIS
is_attr_compatible() Item_type_holder::result_type()
from Item which values should be saved
to Item where values should be saved
RETURN RETURN
1 can be saved Item_result (type of internal MySQL expression result)
0 can not be saved
*/ */
inline bool is_attr_compatible(Item *from, Item *to) Item_result Item_type_holder::result_type() const
{ {
return ((to->max_length >= from->max_length) && return Field::result_merge_type(fld_type);
((to->result_type() != DECIMAL_RESULT &&
to->result_type() != REAL_RESULT &&
to->result_type() != INT_RESULT) ||
(to->decimals >= from->decimals) &&
((to->max_length - to->decimals) >=
(from->max_length - from->decimals))) &&
(to->maybe_null || !from->maybe_null) &&
(to->result_type() != STRING_RESULT ||
from->result_type() != STRING_RESULT ||
(from->collation.collation == to->collation.collation)));
} }
bool Item_type_holder::join_types(THD *thd, Item *item, TABLE *table) /*
Find real field type of item
SYNOPSIS
Item_type_holder::get_real_type()
RETURN
type of field which should be created to store item value
*/
enum_field_types Item_type_holder::get_real_type(Item *item)
{ {
uint32 new_length= real_length(item); switch(item->type())
bool use_new_field= 0, use_expression_type= 0;
Item_result new_result_type= type_convertor[item_type][item->result_type()];
Field *field= get_holder_example_field(thd, item, table);
bool item_is_a_field= (field != NULL);
/*
Check if both items point to fields: in this case we
can adjust column types of result table in the union smartly.
*/
if (field_example && item_is_a_field)
{ {
/* Can 'field_example' field store data of the column? */ case FIELD_ITEM:
if ((use_new_field=
(!field->field_cast_compatible(field_example->field_cast_type()) ||
!is_attr_compatible(item, this))))
{
/*
The old field can't store value of the new field.
Check if the new field can store value of the old one.
*/
use_expression_type|=
(!field_example->field_cast_compatible(field->field_cast_type()) ||
!is_attr_compatible(this, item));
}
}
else if (field_example || item_is_a_field)
{ {
/* /*
Expression types can't be mixed with field types, we have to use Item_fields::field_type ask Field_type() but sometimes field return
expression types. a different type, like for enum/set, so we need to ask real type.
*/ */
use_new_field= 1; // make next if test easier Field *field= ((Item_field *) item)->field;
use_expression_type= 1; enum_field_types type= field->real_type();
/* work around about varchar type field detection */
if (type == MYSQL_TYPE_STRING && field->type() == MYSQL_TYPE_VAR_STRING)
return MYSQL_TYPE_VAR_STRING;
return type;
} }
case SUM_FUNC_ITEM:
/* Check whether size/type of the result item should be changed */
if (use_new_field ||
(new_result_type != item_type) || (new_length > max_length) ||
(!maybe_null && item->maybe_null) ||
((new_result_type == REAL_RESULT || new_result_type == DECIMAL_RESULT) &&
(decimals < item->decimals ||
(max_length - decimals) < (new_length - item->decimals))) ||
(item_type == STRING_RESULT &&
collation.collation != item->collation.collation))
{ {
const char *old_cs,*old_derivation; /*
if (use_expression_type || !item_is_a_field) Argument of aggregate function sometimes should be asked about field
field_example= 0; type
else */
Item_sum *item_sum= (Item_sum *) item;
if (item_sum->keep_field_type())
return get_real_type(item_sum->args[0]);
break;
}
case FUNC_ITEM:
if (((Item_func *) item)->functype() == Item_func::VAR_VALUE_FUNC)
{ {
/* /*
It is safe to assign a pointer to field here, because it will be used There are work around of problem with changing variable type on the
before any table is closed. fly and variable always report "string" as field type to get
acceptable information for client in send_field, so we make field
type from expression type.
*/ */
field_example= field; switch (item->result_type())
{
case STRING_RESULT:
return MYSQL_TYPE_VAR_STRING;
case INT_RESULT:
return MYSQL_TYPE_LONGLONG;
case REAL_RESULT:
return MYSQL_TYPE_DOUBLE;
case ROW_RESULT:
default:
DBUG_ASSERT(0);
return MYSQL_TYPE_VAR_STRING;
}
} }
break;
old_cs= collation.collation->name; default:
old_derivation= collation.derivation_name(); break;
if (item_type == STRING_RESULT && collation.aggregate(item->collation))
{
my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
old_cs, old_derivation,
item->collation.collation->name,
item->collation.derivation_name(),
"UNION");
return 1;
}
if (new_result_type == DECIMAL_RESULT)
{
int intp1= new_length - item->decimals;
int intp2= max_length - decimals;
max_length= max(intp1, intp2);
decimals= max(decimals, item->decimals);
/* can't be overflow because it work only for decimals (no strings) */
max_length+= decimals;
}
else
{
max_length= max(max_length, new_length);
decimals= max(decimals, item->decimals);
}
maybe_null|= item->maybe_null;
item_type= new_result_type;
} }
DBUG_ASSERT(item_type != ROW_RESULT); return item->field_type();
return 0;
} }
/*
Find field type which can carry current Item_type_holder type and
type of given Item.
uint32 Item_type_holder::real_length(Item *item) SYNOPSIS
Item_type_holder::join_types()
thd thread handler
item given item to join its parameters with this item ones
RETURN
TRUE error - types are incompatible
FALSE OK
*/
bool Item_type_holder::join_types(THD *thd, Item *item)
{
max_length= max(max_length, display_length(item));
fld_type= Field::field_type_merge(fld_type, get_real_type(item));
if (Field::result_merge_type(fld_type) == STRING_RESULT)
{
const char *old_cs, *old_derivation;
old_cs= collation.collation->name;
old_derivation= collation.derivation_name();
if (collation.aggregate(item->collation))
{
my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
old_cs, old_derivation,
item->collation.collation->name,
item->collation.derivation_name(),
"UNION");
return TRUE;
}
}
decimals= max(decimals, item->decimals);
maybe_null|= item->maybe_null;
get_full_info(item);
return FALSE;
}
/*
Calculate lenth for merging result for given Item type
SYNOPSIS
Item_type_holder::real_length()
item Item for lrngth detection
RETURN
length
*/
uint32 Item_type_holder::display_length(Item *item)
{ {
if (item->type() == Item::FIELD_ITEM) if (item->type() == Item::FIELD_ITEM)
return ((Item_field *)item)->max_disp_length(); return ((Item_field *)item)->max_disp_length();
switch (item->result_type()) { switch (item->field_type())
case STRING_RESULT: {
case DECIMAL_RESULT: case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_GEOMETRY:
return item->max_length; return item->max_length;
case REAL_RESULT: case MYSQL_TYPE_TINY:
return 4;
case MYSQL_TYPE_SHORT:
return 6;
case MYSQL_TYPE_LONG:
return 11;
case MYSQL_TYPE_FLOAT:
return 25;
case MYSQL_TYPE_DOUBLE:
return 53; return 53;
case INT_RESULT: case MYSQL_TYPE_NULL:
return 4;
case MYSQL_TYPE_LONGLONG:
return 20; return 20;
case ROW_RESULT: case MYSQL_TYPE_INT24:
return 8;
default: default:
DBUG_ASSERT(0); // we should never go there DBUG_ASSERT(0); // we should never go there
return 0; return 0;
} }
} }
/*
Make temporary table field according collected information about type
of UNION result
SYNOPSIS
Item_type_holder::make_field_by_type()
table temporary table for which we create fields
RETURN
created field
*/
Field *Item_type_holder::make_field_by_type(TABLE *table)
{
/*
The field functions defines a field to be not null if null_ptr is not 0
*/
uchar *null_ptr= maybe_null ? (uchar*) "" : 0;
switch (fld_type)
{
case MYSQL_TYPE_ENUM:
DBUG_ASSERT(enum_set_typelib);
return new Field_enum((char *) 0, max_length, null_ptr, 0,
Field::NONE, name,
table, get_enum_pack_length(enum_set_typelib->count),
enum_set_typelib, collation.collation);
case MYSQL_TYPE_SET:
DBUG_ASSERT(enum_set_typelib);
return new Field_set((char *) 0, max_length, null_ptr, 0,
Field::NONE, name,
table, get_set_pack_length(enum_set_typelib->count),
enum_set_typelib, collation.collation);
case MYSQL_TYPE_VAR_STRING:
table->db_create_options|= HA_OPTION_PACK_RECORD;
return new Field_string(max_length, maybe_null, name, table,
collation.collation);
default:
break;
}
return tmp_table_field_from_field_type(table);
}
/*
Get full information from Item about enum/set fields to be able to create
them later
SYNOPSIS
Item_type_holder::get_full_info
item Item for information collection
*/
void Item_type_holder::get_full_info(Item *item)
{
if (fld_type == MYSQL_TYPE_ENUM ||
fld_type == MYSQL_TYPE_SET)
{
/*
We can have enum/set type after merging only if we have one enum/set
field and number of NULL fields
*/
DBUG_ASSERT((enum_set_typelib &&
get_real_type(item) == MYSQL_TYPE_NULL) ||
(!enum_set_typelib &&
item->type() == Item::FIELD_ITEM &&
(get_real_type(item) == MYSQL_TYPE_ENUM ||
get_real_type(item) == MYSQL_TYPE_SET) &&
((Field_enum*)((Item_field *) item)->field)->typelib));
if (!enum_set_typelib)
{
enum_set_typelib= ((Field_enum*)((Item_field *) item)->field)->typelib;
}
}
}
double Item_type_holder::val_real() double Item_type_holder::val_real()
{ {
DBUG_ASSERT(0); // should never be called DBUG_ASSERT(0); // should never be called

View File

@ -1782,33 +1782,33 @@ public:
/* /*
Used to store type. name, length of Item for UNIONS & derived table Item_type_holder used to store type. name, length of Item for UNIONS &
derived tables.
Item_type_holder do not need cleanup() because its time of live limited by
single SP/PS execution.
*/ */
class Item_type_holder: public Item class Item_type_holder: public Item
{ {
protected: protected:
Item_result item_type; TYPELIB *enum_set_typelib;
Item_result orig_type; enum_field_types fld_type;
Field *field_example;
public:
Item_type_holder(THD*, Item*, TABLE *);
Item_result result_type () const { return item_type; } void get_full_info(Item *item);
public:
Item_type_holder(THD*, Item*);
Item_result result_type() const;
virtual enum_field_types field_type() const { return fld_type; };
enum Type type() const { return TYPE_HOLDER; } enum Type type() const { return TYPE_HOLDER; }
double val_real(); double val_real();
longlong val_int(); longlong val_int();
my_decimal *val_decimal(my_decimal *); my_decimal *val_decimal(my_decimal *);
String *val_str(String*); String *val_str(String*);
bool join_types(THD *thd, Item *, TABLE *); bool join_types(THD *thd, Item *);
Field *example() { return field_example; } Field *make_field_by_type(TABLE *table);
static uint32 real_length(Item *item); static uint32 display_length(Item *item);
void cleanup() static enum_field_types get_real_type(Item *);
{
DBUG_ENTER("Item_type_holder::cleanup");
Item::cleanup();
item_type= orig_type;
DBUG_VOID_RETURN;
}
}; };

View File

@ -54,7 +54,7 @@ public:
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
NOT_FUNC, NOT_ALL_FUNC, NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_FUNC, NOW_FUNC, TRIG_COND_FUNC,
GUSERVAR_FUNC}; GUSERVAR_FUNC, VAR_VALUE_FUNC};
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL }; OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; } enum Type type() const { return FUNC_ITEM; }
@ -1124,6 +1124,7 @@ public:
select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b) select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b)
*/ */
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
enum Functype functype() const { return VAR_VALUE_FUNC; }
const char *func_name() const { return "get_user_var"; } const char *func_name() const { return "get_user_var"; }
bool const_item() const; bool const_item() const;
table_map used_tables() const table_map used_tables() const

View File

@ -379,20 +379,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
*/ */
substitution->walk(&Item::remove_dependence_processor, substitution->walk(&Item::remove_dependence_processor,
(byte *) select_lex->outer_select()); (byte *) select_lex->outer_select());
if (join->conds || join->having) /* SELECT without FROM clause can't have WHERE or HAVING clause */
{ DBUG_ASSERT(join->conds == 0 && join->having == 0);
Item *cond;
if (!join->having)
cond= join->conds;
else if (!join->conds)
cond= join->having;
else
if (!(cond= new Item_cond_and(join->conds, join->having)))
goto err;
if (!(substitution= new Item_func_if(cond, substitution,
new Item_null())))
goto err;
}
return RES_REDUCE; return RES_REDUCE;
} }
return RES_OK; return RES_OK;
@ -579,7 +567,7 @@ bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
Item_in_subselect::Item_in_subselect(Item * left_exp, Item_in_subselect::Item_in_subselect(Item * left_exp,
st_select_lex *select_lex): st_select_lex *select_lex):
Item_exists_subselect(), transformed(0), upper_item(0) Item_exists_subselect(), optimizer(0), transformed(0), upper_item(0)
{ {
DBUG_ENTER("Item_in_subselect::Item_in_subselect"); DBUG_ENTER("Item_in_subselect::Item_in_subselect");
left_expr= left_exp; left_expr= left_exp;
@ -656,6 +644,11 @@ String *Item_exists_subselect::val_str(String *str)
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value) my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
{ {
/*
As far as Item_in_subselect called only from Item_in_optimizer this
method should not be used
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (exec()) if (exec())
{ {
@ -681,6 +674,11 @@ bool Item_exists_subselect::val_bool()
double Item_in_subselect::val_real() double Item_in_subselect::val_real()
{ {
/*
As far as Item_in_subselect called only from Item_in_optimizer this
method should not be used
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (exec()) if (exec())
{ {
@ -693,8 +691,14 @@ double Item_in_subselect::val_real()
return (double) value; return (double) value;
} }
longlong Item_in_subselect::val_int() longlong Item_in_subselect::val_int()
{ {
/*
As far as Item_in_subselect called only from Item_in_optimizer this
method should not be used
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (exec()) if (exec())
{ {
@ -707,8 +711,14 @@ longlong Item_in_subselect::val_int()
return value; return value;
} }
String *Item_in_subselect::val_str(String *str) String *Item_in_subselect::val_str(String *str)
{ {
/*
As far as Item_in_subselect called only from Item_in_optimizer this
method should not be used
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (exec()) if (exec())
{ {
@ -732,19 +742,10 @@ Item_subselect::trans_res
Item_in_subselect::single_value_transformer(JOIN *join, Item_in_subselect::single_value_transformer(JOIN *join,
Comp_creator *func) Comp_creator *func)
{ {
const char *save_where= thd->where;
Item_subselect::trans_res result= RES_ERROR; Item_subselect::trans_res result= RES_ERROR;
DBUG_ENTER("Item_in_subselect::single_value_transformer"); DBUG_ENTER("Item_in_subselect::single_value_transformer");
if (changed)
{
DBUG_RETURN(RES_OK);
}
SELECT_LEX *select_lex= join->select_lex; SELECT_LEX *select_lex= join->select_lex;
Item_arena *arena, backup;
arena= thd->change_arena_if_needed(&backup);
thd->where= "scalar IN/ALL/ANY subquery";
/* /*
Check that the right part of the subselect contains no more than one Check that the right part of the subselect contains no more than one
@ -753,7 +754,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (select_lex->item_list.elements > 1) if (select_lex->item_list.elements > 1)
{ {
my_error(ER_OPERAND_COLUMNS, MYF(0), 1); my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
goto err; DBUG_RETURN(RES_ERROR);
} }
/* /*
@ -773,11 +774,12 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (substitution) if (substitution)
{ {
// It is second (third, ...) SELECT of UNION => All is done // It is second (third, ...) SELECT of UNION => All is done
goto ok; DBUG_RETURN(RES_OK);
} }
Item *subs; Item *subs;
if (!select_lex->group_list.elements && if (!select_lex->group_list.elements &&
!select_lex->having &&
!select_lex->with_sum_func && !select_lex->with_sum_func &&
!(select_lex->next_select())) !(select_lex->next_select()))
{ {
@ -813,7 +815,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
we do not check item->fixed we do not check item->fixed
*/ */
if (item->fix_fields(thd, join->tables_list, 0)) if (item->fix_fields(thd, join->tables_list, 0))
goto err; DBUG_RETURN(RES_ERROR);
/* we added aggregate function => we have to change statistic */ /* we added aggregate function => we have to change statistic */
count_field_types(&join->tmp_table_param, join->all_fields, 0); count_field_types(&join->tmp_table_param, join->all_fields, 0);
@ -829,25 +831,16 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (upper_item) if (upper_item)
upper_item->set_sub_test(item); upper_item->set_sub_test(item);
} }
// left expression belong to outer select /* fix fields is already called for left expression */
SELECT_LEX *current= thd->lex->current_select, *up;
thd->lex->current_select= up= current->return_after_parsing();
if (!left_expr->fixed &&
left_expr->fix_fields(thd, up->get_table_list(), &left_expr))
{
thd->lex->current_select= current;
goto err;
}
thd->lex->current_select= current;
substitution= func->create(left_expr, subs); substitution= func->create(left_expr, subs);
goto ok; DBUG_RETURN(RES_OK);
} }
if (!substitution) if (!substitution)
{ {
//first call for this unit //first call for this unit
SELECT_LEX_UNIT *unit= select_lex->master_unit(); SELECT_LEX_UNIT *unit= select_lex->master_unit();
substitution= optimizer= new Item_in_optimizer(left_expr, this); substitution= optimizer;
SELECT_LEX *current= thd->lex->current_select, *up; SELECT_LEX *current= thd->lex->current_select, *up;
@ -856,7 +849,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0)) if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
{ {
thd->lex->current_select= current; thd->lex->current_select= current;
goto err; DBUG_RETURN(RES_ERROR);
} }
thd->lex->current_select= current; thd->lex->current_select= current;
@ -907,7 +900,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
tmp= join->having->fix_fields(thd, join->tables_list, 0); tmp= join->having->fix_fields(thd, join->tables_list, 0);
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
if (tmp) if (tmp)
goto err; DBUG_RETURN(RES_ERROR);
} }
else else
{ {
@ -943,7 +936,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
tmp= join->having->fix_fields(thd, join->tables_list, 0); tmp= join->having->fix_fields(thd, join->tables_list, 0);
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
if (tmp) if (tmp)
goto err; DBUG_RETURN(RES_ERROR);
item= new Item_cond_or(item, item= new Item_cond_or(item,
new Item_func_isnull(orig_item)); new Item_func_isnull(orig_item));
#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE #ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE
@ -963,7 +956,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
after creation after creation
*/ */
if (join->conds->fix_fields(thd, join->tables_list, 0)) if (join->conds->fix_fields(thd, join->tables_list, 0))
goto err; DBUG_RETURN(RES_ERROR);
} }
else else
{ {
@ -992,7 +985,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
tmp= join->having->fix_fields(thd, join->tables_list, 0); tmp= join->having->fix_fields(thd, join->tables_list, 0);
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
if (tmp) if (tmp)
goto err; DBUG_RETURN(RES_ERROR);
} }
else else
{ {
@ -1008,51 +1001,33 @@ Item_in_subselect::single_value_transformer(JOIN *join,
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SELECT_REDUCED, warn_buff); ER_SELECT_REDUCED, warn_buff);
} }
result= RES_REDUCE; DBUG_RETURN(RES_REDUCE);
goto err;
} }
} }
} }
ok: DBUG_RETURN(RES_OK);
thd->where= save_where;
result= RES_OK;
err:
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(result);
} }
Item_subselect::trans_res Item_subselect::trans_res
Item_in_subselect::row_value_transformer(JOIN *join) Item_in_subselect::row_value_transformer(JOIN *join)
{ {
const char *save_where= thd->where;
Item *item= 0; Item *item= 0;
SELECT_LEX *select_lex= join->select_lex; SELECT_LEX *select_lex= join->select_lex;
DBUG_ENTER("Item_in_subselect::row_value_transformer"); DBUG_ENTER("Item_in_subselect::row_value_transformer");
if (changed)
{
DBUG_RETURN(RES_OK);
}
thd->where= "row IN/ALL/ANY subquery";
Item_arena *arena, backup;
arena= thd->change_arena_if_needed(&backup);
if (select_lex->item_list.elements != left_expr->cols()) if (select_lex->item_list.elements != left_expr->cols())
{ {
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols()); my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
goto err; DBUG_RETURN(RES_ERROR);
} }
if (!substitution) if (!substitution)
{ {
//first call for this unit //first call for this unit
SELECT_LEX_UNIT *unit= select_lex->master_unit(); SELECT_LEX_UNIT *unit= select_lex->master_unit();
substitution= optimizer= new Item_in_optimizer(left_expr, this); substitution= optimizer;
SELECT_LEX *current= thd->lex->current_select, *up; SELECT_LEX *current= thd->lex->current_select, *up;
thd->lex->current_select= up= current->return_after_parsing(); thd->lex->current_select= up= current->return_after_parsing();
@ -1060,7 +1035,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0)) if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
{ {
thd->lex->current_select= current; thd->lex->current_select= current;
goto err; DBUG_RETURN(RES_ERROR);
} }
// we will refer to upper level cache array => we have to save it in PS // we will refer to upper level cache array => we have to save it in PS
@ -1079,7 +1054,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed); DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed);
if (select_lex->ref_pointer_array[i]-> if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->el(i)->cols())) check_cols(left_expr->el(i)->cols()))
goto err; DBUG_RETURN(RES_ERROR);
Item *func= new Item_ref_null_helper(this, Item *func= new Item_ref_null_helper(this,
select_lex->ref_pointer_array+i, select_lex->ref_pointer_array+i,
(char *) "<no matter>", (char *) "<no matter>",
@ -1111,7 +1086,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if (join->having->fix_fields(thd, join->tables_list, 0)) if (join->having->fix_fields(thd, join->tables_list, 0))
{ {
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
goto err; DBUG_RETURN(RES_ERROR);
} }
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
} }
@ -1128,27 +1103,113 @@ Item_in_subselect::row_value_transformer(JOIN *join)
join->conds->fixed join->conds->fixed
*/ */
if (join->conds->fix_fields(thd, join->tables_list, 0)) if (join->conds->fix_fields(thd, join->tables_list, 0))
goto err; DBUG_RETURN(RES_ERROR);
} }
thd->where= save_where;
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(RES_OK);
err: DBUG_RETURN(RES_OK);
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(RES_ERROR);
} }
Item_subselect::trans_res Item_subselect::trans_res
Item_in_subselect::select_transformer(JOIN *join) Item_in_subselect::select_transformer(JOIN *join)
{ {
return select_in_like_transformer(join, &eq_creator);
}
/*
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
transformation function
SYNOPSIS
Item_in_subselect::select_in_like_transformer()
join JOIN object of transforming subquery
func creator of condition function of subquery
DESCRIPTION
To decide which transformation procedure (scalar or row) applicable here
we have to call fix_fields() for left expression to be able to call
cols() method on it. Also this method make arena management for
underlying transformation methods.
RETURN
RES_OK OK
RES_REDUCE OK, and current subquery was reduced during transformation
RES_ERROR Error
*/
Item_subselect::trans_res
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
{
Item_arena *arena, backup;
SELECT_LEX *current= thd->lex->current_select, *up;
const char *save_where= thd->where;
Item_subselect::trans_res res= RES_ERROR;
bool result;
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
if (changed)
{
DBUG_RETURN(RES_OK);
}
thd->where= "IN/ALL/ANY subquery";
/*
In some optimisation cases we will not need this Item_in_optimizer
object, but we can't know it here, but here we need address correct
reference on left expresion.
*/
if (!optimizer)
{
arena= thd->change_arena_if_needed(&backup);
result= (!(optimizer= new Item_in_optimizer(left_expr, this)));
if (arena)
thd->restore_backup_item_arena(arena, &backup);
if (result)
goto err;
}
thd->lex->current_select= up= current->return_after_parsing();
result= (!left_expr->fixed &&
left_expr->fix_fields(thd, up->get_table_list(),
optimizer->arguments()));
/* fix_fields can change reference to left_expr, we need reassign it */
left_expr= optimizer->arguments()[0];
thd->lex->current_select= current;
if (result)
goto err;
transformed= 1; transformed= 1;
arena= thd->change_arena_if_needed(&backup);
/*
Both transformers call fix_fields() only for Items created inside them,
and all that items do not make permanent changes in current item arena
which allow to us call them with changed arena (if we do not know nature
of Item, we have to call fix_fields() for it only with original arena to
avoid memory leack)
*/
if (left_expr->cols() == 1) if (left_expr->cols() == 1)
return single_value_transformer(join, &eq_creator); res= single_value_transformer(join, func);
return row_value_transformer(join); else
{
/* we do not support row operation for ALL/ANY/SOME */
if (func != &eq_creator)
{
if (arena)
thd->restore_backup_item_arena(arena, &backup);
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
DBUG_RETURN(RES_ERROR);
}
res= row_value_transformer(join);
}
if (arena)
thd->restore_backup_item_arena(arena, &backup);
err:
thd->where= save_where;
DBUG_RETURN(res);
} }
@ -1171,7 +1232,7 @@ Item_allany_subselect::select_transformer(JOIN *join)
transformed= 1; transformed= 1;
if (upper_item) if (upper_item)
upper_item->show= 1; upper_item->show= 1;
return single_value_transformer(join, func); return select_in_like_transformer(join, func);
} }
@ -1279,7 +1340,7 @@ int subselect_single_select_engine::prepare()
int subselect_union_engine::prepare() int subselect_union_engine::prepare()
{ {
return unit->prepare(thd, result, SELECT_NO_UNLOCK); return unit->prepare(thd, result, SELECT_NO_UNLOCK, "");
} }
int subselect_uniquesubquery_engine::prepare() int subselect_uniquesubquery_engine::prepare()

View File

@ -225,7 +225,8 @@ public:
Item_in_subselect(Item * left_expr, st_select_lex *select_lex); Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
Item_in_subselect() Item_in_subselect()
:Item_exists_subselect(), abort_on_null(0), transformed(0), upper_item(0) :Item_exists_subselect(), optimizer(0), abort_on_null(0), transformed(0),
upper_item(0)
{} {}
subs_type substype() { return IN_SUBS; } subs_type substype() { return IN_SUBS; }
@ -236,8 +237,8 @@ public:
was_null= 0; was_null= 0;
} }
trans_res select_transformer(JOIN *join); trans_res select_transformer(JOIN *join);
trans_res single_value_transformer(JOIN *join, trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
Comp_creator *func); trans_res single_value_transformer(JOIN *join, Comp_creator *func);
trans_res row_value_transformer(JOIN * join); trans_res row_value_transformer(JOIN * join);
longlong val_int(); longlong val_int();
double val_real(); double val_real();

View File

@ -115,7 +115,7 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
DBUG_RETURN(1); // out of memory DBUG_RETURN(1); // out of memory
// st_select_lex_unit::prepare correctly work for single select // st_select_lex_unit::prepare correctly work for single select
if ((res= unit->prepare(thd, derived_result, 0))) if ((res= unit->prepare(thd, derived_result, 0, org_table_list->alias)))
goto exit; goto exit;

View File

@ -436,7 +436,8 @@ public:
void exclude_tree(); void exclude_tree();
/* UNION methods */ /* UNION methods */
bool prepare(THD *thd, select_result *result, ulong additional_options); bool prepare(THD *thd, select_result *result, ulong additional_options,
const char *tmp_table_alias);
bool exec(); bool exec();
bool cleanup(); bool cleanup();
inline void unclean() { cleaned= 0; } inline void unclean() { cleaned= 0; }

View File

@ -5529,9 +5529,7 @@ new_create_field(THD *thd, char *field_name, enum_field_types type,
my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */ my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
new_field->pack_length= (interval_list->elements + 7) / 8; new_field->pack_length= get_set_pack_length(interval_list->elements);
if (new_field->pack_length > 4)
new_field->pack_length=8;
List_iterator<String> it(*interval_list); List_iterator<String> it(*interval_list);
String *tmp; String *tmp;
@ -5548,7 +5546,7 @@ new_create_field(THD *thd, char *field_name, enum_field_types type,
case FIELD_TYPE_ENUM: case FIELD_TYPE_ENUM:
{ {
// Should be safe // Should be safe
new_field->pack_length= interval_list->elements < 256 ? 1 : 2; new_field->pack_length= get_enum_pack_length(interval_list->elements);
List_iterator<String> it(*interval_list); List_iterator<String> it(*interval_list);
String *tmp; String *tmp;

View File

@ -1166,7 +1166,7 @@ static int mysql_test_select(Prepared_statement *stmt,
It is not SELECT COMMAND for sure, so setup_tables will be called as It is not SELECT COMMAND for sure, so setup_tables will be called as
usual, and we pass 0 as setup_tables_done_option usual, and we pass 0 as setup_tables_done_option
*/ */
if (unit->prepare(thd, 0, 0)) if (unit->prepare(thd, 0, 0, ""))
{ {
goto err_prep; goto err_prep;
} }
@ -1318,7 +1318,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt,
thd->used_tables= 0; // Updated by setup_fields thd->used_tables= 0; // Updated by setup_fields
// JOIN::prepare calls // JOIN::prepare calls
if (lex->unit.prepare(thd, 0, setup_tables_done_option)) if (lex->unit.prepare(thd, 0, setup_tables_done_option, ""))
{ {
res= TRUE; res= TRUE;
} }

View File

@ -7802,14 +7802,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
return create_tmp_field_from_item(thd, item, table, copy_func, modify_item, return create_tmp_field_from_item(thd, item, table, copy_func, modify_item,
convert_blob_length); convert_blob_length);
case Item::TYPE_HOLDER: case Item::TYPE_HOLDER:
{ return ((Item_type_holder *)item)->make_field_by_type(table);
Field *example= ((Item_type_holder *)item)->example();
if (example)
return create_tmp_field_from_field(thd, example, item->name, table, NULL,
convert_blob_length);
return create_tmp_field_from_item(thd, item, table, copy_func, 0,
convert_blob_length);
}
default: // Dosen't have to be stored default: // Dosen't have to be stored
return 0; return 0;
} }
@ -10584,7 +10577,19 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
/* Found key that can be used to retrieve data in sorted order */ /* Found key that can be used to retrieve data in sorted order */
if (tab->ref.key >= 0) if (tab->ref.key >= 0)
{ {
tab->ref.key= new_ref_key; /*
We'll use ref access method on key new_ref_key. In general case
the index search tuple for new_ref_key will be different (e.g.
when one of the indexes only covers prefix of the field, see
BUG#9213 in group_by.test).
So we build tab->ref from scratch here.
*/
KEYUSE *keyuse= tab->keyuse;
while (keyuse->key != new_ref_key && keyuse->table == tab->table)
keyuse++;
if (create_ref_for_key(tab->join, tab, keyuse,
tab->join->const_table_map))
DBUG_RETURN(0);
} }
else else
{ {
@ -13188,7 +13193,8 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
unit->fake_select_lex->type= "UNION RESULT"; unit->fake_select_lex->type= "UNION RESULT";
unit->fake_select_lex->options|= SELECT_DESCRIBE; unit->fake_select_lex->options|= SELECT_DESCRIBE;
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE))) if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE,
"")))
res= unit->exec(); res= unit->exec();
res|= unit->cleanup(); res|= unit->cleanup();
} }

View File

@ -30,7 +30,7 @@ bool mysql_union(THD *thd, LEX *lex, select_result *result,
DBUG_ENTER("mysql_union"); DBUG_ENTER("mysql_union");
bool res; bool res;
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
setup_tables_done_option))) setup_tables_done_option, "")))
res= unit->exec(); res= unit->exec();
if (!res && thd->cursor && thd->cursor->is_open()) if (!res && thd->cursor && thd->cursor->is_open())
{ {
@ -140,7 +140,8 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd)
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
ulong additional_options) ulong additional_options,
const char *tmp_table_alias)
{ {
SELECT_LEX *lex_select_save= thd_arg->lex->current_select; SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
SELECT_LEX *sl, *first_select; SELECT_LEX *sl, *first_select;
@ -255,7 +256,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
while ((item_tmp= it++)) while ((item_tmp= it++))
{ {
/* Error's in 'new' will be detected after loop */ /* Error's in 'new' will be detected after loop */
types.push_back(new Item_type_holder(thd_arg, item_tmp, empty_table)); types.push_back(new Item_type_holder(thd_arg, item_tmp));
} }
if (thd_arg->is_fatal_error) if (thd_arg->is_fatal_error)
@ -274,8 +275,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
Item *type, *item_tmp; Item *type, *item_tmp;
while ((type= tp++, item_tmp= it++)) while ((type= tp++, item_tmp= it++))
{ {
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp, if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
empty_table))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
} }
@ -308,7 +308,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
(first_select_in_union()->options | (first_select_in_union()->options |
thd_arg->options | thd_arg->options |
TMP_TABLE_ALL_COLUMNS), TMP_TABLE_ALL_COLUMNS),
HA_POS_ERROR, (char*) ""))) HA_POS_ERROR, (char *) tmp_table_alias)))
goto err; goto err;
table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);

View File

@ -99,10 +99,12 @@ parse_manager_arguments() {
} }
wait_for_pid () { wait_for_pid () {
for((i=0; i<35; i++)); do i=0
while test $i -lt 35 ; do
sleep 1 sleep 1
test -s $pid_file && i='' && break test -s $pid_file && i='' && break
echo $echo_n ".$echo_c" echo $echo_n ".$echo_c"
i=`expr $i + 1`
done done
if test -z "$i" ; then if test -z "$i" ; then