Merge rburnett@bk-internal.mysql.com:/home/bk/mysql-4.1

into mdk10.(none):/home/reggie/bk/mysql-4.1
This commit is contained in:
reggie@mdk10.(none) 2005-03-31 08:41:22 -06:00
commit 579124f03d
57 changed files with 2828 additions and 640 deletions

View file

@ -240,40 +240,52 @@ if (defined $opt_changelog)
# the last tagged ChangeSet (this relies heavily on our current tagging
# 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_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
{
$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);
$opt_changelog= $revision;
chomp($log_base);
}
$msg= "Adding $target_dir/ChangeLog";
$msg.= " (down to revision $opt_changelog)" if $opt_changelog ne "";
$msg= "Adding $changelogfile";
$msg.= " (down to revision $log_base)" if $log_base ne "";
&logger($msg);
$command= "bk changes -v";
$command.= " -r" if ($opt_changelog ne "" || $opt_revision);
$command.= $opt_changelog if $opt_changelog ne "";
$command.= ".." if ($opt_changelog ne "" && !$opt_revision);
# Due to a BK error, "bk changes" must be run in $REPO !
$command= "cd $REPO ; ";
$command.= "bk changes -v";
$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.= " " . $REPO . " > $target_dir/ChangeLog";
$command.= " > $changelogfile";
&logger($command);
# We cannot use run_command here because of output redirection
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)
{
@ -283,6 +295,8 @@ unless ($opt_skip_manual)
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/!");
}
&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*",
"Could not remove Makefiles in $target_dir/Docs/Images/!");

View file

@ -10,8 +10,8 @@ use Sys::Hostname;
$opt_comment=$opt_distribution=$opt_user=$opt_config_env=$opt_config_extra_env="";
$opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix="";
$opt_tmp=$opt_version_suffix="";
$opt_bundled_zlib=$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_one_error=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_archive=$opt_with_cluster=$opt_with_csv=$opt_with_example=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=$opt_readline=0;
$opt_skip_embedded_test=$opt_skip_ps_test=$opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=$opt_clearlogs=0;
$opt_bundled_zlib=$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_one_error=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_archive=$opt_with_cluster=$opt_with_csv=$opt_with_example=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=$opt_readline=$opt_with_blackhole=0;
$opt_skip_embedded_test=$opt_skip_ps_test=$opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=$opt_clearlogs=$opt_with_big_tables=0;
$global_step="";
GetOptions(
@ -58,6 +58,8 @@ GetOptions(
"user=s",
"version-suffix=s",
"with-archive",
"with-big-tables",
"with-blackhole",
"with-cluster",
"with-csv",
"with-example",
@ -274,6 +276,7 @@ if ($opt_stage <= 1)
$opt_config_options.= " --without-ndb-debug" if ($opt_with_debug && $opt_with_cluster);
$opt_config_options.= " --with-libwrap" if ($opt_libwrap);
$opt_config_options.= " --with-low-memory" if ($opt_with_low_memory);
$opt_config_options.= " --with-big-tables" if ($opt_with_big_tables);
$opt_config_options.= " --with-mysqld-ldflags=-all-static" if ($opt_static_server);
$opt_config_options.= " --with-raid" if ($opt_raid);
if ($opt_readline)
@ -287,6 +290,7 @@ if ($opt_stage <= 1)
$opt_config_options.= " --with-embedded-server" unless ($opt_without_embedded);
$opt_skip_embedded_test= 1 if ($opt_without_embedded);
$opt_config_options.= " --with-archive-storage-engine" if ($opt_with_archive);
$opt_config_options.= " --with-blackhole-storage-engine" if ($opt_with_blackhole);
$opt_config_options.= " --with-ndbcluster" if ($opt_with_cluster);
$opt_config_options.= " --with-csv-storage-engine" if ($opt_with_csv);
$opt_config_options.= " --with-example-storage-engine" if ($opt_with_example);

View file

@ -1067,6 +1067,34 @@ AC_MSG_CHECKING(for OpenSSL)
])
dnl ---------------------------------------------------------------------------
dnl Macro: MYSQL_CHECK_BIG_TABLES
dnl Sets BIG_TABLES if --with-big-tables is used
dnl ---------------------------------------------------------------------------
AC_DEFUN([MYSQL_CHECK_BIG_TABLES], [
AC_ARG_WITH([big-tables],
[
--with-big-tables Support tables with more than 4 G rows even on 32 bit platforms],
[bigtables="$withval"],
[bigtables=no])
AC_MSG_CHECKING([for big tables support])
case "$bigtables" in
yes )
AC_DEFINE([BIG_TABLES], [1], [Support big tables])
AC_MSG_RESULT([yes])
;;
* )
AC_MSG_RESULT([no])
;;
esac
])
dnl ---------------------------------------------------------------------------
dnl END OF MYSQL_CHECK_BIG_TABLES SECTION
dnl ---------------------------------------------------------------------------
AC_DEFUN([MYSQL_CHECK_MYSQLFS], [
AC_ARG_WITH([mysqlfs],
[

View file

@ -2835,6 +2835,7 @@ else
AC_MSG_RESULT(no)
fi
MYSQL_CHECK_BIG_TABLES
MYSQL_CHECK_ISAM
MYSQL_CHECK_BDB
MYSQL_CHECK_INNODB

View file

@ -138,8 +138,8 @@ int vio_close_shared_memory(Vio * vio);
#if defined(HAVE_VIO) && !defined(DONT_MAP_VIO)
#define vio_delete(vio) (vio)->viodelete(vio)
#define vio_errno(vio) (vio)->vioerrno(vio)
#define vio_read(vio, buf, size) (vio)->read(vio,buf,size)
#define vio_write(vio, buf, size) (vio)->write(vio, buf, size)
#define vio_read(vio, buf, size) ((vio)->read)(vio,buf,size)
#define vio_write(vio, buf, size) ((vio)->write)(vio, buf, size)
#define vio_blocking(vio, set_blocking_mode, old_mode)\
(vio)->vioblocking(vio, set_blocking_mode, old_mode)
#define vio_is_blocking(vio) (vio)->is_blocking(vio)

View file

@ -421,6 +421,11 @@ prepare stmt1 from ' select a, ?, b FROM t1 outer_table where
b=? and a = (select ? from t1 where b = ? ) ' ;
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
# Bug#8807
prepare stmt1 from 'select c4 FROM t9 where
c13 = (select MAX(b) from t1 where a = ?) and c22 = ? ' ;
execute stmt1 using @arg01, @arg02;
######## correlated subquery
# no parameter
prepare stmt1 from ' select a, b FROM t1 outer_table where

283
mysql-test/lib/mtr_diff.pl Normal file
View file

@ -0,0 +1,283 @@
# -*- cperl -*-
# This is a library file used by the Perl version of mysql-test-run,
# and is part of the translation of the Bourne shell script with the
# same name.
#use Data::Dumper;
use strict;
# $Data::Dumper::Indent= 1;
sub mtr_diff($$);
##############################################################################
#
# This is a simplified unified diff, with some special handling
# of unsorted result sets
#
##############################################################################
# FIXME replace die with mtr_error
#require "mtr_report.pl";
#mtr_diff("a.txt","b.txt");
sub mtr_diff ($$) {
my $file1 = shift;
my $file2 = shift;
# ----------------------------------------------------------------------
# We read in all of the files at once
# ----------------------------------------------------------------------
unless ( open(FILE1, $file1) )
{
mtr_warning("can't open \"$file1\": $!");
return;
}
unless ( open(FILE2, $file2) )
{
mtr_warning("can't open \"$file2\": $!");
return;
}
my $lines1= collect_lines(<FILE1>);
my $lines2= collect_lines(<FILE2>);
close FILE1;
close FILE2;
# print Dumper($lines1);
# print Dumper($lines2);
# ----------------------------------------------------------------------
# We compare line by line, but don't shift off elements until we know
# what to do. This way we use the "restart" method, do simple change
# and restart by entering the diff loop from the beginning again.
# ----------------------------------------------------------------------
my @context;
my @info; # Collect information, and output later
my $lno1= 1;
my $lno2= 1;
while ( @$lines1 or @$lines2 )
{
unless ( @$lines1 )
{
push(@info, map {['+',$lno1,$lno2++,$_]} @$lines2);
last;
}
unless ( @$lines2 )
{
push(@info, map {['-',$lno1++,$lno2,$_]} @$lines1);
last;
}
# ----------------------------------------------------------------------
# We know both have lines
# ----------------------------------------------------------------------
if ( $lines1->[0] eq $lines2->[0] )
{
# Simple case, first line match and all is well
push(@info, ['',$lno1++,$lno2++,$lines1->[0]]);
shift @$lines1;
shift @$lines2;
next;
}
# ----------------------------------------------------------------------
# Now, we know they differ
# ----------------------------------------------------------------------
# How far in the other one, is there a match?
my $idx2= find_next_match($lines1->[0], $lines2);
my $idx1= find_next_match($lines2->[0], $lines1);
# Here we could test "if ( !defined $idx2 or !defined $idx1 )" and
# use a more complicated diff algorithm in the case both contains
# each others lines, just dislocated. But for this application, there
# should be no need.
if ( !defined $idx2 )
{
push(@info, ['-',$lno1++,$lno2,$lines1->[0]]);
shift @$lines1;
}
else
{
push(@info, ['+',$lno1,$lno2++,$lines2->[0]]);
shift @$lines2;
}
}
# ----------------------------------------------------------------------
# Try to output nicely
# ----------------------------------------------------------------------
# print Dumper(\@info);
# We divide into "chunks" to output
# We want at least three lines of context
my @chunks;
my @chunk;
my $state= 'pre'; # 'pre', 'in' and 'post' difference
my $post_count= 0;
foreach my $info ( @info )
{
if ( $info->[0] eq '' and $state eq 'pre' )
{
# Collect no more than three lines of context before diff
push(@chunk, $info);
shift(@chunk) if @chunk > 3;
next;
}
if ( $info->[0] =~ /(\+|\-)/ and $state =~ /(pre|in)/ )
{
# Start/continue collecting diff
$state= 'in';
push(@chunk, $info);
next;
}
if ( $info->[0] eq '' and $state eq 'in' )
{
# Stop collecting diff, and collect context after diff
$state= 'post';
$post_count= 1;
push(@chunk, $info);
next;
}
if ( $info->[0] eq '' and $state eq 'post' and $post_count < 6 )
{
# We might find a new diff sequence soon, continue to collect
# non diffs but five up on 6.
$post_count++;
push(@chunk, $info);
next;
}
if ( $info->[0] eq '' and $state eq 'post' )
{
# We put an end to this, giving three non diff lines to
# the old chunk, and three to the new one.
my @left= splice(@chunk, -3, 3);
push(@chunks, [@chunk]);
$state= 'pre';
$post_count= 0;
@chunk= @left;
next;
}
if ( $info->[0] =~ /(\+|\-)/ and $state eq 'post' )
{
# We didn't split, continue collect diff
$state= 'in';
push(@chunk, $info);
next;
}
}
if ( $post_count > 3 )
{
$post_count -= 3;
splice(@chunk, -$post_count, $post_count);
}
push(@chunks, [@chunk]) if @chunk and $state ne 'pre';
foreach my $chunk ( @chunks )
{
my $from_file_start= $chunk->[0]->[1];
my $to_file_start= $chunk->[0]->[2];
my $from_file_offset= $chunk->[$#$chunk]->[1] - $from_file_start;
my $to_file_offset= $chunk->[$#$chunk]->[2] - $to_file_start;
print "\@\@ -$from_file_start,$from_file_offset ",
"+$to_file_start,$to_file_offset \@\@\n";
foreach my $info ( @$chunk )
{
if ( $info->[0] eq '' )
{
print " $info->[3]\n";
}
elsif ( $info->[0] eq '-' )
{
print "- $info->[3]\n";
}
elsif ( $info->[0] eq '+' )
{
print "+ $info->[3]\n";
}
}
}
# print Dumper(\@chunks);
}
##############################################################################
# Find if the string is found in the array, return the index if found,
# if not found, return "undef"
##############################################################################
sub find_next_match {
my $line= shift;
my $lines= shift;
for ( my $idx= 0; $idx < @$lines; $idx++ )
{
return $idx if $lines->[$idx] eq $line;
}
return undef; # No match found
}
##############################################################################
# Just read the lines, but handle "sets" of lines that are unordered
##############################################################################
sub collect_lines {
my @recordset;
my @lines;
while (@_)
{
my $line= shift @_;
chomp($line);
if ( $line =~ /^\Q%unordered%\E\t/ )
{
push(@recordset, $line);
}
elsif ( @recordset )
{
push(@lines, sort @recordset);
@recordset= (); # Clear it
}
else
{
push(@lines, $line);
}
}
if ( @recordset )
{
push(@lines, sort @recordset);
@recordset= (); # Clear it
}
return \@lines;
}
1;

View file

@ -94,6 +94,7 @@ require "lib/mtr_io.pl";
require "lib/mtr_gcov.pl";
require "lib/mtr_gprof.pl";
require "lib/mtr_report.pl";
require "lib/mtr_diff.pl";
require "lib/mtr_match.pl";
require "lib/mtr_misc.pl";
@ -1668,13 +1669,13 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--datadir=%s", $prefix,
$slave->[$idx]->{'path_myddir'});
% FIXME slave get this option twice?!
# FIXME slave get this option twice?!
mtr_add_arg($args, "%s--exit-info=256", $prefix);
mtr_add_arg($args, "%s--init-rpl-role=slave", $prefix);
mtr_add_arg($args, "%s--log-bin=%s/var/log/slave%s-bin", $prefix,
$glob_mysql_test_dir, $sidx); # FIXME use own dir for binlogs
mtr_add_arg($args, "%s--log-slave-updates", $prefix);
% FIXME option duplicated for slave
# FIXME option duplicated for slave
mtr_add_arg($args, "%s--log=%s", $prefix,
$slave->[$idx]->{'path_mylog'});
mtr_add_arg($args, "%s--master-retry-count=10", $prefix);

View file

@ -201,7 +201,6 @@ export LD_LIBRARY_PATH DYLD_LIBRARY_PATH
MASTER_RUNNING=0
MASTER1_RUNNING=0
MASTER_MYPORT=9306
MASTER_MYPORT1=9307
SLAVE_RUNNING=0
SLAVE_MYPORT=9308 # leave room for 2 masters for cluster tests
MYSQL_MANAGER_PORT=9305 # needs to be out of the way of slaves
@ -1135,6 +1134,8 @@ start_master()
id=`$EXPR $1 + 101`;
this_master_myport=`$EXPR $MASTER_MYPORT + $1`
NOT_FIRST_MASTER_EXTRA_OPTS="--skip-innodb"
eval "MASTER_MYPORT$1=$this_master_myport"
export MASTER_MYPORT$1
else
id=1;
this_master_myport=$MASTER_MYPORT
@ -1748,7 +1749,7 @@ then
$MYSQLADMIN --no-defaults --socket=$MASTER_MYSOCK1 -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
$MYSQLADMIN --no-defaults --socket=$SLAVE_MYSOCK -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
$MYSQLADMIN --no-defaults --host=$hostname --port=$MASTER_MYPORT -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
$MYSQLADMIN --no-defaults --host=$hostname --port=$MASTER_MYPORT1 -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
$MYSQLADMIN --no-defaults --host=$hostname --port=$MASTER_MYPORT+1 -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
$MYSQLADMIN --no-defaults --host=$hostname --port=$SLAVE_MYPORT -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
$MYSQLADMIN --no-defaults --host=$hostname --port=`expr $SLAVE_MYPORT + 1` -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
sleep_until_file_deleted 0 $MASTER_MYPID

View file

@ -1,6 +1,6 @@
drop table if exists t1;
SET NAMES cp1251;
create table t1 (a varchar(10) not null);
create table t1 (a varchar(10) not null) character set cp1251;
insert into t1 values ("a"),("ab"),("abc");
select * from t1;
a
@ -23,7 +23,7 @@ a
b
c
drop table t1;
create table t1 (a char(15) binary, b binary(15));
create table t1 (a char(15) binary, b binary(15)) character set cp1251;
insert into t1 values ('aaa','bbb'),('AAA','BBB');
select upper(a),upper(b) from t1;
upper(a) upper(b)

View file

@ -747,7 +747,7 @@ insert into t1 values (now());
create table t2 select f2 from (select max(now()) f2 from t1) a;
show columns from t2;
Field Type Null Key Default Extra
f2 datetime 0000-00-00 00:00:00
f2 datetime YES NULL
drop table t2;
create table t2 select f2 from (select now() f2 from t1) a;
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
10
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
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
def test t1 t1 id id 1 3 1 Y 32768 0 63
def id id 1 4 1 Y 32768 0 63
id
1
2
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

@ -768,6 +768,10 @@ prepare stmt1 from ' select a, ?, b FROM t1 outer_table where
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
a ? b
2 1 two
prepare stmt1 from 'select c4 FROM t9 where
c13 = (select MAX(b) from t1 where a = ?) and c22 = ? ' ;
execute stmt1 using @arg01, @arg02;
c4
prepare stmt1 from ' select a, b FROM t1 outer_table where
a = (select a from t1 where b = outer_table.b ) order by a ';
execute stmt1 ;

View file

@ -768,6 +768,10 @@ prepare stmt1 from ' select a, ?, b FROM t1 outer_table where
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
a ? b
2 1 two
prepare stmt1 from 'select c4 FROM t9 where
c13 = (select MAX(b) from t1 where a = ?) and c22 = ? ' ;
execute stmt1 using @arg01, @arg02;
c4
prepare stmt1 from ' select a, b FROM t1 outer_table where
a = (select a from t1 where b = outer_table.b ) order by a ';
execute stmt1 ;

View file

@ -769,6 +769,10 @@ prepare stmt1 from ' select a, ?, b FROM t1 outer_table where
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
a ? b
2 1 two
prepare stmt1 from 'select c4 FROM t9 where
c13 = (select MAX(b) from t1 where a = ?) and c22 = ? ' ;
execute stmt1 using @arg01, @arg02;
c4
prepare stmt1 from ' select a, b FROM t1 outer_table where
a = (select a from t1 where b = outer_table.b ) order by a ';
execute stmt1 ;

View file

@ -811,6 +811,10 @@ prepare stmt1 from ' select a, ?, b FROM t1 outer_table where
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
a ? b
2 1 two
prepare stmt1 from 'select c4 FROM t9 where
c13 = (select MAX(b) from t1 where a = ?) and c22 = ? ' ;
execute stmt1 using @arg01, @arg02;
c4
prepare stmt1 from ' select a, b FROM t1 outer_table where
a = (select a from t1 where b = outer_table.b ) order by a ';
execute stmt1 ;
@ -3821,6 +3825,10 @@ prepare stmt1 from ' select a, ?, b FROM t1 outer_table where
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
a ? b
2 1 two
prepare stmt1 from 'select c4 FROM t9 where
c13 = (select MAX(b) from t1 where a = ?) and c22 = ? ' ;
execute stmt1 using @arg01, @arg02;
c4
prepare stmt1 from ' select a, b FROM t1 outer_table where
a = (select a from t1 where b = outer_table.b ) order by a ';
execute stmt1 ;

View file

@ -768,6 +768,10 @@ prepare stmt1 from ' select a, ?, b FROM t1 outer_table where
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
a ? b
2 1 two
prepare stmt1 from 'select c4 FROM t9 where
c13 = (select MAX(b) from t1 where a = ?) and c22 = ? ' ;
execute stmt1 using @arg01, @arg02;
c4
prepare stmt1 from ' select a, b FROM t1 outer_table where
a = (select a from t1 where b = outer_table.b ) order by a ';
execute stmt1 ;

View file

@ -48,7 +48,7 @@ test_sequence
------ simple select tests ------
prepare stmt1 from ' select * from t9 order by c1 ' ;
execute stmt1;
Catalog Database Table Table_alias Column Column_alias Name 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 t9 t9 c1 c1 1 4 1 N 49155 0 63
def test t9 t9 c2 c2 2 6 1 Y 32768 0 63
def test t9 t9 c3 c3 9 9 1 Y 32768 0 63
@ -768,6 +768,10 @@ prepare stmt1 from ' select a, ?, b FROM t1 outer_table where
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
a ? b
2 1 two
prepare stmt1 from 'select c4 FROM t9 where
c13 = (select MAX(b) from t1 where a = ?) and c22 = ? ' ;
execute stmt1 using @arg01, @arg02;
c4
prepare stmt1 from ' select a, b FROM t1 outer_table where
a = (select a from t1 where b = outer_table.b ) order by a ';
execute stmt1 ;
@ -1144,7 +1148,7 @@ test_sequence
------ explain select tests ------
prepare stmt1 from ' explain select * from t9 ' ;
execute stmt1;
Catalog Database Table Table_alias Column Column_alias Name 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 id 8 3 1 N 32929 0 63
def select_type 253 19 6 N 1 31 8
def table 253 64 2 N 1 31 8
@ -1783,7 +1787,7 @@ t5 CREATE TABLE `t5` (
`param15` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Name 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 t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
def test t5 t5 const02 const02 5 3 3 N 32769 1 63
@ -1895,7 +1899,7 @@ from t9 where c1= 1 ;
@arg01:= c1 @arg02:= c2 @arg03:= c3 @arg04:= c4 @arg05:= c5 @arg06:= c6 @arg07:= c7 @arg08:= c8 @arg09:= c9 @arg10:= c10 @arg11:= c11 @arg12:= c12 @arg13:= c13 @arg14:= c14 @arg15:= c15 @arg16:= c16 @arg17:= c17 @arg18:= c18 @arg19:= c19 @arg20:= c20 @arg21:= c21 @arg22:= c22 @arg23:= c23 @arg24:= c24 @arg25:= c25 @arg26:= c26 @arg27:= c27 @arg28:= c28 @arg29:= c29 @arg30:= c30 @arg31:= c31 @arg32:= c32
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
execute full_info ;
Catalog Database Table Table_alias Column Column_alias Name 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 @arg01 254 20 1 Y 128 31 63
def @arg02 254 20 1 Y 128 31 63
def @arg03 254 20 1 Y 128 31 63
@ -1942,7 +1946,7 @@ from t9 where c1= 0 ;
@arg01:= c1 @arg02:= c2 @arg03:= c3 @arg04:= c4 @arg05:= c5 @arg06:= c6 @arg07:= c7 @arg08:= c8 @arg09:= c9 @arg10:= c10 @arg11:= c11 @arg12:= c12 @arg13:= c13 @arg14:= c14 @arg15:= c15 @arg16:= c16 @arg17:= c17 @arg18:= c18 @arg19:= c19 @arg20:= c20 @arg21:= c21 @arg22:= c22 @arg23:= c23 @arg24:= c24 @arg25:= c25 @arg26:= c26 @arg27:= c27 @arg28:= c28 @arg29:= c29 @arg30:= c30 @arg31:= c31 @arg32:= c32
0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
execute full_info ;
Catalog Database Table Table_alias Column Column_alias Name 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 @arg01 254 20 1 Y 128 31 63
def @arg02 254 20 0 Y 128 31 63
def @arg03 254 20 0 Y 128 31 63
@ -1992,7 +1996,7 @@ execute stmt1 using @my_key ;
@arg01:= c1 @arg02:= c2 @arg03:= c3 @arg04:= c4 @arg05:= c5 @arg06:= c6 @arg07:= c7 @arg08:= c8 @arg09:= c9 @arg10:= c10 @arg11:= c11 @arg12:= c12 @arg13:= c13 @arg14:= c14 @arg15:= c15 @arg16:= c16 @arg17:= c17 @arg18:= c18 @arg19:= c19 @arg20:= c20 @arg21:= c21 @arg22:= c22 @arg23:= c23 @arg24:= c24 @arg25:= c25 @arg26:= c26 @arg27:= c27 @arg28:= c28 @arg29:= c29 @arg30:= c30 @arg31:= c31 @arg32:= c32
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
execute full_info ;
Catalog Database Table Table_alias Column Column_alias Name 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 @arg01 254 20 1 Y 128 31 63
def @arg02 254 20 1 Y 128 31 63
def @arg03 254 20 1 Y 128 31 63
@ -2032,7 +2036,7 @@ execute stmt1 using @my_key ;
@arg01:= c1 @arg02:= c2 @arg03:= c3 @arg04:= c4 @arg05:= c5 @arg06:= c6 @arg07:= c7 @arg08:= c8 @arg09:= c9 @arg10:= c10 @arg11:= c11 @arg12:= c12 @arg13:= c13 @arg14:= c14 @arg15:= c15 @arg16:= c16 @arg17:= c17 @arg18:= c18 @arg19:= c19 @arg20:= c20 @arg21:= c21 @arg22:= c22 @arg23:= c23 @arg24:= c24 @arg25:= c25 @arg26:= c26 @arg27:= c27 @arg28:= c28 @arg29:= c29 @arg30:= c30 @arg31:= c31 @arg32:= c32
0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
execute full_info ;
Catalog Database Table Table_alias Column Column_alias Name 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 @arg01 254 20 1 Y 128 31 63
def @arg02 254 20 0 Y 128 31 63
def @arg03 254 20 0 Y 128 31 63
@ -2080,7 +2084,7 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08,
@arg25, @arg26, @arg27, @arg28, @arg29, @arg30, @arg31, @arg32
from t9 where c1= 1 ;
execute full_info ;
Catalog Database Table Table_alias Column Column_alias Name 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 @arg01 254 20 1 Y 128 31 63
def @arg02 254 20 1 Y 128 31 63
def @arg03 254 20 1 Y 128 31 63
@ -2124,7 +2128,7 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08,
@arg25, @arg26, @arg27, @arg28, @arg29, @arg30, @arg31, @arg32
from t9 where c1= 0 ;
execute full_info ;
Catalog Database Table Table_alias Column Column_alias Name 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 @arg01 254 20 1 Y 128 31 63
def @arg02 254 20 0 Y 128 31 63
def @arg03 254 20 0 Y 128 31 63
@ -2170,7 +2174,7 @@ from t9 where c1= ?" ;
set @my_key= 1 ;
execute stmt1 using @my_key ;
execute full_info ;
Catalog Database Table Table_alias Column Column_alias Name 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 @arg01 254 20 1 Y 128 31 63
def @arg02 254 20 1 Y 128 31 63
def @arg03 254 20 1 Y 128 31 63
@ -2208,7 +2212,7 @@ def @arg32 254 8192 6 Y 0 31 8
set @my_key= 0 ;
execute stmt1 using @my_key ;
execute full_info ;
Catalog Database Table Table_alias Column Column_alias Name 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 @arg01 254 20 1 Y 128 31 63
def @arg02 254 20 0 Y 128 31 63
def @arg03 254 20 0 Y 128 31 63

View file

@ -1873,6 +1873,380 @@ SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
a
1
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;
create table t1 (a int, b int);
insert into t1 values (1,2),(3,4);
@ -2128,7 +2502,7 @@ drop table t1;
create table t1 (a1 int);
create table t2 (b1 int);
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);
a1
drop table t1,t2;
@ -2267,4 +2641,59 @@ 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 2 88 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)

View file

@ -27,7 +27,7 @@ t3 CREATE TABLE `t3` (
drop table t1,t2,t3
#;
CREATE TABLE t1 (a char(257) default "hello");
ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB instead
ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
CREATE TABLE t2 (a blob default "hello");
ERROR 42000: BLOB/TEXT column 'a' can't have a default value
drop table if exists t1,t2;

View file

@ -655,7 +655,7 @@ f
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f` binary(24) default NULL
`f` varbinary(24) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT y from t2 UNION select da from t2;
@ -666,7 +666,7 @@ y
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`y` binary(10) default NULL
`y` varbinary(10) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT y from t2 UNION select dt from t2;
@ -677,7 +677,7 @@ y
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`y` binary(19) default NULL
`y` varbinary(19) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT da from t2 UNION select dt from t2;
@ -699,7 +699,7 @@ testc
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`dt` binary(19) default NULL
`dt` varbinary(19) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT dt from t2 UNION select sv from t2;
@ -710,7 +710,7 @@ testv
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`dt` binary(19) default NULL
`dt` varbinary(19) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT sc from t2 UNION select sv from t2;
@ -732,7 +732,7 @@ tetetetetest
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`dt` blob
`dt` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT sv from t2 UNION select b from t2;
@ -755,7 +755,7 @@ tetetetetest
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`i` blob
`i` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT sv from t2 UNION select tx from t2;
@ -766,7 +766,7 @@ teeeeeeeeeeeest
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`sv` text
`sv` longtext
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT b from t2 UNION select tx from t2;
@ -1069,7 +1069,7 @@ create table t1 as
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_latin1'test' collate latin1_bin` char(4) character set latin1 collate latin1_bin NOT NULL default ''
`_latin1'test' collate latin1_bin` varchar(4) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select count(*) from t1;
count(*)
@ -1082,7 +1082,7 @@ create table t1 as
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`test` char(4) character set latin1 collate latin1_bin NOT NULL default ''
`test` varchar(4) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select count(*) from t1;
count(*)
@ -1095,7 +1095,7 @@ create table t1 as
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`test` char(4) character set latin1 collate latin1_bin NOT NULL default ''
`test` varchar(4) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select count(*) from t1;
count(*)
@ -1200,3 +1200,38 @@ select concat('value is: ', @val) union select 'some text';
concat('value is: ', @val)
value is: 6
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

@ -1,2 +0,0 @@
--default-character-set=cp1251 --new

View file

@ -10,7 +10,7 @@ SET NAMES cp1251;
# Test problem with LEFT() (Bug #514)
#
create table t1 (a varchar(10) not null);
create table t1 (a varchar(10) not null) character set cp1251;
insert into t1 values ("a"),("ab"),("abc");
select * from t1;
select a, left(a,1) as b from t1;
@ -21,7 +21,7 @@ drop table t1;
#
# Test of binary and upper/lower
#
create table t1 (a char(15) binary, b binary(15));
create table t1 (a char(15) binary, b binary(15)) character set cp1251;
insert into t1 values ('aaa','bbb'),('AAA','BBB');
select upper(a),upper(b) from t1;
select lower(a),lower(b) from 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 sum(a)*sum(b) as d from t1 where a=1 group by c having d > 0;
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;
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

View file

@ -1148,6 +1148,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 );
# with index
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 );
@ -1161,7 +1162,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 );
# 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;
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
@ -1438,8 +1576,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;
drop table t1;
#
# Test for BUG#8218
#
CREATE TABLE t1 (
categoryId int(11) NOT NULL,
courseId int(11) NOT NULL,
@ -1536,5 +1675,50 @@ join
group by
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

View file

@ -717,3 +717,28 @@ drop table t1;
#
set @val:=6;
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;

View file

@ -62,6 +62,9 @@ extern CHARSET_INFO my_charset_utf8_slovak_uca_ci;
extern CHARSET_INFO my_charset_utf8_spanish2_uca_ci;
extern CHARSET_INFO my_charset_utf8_roman_uca_ci;
extern CHARSET_INFO my_charset_utf8_persian_uca_ci;
#ifdef HAVE_CYBOZU_COLLATION
extern CHARSET_INFO my_charset_utf8_general_cs;
#endif
#endif
#endif /* HAVE_UCA_COLLATIONS */
@ -146,6 +149,9 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
#ifdef HAVE_CHARSET_utf8
add_compiled_collation(&my_charset_utf8_general_ci);
add_compiled_collation(&my_charset_utf8_bin);
#ifdef HAVE_CYBOZU_COLLATION
add_compiled_collation(&my_charset_utf8_general_cs);
#endif
#ifdef HAVE_UCA_COLLATIONS
add_compiled_collation(&my_charset_utf8_general_uca_ci);
add_compiled_collation(&my_charset_utf8_icelandic_uca_ci);

View file

@ -73,7 +73,7 @@ static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc,
static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
const char *dir, const char *ext,
const char *config_file,
TYPELIB *group);
TYPELIB *group, int recursion_level);
static char *remove_end_comment(char *ptr);
@ -193,8 +193,8 @@ int load_defaults(const char *conf_file, const char **groups,
if (forced_default_file)
{
if ((error= search_default_file_with_ext(&args, &alloc, "", "",
forced_default_file,
&group)) < 0)
forced_default_file,
&group, 0)) < 0)
goto err;
if (error > 0)
{
@ -311,7 +311,7 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
{
int error;
if ((error= search_default_file_with_ext(args, alloc, dir, *ext,
config_file, group)) < 0)
config_file, group, 0)) < 0)
return error;
}
return 0;
@ -320,15 +320,17 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
/*
Open a configuration file (if exists) and read given options from it
SYNOPSIS
search_default_file_with_ext()
args Store pointer to found options here
alloc Allocate strings in this object
dir directory to read
config_file Name of configuration file
ext Extension for configuration file
config_file Name of configuration file
group groups to read
recursion_level the level of recursion, got while processing
"!include" or "!includedir"
RETURN
0 Success
@ -340,12 +342,18 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
const char *dir, const char *ext,
const char *config_file,
TYPELIB *group)
TYPELIB *group, int recursion_level)
{
char name[FN_REFLEN+10],buff[4096],*ptr,*end,*value,*tmp;
char name[FN_REFLEN + 10], buff[4096], *ptr, *end, *value, *tmp, **tmp_ext;
static const char includedir_keyword[]= "includedir";
static const char include_keyword[]= "include";
const int max_recursion_level= 10;
FILE *fp;
uint line=0;
my_bool read_values=0,found_group=0;
uint line= 0;
my_bool read_values= 0, found_group= 0;
uint i;
MY_DIR *search_dir;
FILEINFO *search_file;
if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
return 0; /* Ignore wrong paths */
@ -374,22 +382,121 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
if ((stat_info.st_mode & S_IWOTH) &&
(stat_info.st_mode & S_IFMT) == S_IFREG)
{
fprintf(stderr, "warning: World-writeable config file %s is ignored\n",
fprintf(stderr, "warning: World-writable config file %s is ignored\n",
name);
return 0;
}
}
#endif
if (!(fp = my_fopen(fn_format(name,name,"","",4),O_RDONLY,MYF(0))))
if (!(fp= my_fopen(fn_format(name, name, "", "", 4), O_RDONLY, MYF(0))))
return 0; /* Ignore wrong files */
while (fgets(buff,sizeof(buff)-1,fp))
while (fgets(buff, sizeof(buff) - 1, fp))
{
line++;
/* Ignore comment and empty lines */
for (ptr=buff ; my_isspace(&my_charset_latin1,*ptr) ; ptr++ ) ;
for (ptr= buff; my_isspace(&my_charset_latin1, *ptr); ptr++)
{}
if (*ptr == '#' || *ptr == ';' || !*ptr)
continue;
/* Configuration File Directives */
if ((*ptr == '!') && (recursion_level < max_recursion_level))
{
/* skip over `!' and following whitespace */
for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
if ((!strncmp(ptr, includedir_keyword, sizeof(includedir_keyword) - 1))
&& my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
{
/* skip over "includedir" and following whitespace */
for (ptr+= sizeof(includedir_keyword) - 1;
my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
/* trim trailing whitespace from directory name */
end= ptr + strlen(ptr) - 1;
/*
This would work fine even if no whitespaces are met
since fgets() stores the newline character in the buffer
*/
for (; my_isspace(&my_charset_latin1, *(end - 1)); end--)
{}
end[0]= 0;
/* print error msg if there is nothing after !inludedir directive */
if (end == ptr)
{
fprintf(stderr,
"error: Wrong !includedir directive in config "
"file: %s at line %d\n",
name,line);
goto err;
}
if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
goto err;
for (i= 0; i < (uint) search_dir->number_off_files; i++)
{
search_file= search_dir->dir_entry + i;
ext= fn_ext(search_file->name);
/* check extenstion */
for (tmp_ext= (char**) f_extensions; *tmp_ext; *tmp_ext++)
{
if (!strcmp(ext, *tmp_ext))
break;
}
if (*tmp_ext)
{
if (!(tmp= alloc_root(alloc, 2 + strlen(search_file->name)
+ strlen(ptr))))
goto err;
fn_format(tmp, search_file->name, ptr, "",
MY_UNPACK_FILENAME | MY_SAFE_PATH);
search_default_file_with_ext(args, alloc, "", "", tmp, group,
recursion_level + 1);
}
}
my_dirend(search_dir);
}
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1))
&& my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword) - 1]))
{
/* skip over `include' and following whitespace */
for (ptr+= sizeof(include_keyword) - 1;
my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
/* trim trailing whitespace from filename */
end= ptr + strlen(ptr) - 1;
for (; my_isspace(&my_charset_latin1, *(end - 1)) ; end--)
{}
end[0]= 0;
if (end == ptr)
{
fprintf(stderr,
"error: Wrong !include directive in config "
"file: %s at line %d\n",
name,line);
goto err;
}
search_default_file_with_ext(args, alloc, "", "", ptr, group,
recursion_level + 1);
}
continue;
}
if (*ptr == '[') /* Group name */
{
found_group=1;

View file

@ -1076,7 +1076,7 @@ private:
void storeLongKeysAtPos(Signal* signal);
void reorgLongPage(Signal* signal);
void getElement(Signal* signal);
void searchLongKey(Signal* signal);
void searchLongKey(Signal* signal, bool verify);
void getdirindex(Signal* signal);
void commitdelete(Signal* signal, bool systemRestart);
void deleteElement(Signal* signal);

View file

@ -2522,6 +2522,26 @@ void Dbacc::execACC_LOCKREQ(Signal* signal)
*sig = *req;
return;
}
operationRecPtr.i = req->accOpPtr;
ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
fragrecptr.i = operationRecPtr.p->fragptr;
ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
if (fragrecptr.p->keyLength == 0 &&
// should test some state variable
operationRecPtr.p->elementPage != RNIL) {
jam();
// re-compute long key vars
Page8Ptr tPageptr;
tPageptr.i = operationRecPtr.p->elementPage;
ptrCheckGuard(tPageptr, cpagesize, page8);
Uint32 tKeyptr =
operationRecPtr.p->elementPointer +
operationRecPtr.p->elementIsforward *
(ZELEM_HEAD_SIZE + fragrecptr.p->localkeylen);
tslcPageIndex = tPageptr.p->word32[tKeyptr] & 0x3ff;
tslcPagedir = tPageptr.p->word32[tKeyptr] >> 10;
searchLongKey(signal, false);
}
if (lockOp == AccLockReq::Unlock) {
jam();
// do unlock via ACC_COMMITREQ (immediate)
@ -4685,7 +4705,7 @@ void Dbacc::getElement(Signal* signal)
/* --------------------------------------------------------------------------------- */
tslcPageIndex = gePageptr.p->word32[tgeKeyptr] & 0x3ff;
tslcPagedir = gePageptr.p->word32[tgeKeyptr] >> 10;
searchLongKey(signal);
searchLongKey(signal, true);
if (tslcResult == ZTRUE) {
register Uint32 TlocData1, TlocData2;
jam();
@ -4728,6 +4748,14 @@ void Dbacc::getElement(Signal* signal)
Uint32 TgeIndex = TdataIndex + tgeForward;
operationRecPtr.p->localdata[0] = gePageptr.p->word32[TdataIndex];
operationRecPtr.p->localdata[1] = gePageptr.p->word32[TgeIndex];
if (fragrecptr.p->keyLength == 0) {
// set up long key variables in operation record
tslcPageIndex = gePageptr.p->word32[tgeKeyptr] & 0x3ff;
tslcPagedir = gePageptr.p->word32[tgeKeyptr] >> 10;
// no verification since we have no key data
searchLongKey(signal, false);
}
return;
}//if
if (tgeRemLen <= ZCON_HEAD_SIZE) {
@ -4775,7 +4803,7 @@ void Dbacc::getElement(Signal* signal)
/* TSLC_RESULT */
/* DESCRIPTION: SEARCH FOR AN ELEMENT IN A LONG_KEY_PAGE. */
/* --------------------------------------------------------------------------------- */
void Dbacc::searchLongKey(Signal* signal)
void Dbacc::searchLongKey(Signal* signal, bool verify)
{
DirRangePtr slcOverflowrangeptr;
DirectoryarrayPtr slcOverflowDirptr;
@ -4801,23 +4829,27 @@ void Dbacc::searchLongKey(Signal* signal)
dbgWord32(slcPageptr, ZWORDS_IN_PAGE - tslcPageIndex, (int)slcPageptr.p->word32[ZWORDS_IN_PAGE - tslcPageIndex] & 0xffff);
dbgWord32(slcPageptr, ZWORDS_IN_PAGE - tslcPageIndex, slcPageptr.p->word32[ZWORDS_IN_PAGE - tslcPageIndex] >> 16);
tslcIndexValue = slcPageptr.p->word32[ZWORDS_IN_PAGE - tslcPageIndex];
if ((tslcIndexValue >> 16) != operationRecPtr.p->tupkeylen) {
jam();
tslcResult = ZFALSE;
return;
}//if
tslcStartIndex = tslcIndexValue & 0xffff;
guard30 = operationRecPtr.p->tupkeylen - 1;
arrGuard(guard30, 2048);
arrGuard(guard30 + tslcStartIndex, 2048);
for (tslcIndex = 0; tslcIndex <= guard30; tslcIndex++) {
dbgWord32(slcPageptr, tslcIndex + tslcStartIndex, slcPageptr.p->word32[tslcIndex + tslcStartIndex]);
if (slcPageptr.p->word32[tslcIndex + tslcStartIndex] != Tkeydata[tslcIndex]) {
if (verify) {
if ((tslcIndexValue >> 16) != operationRecPtr.p->tupkeylen) {
jam();
tslcResult = ZFALSE;
return;
}//if
}//for
}
tslcStartIndex = tslcIndexValue & 0xffff;
guard30 = operationRecPtr.p->tupkeylen - 1;
arrGuard(guard30, 2048);
arrGuard(guard30 + tslcStartIndex, 2048);
if (verify) {
for (tslcIndex = 0; tslcIndex <= guard30; tslcIndex++) {
dbgWord32(slcPageptr, tslcIndex + tslcStartIndex, slcPageptr.p->word32[tslcIndex + tslcStartIndex]);
if (slcPageptr.p->word32[tslcIndex + tslcStartIndex] != Tkeydata[tslcIndex]) {
jam();
tslcResult = ZFALSE;
return;
}//if
}//for
}
jam();
tslcResult = ZTRUE;
operationRecPtr.p->longPagePtr = slcPageptr.i;

View file

@ -2227,7 +2227,6 @@ void Dbdict::checkSchemaStatus(Signal* signal)
restartCreateTab(signal, tableId, oldEntry, false);
return;
}//if
ndbrequire(ok);
break;
}
}
@ -2452,7 +2451,9 @@ Dbdict::restartCreateTab_writeTableConf(Signal* signal,
callback.m_callbackFunction =
safe_cast(&Dbdict::restartCreateTab_dihComplete);
SegmentedSectionPtr fragDataPtr; fragDataPtr.setNull();
SegmentedSectionPtr fragDataPtr;
fragDataPtr.sz = 0;
fragDataPtr.setNull();
createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
}

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,17 @@ class Protocol;
struct st_cache_field;
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
{
Field(const Item &); /* Prevent use of these */
@ -75,17 +86,6 @@ public:
GEOM_GEOMETRYCOLLECTION = 7
};
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
};
utype unireg_check;
uint32 field_length; // Length of field
@ -119,6 +119,8 @@ public:
virtual String *val_str(String*,String *)=0;
virtual Item_result result_type () const=0;
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) { return ptr == field->ptr && null_ptr == field->null_ptr; }
virtual bool eq_def(Field *field);
virtual uint32 pack_length() const { return (uint32) field_length; }
@ -290,8 +292,6 @@ public:
int cuted_increment);
void set_datetime_warning(const uint level, const uint code,
double nr, timestamp_type ts_type);
virtual field_cast_enum field_cast_type()= 0;
bool field_cast_compatible(field_cast_enum type);
/* maximum possible display length */
virtual uint32 max_length()= 0;
friend bool reopen_table(THD *,struct st_table *,bool);
@ -398,7 +398,6 @@ public:
bool zero_pack() const { return 0; }
void sql_type(String &str) const;
uint32 max_length() { return field_length; }
field_cast_enum field_cast_type() { return FIELD_CAST_DECIMAL; }
};
@ -430,7 +429,6 @@ public:
uint32 pack_length() const { return 1; }
void sql_type(String &str) const;
uint32 max_length() { return 4; }
field_cast_enum field_cast_type() { return FIELD_CAST_TINY; }
};
@ -467,7 +465,6 @@ public:
uint32 pack_length() const { return 2; }
void sql_type(String &str) const;
uint32 max_length() { return 6; }
field_cast_enum field_cast_type() { return FIELD_CAST_SHORT; }
};
@ -499,7 +496,6 @@ public:
uint32 pack_length() const { return 3; }
void sql_type(String &str) const;
uint32 max_length() { return 8; }
field_cast_enum field_cast_type() { return FIELD_CAST_MEDIUM; }
};
@ -536,7 +532,6 @@ public:
uint32 pack_length() const { return 4; }
void sql_type(String &str) const;
uint32 max_length() { return 11; }
field_cast_enum field_cast_type() { return FIELD_CAST_LONG; }
};
@ -576,7 +571,6 @@ public:
void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; }
uint32 max_length() { return 20; }
field_cast_enum field_cast_type() { return FIELD_CAST_LONGLONG; }
};
#endif
@ -611,7 +605,6 @@ public:
uint32 pack_length() const { return sizeof(float); }
void sql_type(String &str) const;
uint32 max_length() { return 24; }
field_cast_enum field_cast_type() { return FIELD_CAST_FLOAT; }
};
@ -646,7 +639,6 @@ public:
uint32 pack_length() const { return sizeof(double); }
void sql_type(String &str) const;
uint32 max_length() { return 53; }
field_cast_enum field_cast_type() { return FIELD_CAST_DOUBLE; }
};
@ -677,7 +669,6 @@ public:
void sql_type(String &str) const;
uint size_of() const { return sizeof(*this); }
uint32 max_length() { return 4; }
field_cast_enum field_cast_type() { return FIELD_CAST_NULL; }
};
@ -729,7 +720,6 @@ public:
}
bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime);
field_cast_enum field_cast_type() { return FIELD_CAST_TIMESTAMP; }
timestamp_auto_set_type get_auto_set_type() const;
};
@ -753,7 +743,6 @@ public:
bool send_binary(Protocol *protocol);
void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_YEAR; }
};
@ -786,7 +775,6 @@ public:
void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; }
field_cast_enum field_cast_type() { return FIELD_CAST_DATE; }
};
class Field_newdate :public Field_str {
@ -818,7 +806,6 @@ public:
bool zero_pack() const { return 1; }
bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime);
field_cast_enum field_cast_type() { return FIELD_CAST_NEWDATE; }
};
@ -853,7 +840,6 @@ public:
void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; }
field_cast_enum field_cast_type() { return FIELD_CAST_TIME; }
};
@ -891,7 +877,6 @@ public:
bool zero_pack() const { return 1; }
bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime);
field_cast_enum field_cast_type() { return FIELD_CAST_DATETIME; }
};
@ -937,7 +922,6 @@ public:
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_STRING; }
};
@ -986,7 +970,6 @@ public:
enum_field_types real_type() const { return FIELD_TYPE_VAR_STRING; }
bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; }
};
@ -1081,7 +1064,6 @@ public:
uint size_of() const { return sizeof(*this); }
bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_BLOB; }
uint32 max_length();
};
@ -1111,7 +1093,6 @@ public:
void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
field_cast_enum field_cast_type() { return FIELD_CAST_GEOM; }
};
#endif /*HAVE_SPATIAL*/
@ -1155,7 +1136,6 @@ public:
bool has_charset(void) const { return TRUE; }
/* enum and set are sorted as integers */
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
field_cast_enum field_cast_type() { return FIELD_CAST_ENUM; }
};
@ -1181,7 +1161,6 @@ public:
void sql_type(String &str) const;
enum_field_types real_type() const { return FIELD_TYPE_SET; }
bool has_charset(void) const { return TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_SET; }
};
@ -1268,7 +1247,6 @@ int set_field_to_null(Field *field);
int set_field_to_null_with_conversions(Field *field, bool no_conversions);
bool test_if_int(const char *str, int length, const char *int_end,
CHARSET_INFO *cs);
bool field_types_to_be_kept(enum_field_types field_type);
/*
The following are for the interface with the .frm file

View file

@ -1319,6 +1319,34 @@ bool Item_param::convert_str_value(THD *thd)
return rc;
}
bool Item_param::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
DBUG_ASSERT(fixed == 0);
SELECT_LEX *cursel= (SELECT_LEX *) thd->lex->current_select;
/*
Parameters in a subselect should mark the subselect as not constant
during prepare
*/
if (state == NO_VALUE)
{
/*
SELECT_LEX_UNIT::item set only for subqueries, so test of it presence
can be barrier to stop before derived table SELECT or very outer SELECT
*/
for(;
cursel->master_unit()->item;
cursel= cursel->outer_select())
{
Item_subselect *subselect_item= cursel->master_unit()->item;
subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
subselect_item->const_item_cache= 0;
}
}
fixed= 1;
return 0;
}
/* End of Item_param related */
@ -1700,10 +1728,10 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
case MYSQL_TYPE_NULL:
return new Field_null((char*) 0, max_length, Field::NONE,
name, table, &my_charset_bin);
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_INT24:
return new Field_medium((char*) 0, max_length, null_ptr, 0, Field::NONE,
name, table, 0, unsigned_flag);
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE:
return new Field_date(maybe_null, name, table, &my_charset_bin);
case MYSQL_TYPE_TIME:
@ -2701,204 +2729,274 @@ void Item_cache_row::bring_value()
}
/*
Returns field for temporary table dependind on item type
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);
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)
Item_type_holder::Item_type_holder(THD *thd, Item *item)
:Item(thd, item), enum_set_typelib(0), fld_type(get_real_type(item))
{
DBUG_ASSERT(item->fixed);
/*
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);
max_length= display_length(item);
maybe_null= item->maybe_null;
collation.set(item->collation);
get_full_info(item);
}
/*
STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT
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[4][4]=
{{STRING_RESULT, STRING_RESULT, STRING_RESULT, ROW_RESULT},
{STRING_RESULT, REAL_RESULT, REAL_RESULT, ROW_RESULT},
{STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT},
{ROW_RESULT, ROW_RESULT, ROW_RESULT, ROW_RESULT}};
/*
Values of 'from' field can be stored in 'to' field.
Return expression type of Item_type_holder
SYNOPSIS
is_attr_compatible()
from Item which values should be saved
to Item where values should be saved
Item_type_holder::result_type()
RETURN
1 can be saved
0 can not be saved
Item_result (type of internal MySQL expression result)
*/
inline bool is_attr_compatible(Item *from, Item *to)
Item_result Item_type_holder::result_type() const
{
return ((to->max_length >= from->max_length) &&
(to->maybe_null || !from->maybe_null) &&
(to->result_type() != STRING_RESULT ||
from->result_type() != STRING_RESULT ||
(from->collation.collation == to->collation.collation)));
return Field::result_merge_type(fld_type);
}
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);
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)
switch(item->type())
{
/* Can 'field_example' field store data of the column? */
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)
case FIELD_ITEM:
{
/*
Expression types can't be mixed with field types, we have to use
expression types.
Item_fields::field_type ask Field_type() but sometimes field return
a different type, like for enum/set, so we need to ask real type.
*/
use_new_field= 1; // make next if test easier
use_expression_type= 1;
Field *field= ((Item_field *) item)->field;
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;
}
/* 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) ||
(item_type == STRING_RESULT &&
collation.collation != item->collation.collation))
case SUM_FUNC_ITEM:
{
const char *old_cs,*old_derivation;
if (use_expression_type || !item_is_a_field)
field_example= 0;
else
/*
Argument of aggregate function sometimes should be asked about field
type
*/
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
before any table is closed.
There are work around of problem with changing variable type on the
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;
default:
break;
}
return item->field_type();
}
/*
Find field type which can carry current Item_type_holder type and
type of given 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 (item_type == STRING_RESULT && collation.aggregate(item->collation))
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 1;
return TRUE;
}
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 0;
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
uint32 Item_type_holder::real_length(Item *item)
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)
return ((Item_field *)item)->max_disp_length();
switch (item->result_type())
switch (item->field_type())
{
case STRING_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;
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;
case INT_RESULT:
case MYSQL_TYPE_NULL:
return 4;
case MYSQL_TYPE_LONGLONG:
return 20;
case ROW_RESULT:
case MYSQL_TYPE_INT24:
return 8;
default:
DBUG_ASSERT(0); // we should never go there
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()
{
DBUG_ASSERT(0); // should never be called

View file

@ -559,6 +559,7 @@ public:
bool get_time(TIME *tm);
bool get_date(TIME *tm, uint fuzzydate);
int save_in_field(Field *field, bool no_conversions);
bool fix_fields(THD *, struct st_table_list *, Item **);
void set_null();
void set_int(longlong i, uint32 max_length_arg);
@ -1332,32 +1333,32 @@ 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
{
protected:
Item_result item_type;
Item_result orig_type;
Field *field_example;
public:
Item_type_holder(THD*, Item*, TABLE *);
TYPELIB *enum_set_typelib;
enum_field_types fld_type;
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; }
double val();
longlong val_int();
String *val_str(String*);
bool join_types(THD *thd, Item *, TABLE *);
Field *example() { return field_example; }
static uint32 real_length(Item *item);
void cleanup()
{
DBUG_ENTER("Item_type_holder::cleanup");
Item::cleanup();
item_type= orig_type;
DBUG_VOID_RETURN;
}
bool join_types(THD *thd, Item *);
Field *make_field_by_type(TABLE *table);
static uint32 display_length(Item *item);
static enum_field_types get_real_type(Item *);
};

View file

@ -393,10 +393,16 @@ int Arg_comparator::compare_e_binary_string()
int Arg_comparator::compare_real()
{
double val1= (*a)->val();
/*
Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
gcc to flush double values out of 80-bit Intel FPU registers before
performing the comparison.
*/
volatile double val1, val2;
val1= (*a)->val();
if (!(*a)->null_value)
{
double val2= (*b)->val();
val2= (*b)->val();
if (!(*b)->null_value)
{
owner->null_value= 0;

View file

@ -51,7 +51,7 @@ public:
SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC,
SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING,
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
NOT_FUNC, NOT_ALL_FUNC, NOW_FUNC};
NOT_FUNC, NOT_ALL_FUNC, NOW_FUNC, VAR_VALUE_FUNC};
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL };
enum Type type() const { return FUNC_ITEM; }
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
@ -981,6 +981,7 @@ public:
select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b)
*/
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
enum Functype functype() const { return VAR_VALUE_FUNC; }
const char *func_name() const { return "get_user_var"; }
bool const_item() const;
table_map used_tables() const

View file

@ -369,25 +369,13 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
}
substitution= select_lex->item_list.head();
/*
as far as we moved content to upper leven, field which depend of
as far as we moved content to upper level, field which depend of
'upper' select is not really dependent => we remove this dependence
*/
substitution->walk(&Item::remove_dependence_processor,
(byte *) select_lex->outer_select());
if (join->conds || join->having)
{
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;
}
/* SELECT without FROM clause can't have WHERE or HAVING clause */
DBUG_ASSERT(join->conds == 0 && join->having == 0);
return RES_REDUCE;
}
return RES_OK;
@ -542,7 +530,7 @@ bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
Item_in_subselect::Item_in_subselect(Item * left_exp,
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");
left_expr= left_exp;
@ -616,8 +604,14 @@ String *Item_exists_subselect::val_str(String *str)
return str;
}
double Item_in_subselect::val()
{
/*
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);
if (exec())
{
@ -630,6 +624,7 @@ double Item_in_subselect::val()
return (double) value;
}
longlong Item_in_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
@ -644,8 +639,14 @@ longlong Item_in_subselect::val_int()
return value;
}
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);
if (exec())
{
@ -669,18 +670,9 @@ Item_subselect::trans_res
Item_in_subselect::single_value_transformer(JOIN *join,
Comp_creator *func)
{
const char *save_where= thd->where;
DBUG_ENTER("Item_in_subselect::single_value_transformer");
if (changed)
{
DBUG_RETURN(RES_OK);
}
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
@ -689,7 +681,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (select_lex->item_list.elements > 1)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
goto err;
DBUG_RETURN(RES_ERROR);
}
/*
@ -709,11 +701,12 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (substitution)
{
// It is second (third, ...) SELECT of UNION => All is done
goto ok;
DBUG_RETURN(RES_OK);
}
Item *subs;
if (!select_lex->group_list.elements &&
!select_lex->having &&
!select_lex->with_sum_func &&
!(select_lex->next_select()))
{
@ -748,7 +741,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
reference
*/
if (item->fix_fields(thd, join->tables_list, 0))
goto err;
DBUG_RETURN(RES_ERROR);
/* we added aggregate function => we have to change statistic */
count_field_types(&join->tmp_table_param, join->all_fields, 0);
@ -764,25 +757,16 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (upper_item)
upper_item->set_sub_test(item);
}
// left expression belong to outer select
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;
/* fix fields is already called for left expression */
substitution= func->create(left_expr, subs);
goto ok;
DBUG_RETURN(RES_OK);
}
if (!substitution)
{
//first call for this 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;
@ -791,7 +775,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
{
thd->lex->current_select= current;
goto err;
DBUG_RETURN(RES_ERROR);
}
thd->lex->current_select= current;
@ -835,7 +819,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (join->having->fix_fields(thd, join->tables_list, 0))
{
select_lex->having_fix_field= 0;
goto err;
DBUG_RETURN(RES_ERROR);
}
select_lex->having_fix_field= 0;
}
@ -865,7 +849,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (join->having->fix_fields(thd, join->tables_list, 0))
{
select_lex->having_fix_field= 0;
goto err;
DBUG_RETURN(RES_ERROR);
}
select_lex->having_fix_field= 0;
item= new Item_cond_or(item,
@ -879,7 +863,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
*/
select_lex->where= join->conds= and_items(join->conds, item);
if (join->conds->fix_fields(thd, join->tables_list, 0))
goto err;
DBUG_RETURN(RES_ERROR);
}
else
{
@ -901,7 +885,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
0))
{
select_lex->having_fix_field= 0;
goto err;
DBUG_RETURN(RES_ERROR);
}
select_lex->having_fix_field= 0;
}
@ -919,54 +903,34 @@ Item_in_subselect::single_value_transformer(JOIN *join,
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SELECT_REDUCED, warn_buff);
}
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(RES_REDUCE);
}
}
}
ok:
if (arena)
thd->restore_backup_item_arena(arena, &backup);
thd->where= save_where;
DBUG_RETURN(RES_OK);
err:
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(RES_ERROR);
}
Item_subselect::trans_res
Item_in_subselect::row_value_transformer(JOIN *join)
{
const char *save_where= thd->where;
DBUG_ENTER("Item_in_subselect::row_value_transformer");
if (changed)
{
DBUG_RETURN(RES_OK);
}
Item_arena *arena, backup;
Item *item= 0;
SELECT_LEX *select_lex= join->select_lex;
thd->where= "row IN/ALL/ANY subquery";
arena= thd->change_arena_if_needed(&backup);
if (select_lex->item_list.elements != left_expr->cols())
{
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
goto err;
DBUG_RETURN(RES_ERROR);
}
if (!substitution)
{
//first call for this 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;
thd->lex->current_select= up= current->return_after_parsing();
@ -974,7 +938,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
{
thd->lex->current_select= current;
goto err;
DBUG_RETURN(RES_ERROR);
}
// we will refer to apper level cache array => we have to save it in PS
@ -993,7 +957,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed);
if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->el(i)->cols()))
goto err;
DBUG_RETURN(RES_ERROR);
Item *func= new Item_ref_null_helper(this,
select_lex->ref_pointer_array+i,
(char *) "<no matter>",
@ -1021,7 +985,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if (join->having->fix_fields(thd, join->tables_list, 0))
{
select_lex->having_fix_field= 0;
goto err;
DBUG_RETURN(RES_ERROR);
}
select_lex->having_fix_field= 0;
}
@ -1034,27 +998,112 @@ Item_in_subselect::row_value_transformer(JOIN *join)
*/
select_lex->where= join->conds= and_items(join->conds, item);
if (join->conds->fix_fields(thd, join->tables_list, 0))
goto err;
DBUG_RETURN(RES_ERROR);
}
if (arena)
thd->restore_backup_item_arena(arena, &backup);
thd->where= save_where;
DBUG_RETURN(RES_OK);
err:
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(RES_ERROR);
}
Item_subselect::trans_res
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;
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)
return single_value_transformer(join, &eq_creator);
return row_value_transformer(join);
res= single_value_transformer(join, func);
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);
}
@ -1077,7 +1126,7 @@ Item_allany_subselect::select_transformer(JOIN *join)
transformed= 1;
if (upper_item)
upper_item->show= 1;
return single_value_transformer(join, func);
return select_in_like_transformer(join, func);
}
@ -1191,7 +1240,7 @@ int subselect_single_select_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()

View file

@ -119,6 +119,7 @@ public:
friend class Item_in_optimizer;
friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **);
friend bool Item_ref::fix_fields(THD *, TABLE_LIST *, Item **);
friend bool Item_param::fix_fields(THD *, TABLE_LIST *, Item **);
};
/* single value subselect */
@ -220,8 +221,8 @@ public:
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
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; }
@ -232,8 +233,8 @@ public:
was_null= 0;
}
trans_res select_transformer(JOIN *join);
trans_res single_value_transformer(JOIN *join,
Comp_creator *func);
trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
trans_res single_value_transformer(JOIN *join, Comp_creator *func);
trans_res row_value_transformer(JOIN * join);
longlong val_int();
double val();

View file

@ -3990,8 +3990,6 @@ errorconn:
NullS);
sql_perror(buff);
}
my_security_attr_free(sa_event);
my_security_attr_free(sa_mapping);
if (handle_client_file_map)
CloseHandle(handle_client_file_map);
if (handle_client_map)

View file

@ -90,7 +90,7 @@ character-set=latin1
"Specified key was too long; max key length is %d bytes",
"Key column '%-.64s' doesn't exist in table",
"BLOB column '%-.64s' can't be used in key specification with the used table type",
"Column length too big for column '%-.64s' (max = %d); use BLOB instead",
"Column length too big for column '%-.64s' (max = %d); use BLOB or TEXT instead",
"Incorrect table definition; there can be only one auto column and it must be defined as a key",
"%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d",
"%s: Normal shutdown\n",

View file

@ -123,7 +123,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
DBUG_RETURN(1); // out of memory
// 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;
@ -161,7 +161,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
if (is_union)
{
// execute union without clean up
if (!(res= unit->prepare(thd, derived_result, SELECT_NO_UNLOCK)))
if (!(res= unit->prepare(thd, derived_result, SELECT_NO_UNLOCK, "")))
res= unit->exec();
}
else

View file

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

View file

@ -3731,6 +3731,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
db ? db : "", want_access, thd->master_access));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
bool db_is_pattern= test(want_access & GRANT_ACL);
#endif
ulong dummy;
if (save_priv)
@ -3757,9 +3758,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
*/
db_access= thd->db_access;
if (!(thd->master_access & SELECT_ACL) &&
(db && (!thd->db || strcmp(db,thd->db))))
db_access=acl_get(thd->host, thd->ip,
thd->priv_user, db, test(want_access & GRANT_ACL));
(db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
db_access=acl_get(thd->host, thd->ip, thd->priv_user, db, db_is_pattern);
*save_priv=thd->master_access | db_access;
DBUG_RETURN(FALSE);
}
@ -3777,9 +3777,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
if (db == any_db)
DBUG_RETURN(FALSE); // Allow select on anything
if (db && (!thd->db || strcmp(db,thd->db)))
db_access=acl_get(thd->host, thd->ip,
thd->priv_user, db, test(want_access & GRANT_ACL));
if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
db_access=acl_get(thd->host, thd->ip, thd->priv_user, db, db_is_pattern);
else
db_access=thd->db_access;
DBUG_PRINT("info",("db_access: %lu", db_access));
@ -4539,9 +4538,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
net_printf(thd,ER_TOO_BIG_SET,field_name); /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}
new_field->pack_length= (interval_list->elements + 7) / 8;
if (new_field->pack_length > 4)
new_field->pack_length=8;
new_field->pack_length= get_set_pack_length(interval_list->elements);
List_iterator<String> it(*interval_list);
String *tmp;
@ -4558,7 +4555,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
case FIELD_TYPE_ENUM:
{
// 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);
String *tmp;

View file

@ -1079,7 +1079,7 @@ static int mysql_test_select(Prepared_statement *stmt,
thd->used_tables= 0; // Updated by setup_fields
// JOIN::prepare calls
if (unit->prepare(thd, 0, 0))
if (unit->prepare(thd, 0, 0, ""))
{
send_error(thd);
goto err_prep;
@ -1228,7 +1228,7 @@ static int select_like_statement_test(Prepared_statement *stmt,
thd->used_tables= 0; // Updated by setup_fields
// JOIN::prepare calls
if (lex->unit.prepare(thd, 0, 0))
if (lex->unit.prepare(thd, 0, 0, ""))
{
res= thd->net.report_error ? -1 : 1;
}

View file

@ -4604,14 +4604,14 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
create_tmp_field_from_field()
thd Thread handler
org_field field from which new field will be created
name New field name
item Item to create a field for
table Temporary table
modify_item 1 if item->result_field should point to new item.
This is relevent for how fill_record() is going to
work:
If modify_item is 1 then fill_record() will update
item !=NULL if item->result_field should point to new field.
This is relevant for how fill_record() is going to work:
If item != NULL then fill_record() will update
the record in the original table.
If modify_item is 0 then fill_record() will update
If item == NULL then fill_record() will update
the temporary table
convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
@ -4622,8 +4622,8 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
*/
static Field* create_tmp_field_from_field(THD *thd, Field* org_field,
Item *item, TABLE *table,
bool modify_item,
const char *name, TABLE *table,
Item_field *item,
uint convert_blob_length)
{
Field *new_field;
@ -4636,10 +4636,10 @@ static Field* create_tmp_field_from_field(THD *thd, Field* org_field,
new_field= org_field->new_field(thd->mem_root, table);
if (new_field)
{
if (modify_item)
((Item_field *)item)->result_field= new_field;
if (item)
item->result_field= new_field;
else
new_field->field_name= item->name;
new_field->field_name= name;
if (org_field->maybe_null())
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
if (org_field->type() == FIELD_TYPE_VAR_STRING)
@ -4779,8 +4779,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
if (item_sum->args[0]->type() == Item::FIELD_ITEM)
{
*from_field= ((Item_field*) item_sum->args[0])->field;
return create_tmp_field_from_field(thd, *from_field, item, table,
modify_item, convert_blob_length);
return create_tmp_field_from_field(thd, *from_field, item->name, table,
NULL, convert_blob_length);
}
/* fall through */
default:
@ -4818,8 +4818,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case Item::DEFAULT_VALUE_ITEM:
{
Item_field *field= (Item_field*) item;
return create_tmp_field_from_field(thd, (*from_field= field->field), item,
table, modify_item, convert_blob_length);
return create_tmp_field_from_field(thd, (*from_field= field->field),
item->name, table,
modify_item ? (Item_field*) item : NULL,
convert_blob_length);
}
case Item::FUNC_ITEM:
case Item::COND_ITEM:
@ -4837,14 +4839,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,
convert_blob_length);
case Item::TYPE_HOLDER:
{
Field *example= ((Item_type_holder *)item)->example();
if (example)
return create_tmp_field_from_field(thd, example, item, table, 0,
convert_blob_length);
return create_tmp_field_from_item(thd, item, table, copy_func, 0,
convert_blob_length);
}
return ((Item_type_holder *)item)->make_field_by_type(table);
default: // Dosen't have to be stored
return 0;
}
@ -5341,8 +5336,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (create_myisam_tmp_table(table,param,select_options))
goto err;
}
/* Set table_name for easier debugging */
table->table_name= base_name(tmpname);
if (!open_tmp_table(table))
DBUG_RETURN(table);
@ -7183,7 +7176,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 */
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
{
@ -9592,7 +9597,8 @@ int 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->type= "UNION RESULT";
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->cleanup();
}

View file

@ -29,7 +29,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result,
{
DBUG_ENTER("mysql_union");
int res= 0;
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK)))
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK, "")))
res= unit->exec();
res|= unit->cleanup();
DBUG_RETURN(res);
@ -142,7 +142,8 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd)
int 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 *sl, *first_select;
@ -252,7 +253,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
while ((item_tmp= it++))
{
/* 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)
@ -271,8 +272,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
Item *type, *item_tmp;
while ((type= tp++, item_tmp= it++))
{
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp,
empty_table))
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
DBUG_RETURN(-1);
}
}
@ -304,7 +304,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
(first_select_in_union()->options |
thd_arg->options |
TMP_TABLE_ALL_COLUMNS),
HA_POS_ERROR, (char*) "")))
HA_POS_ERROR, (char *) tmp_table_alias)))
goto err;
table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);

View file

@ -90,7 +90,9 @@ struct st_table {
uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob fields */
key_map keys_in_use, keys_for_keyread, read_only_keys;
key_map quick_keys, used_keys, keys_in_use_for_query;
key_map quick_keys;
key_map used_keys; /* keys that cover all used table fields */
key_map keys_in_use_for_query;
KEY *key_info; /* data of keys in database */
TYPELIB keynames; /* Pointers to keynames */
ha_rows max_rows; /* create information */

View file

@ -6284,11 +6284,7 @@ uint my_well_formed_len_big5(CHARSET_INFO *cs __attribute__((unused)),
const char *emb= e - 1; /* Last possible end of an MB character */
while (pos && b < e)
{
/*
Cast to int8 for extra safety. "char" can be unsigned
by default on some platforms.
*/
if (((int8)b[0]) >= 0)
if ((uchar) b[0] < 128)
{
/* Single byte ascii character */
b++;

View file

@ -4576,12 +4576,7 @@ uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)),
const char *b0= b;
while (pos && b < e)
{
/*
Cast to int8 for extra safety.
"char" can be unsigned by default
on some platforms.
*/
if (((int8)b[0]) >= 0)
if ((uchar) b[0] < 128)
{
/* Single byte ascii character */
b++;

View file

@ -2129,12 +2129,7 @@ int my_strcasecmp_utf8(CHARSET_INFO *cs, const char *s, const char *t)
{
my_wc_t s_wc,t_wc;
/*
Cast to int8 for extra safety.
char can be unsigned by default
on some platforms.
*/
if (((int8)s[0]) >= 0)
if ((uchar) s[0] < 128)
{
/*
s[0] is between 0 and 127.
@ -2181,7 +2176,7 @@ int my_strcasecmp_utf8(CHARSET_INFO *cs, const char *s, const char *t)
/* Do the same for the second string */
if (((int8)t[0]) >= 0)
if ((uchar) t[0] < 128)
{
/* Convert single byte character into weight */
t_wc= plane00[(uchar) t[0]].tolower;
@ -2380,6 +2375,172 @@ CHARSET_INFO my_charset_utf8_bin=
&my_collation_mb_bin_handler
};
#ifdef HAVE_CYBOZU_COLLATION
/*
* These functions bacically do the same as their original, except
* that they return 0 only when two comparing unicode strings are
* strictly the same in case-sensitive way. See "save_diff" local
* variable to what they actually do.
*/
static int my_strnncoll_utf8_cs(CHARSET_INFO *cs,
const uchar *s, uint slen,
const uchar *t, uint tlen,
my_bool t_is_prefix)
{
int s_res,t_res;
my_wc_t s_wc,t_wc;
const uchar *se=s+slen;
const uchar *te=t+tlen;
int save_diff = 0;
int diff;
while ( s < se && t < te )
{
int plane;
s_res=my_utf8_uni(cs,&s_wc, s, se);
t_res=my_utf8_uni(cs,&t_wc, t, te);
if ( s_res <= 0 || t_res <= 0 )
{
/* Incorrect string, compare by char value */
return ((int)s[0]-(int)t[0]);
}
if ( save_diff == 0 )
{
save_diff = ((int)s_wc) - ((int)t_wc);
}
plane=(s_wc>>8) & 0xFF;
s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
plane=(t_wc>>8) & 0xFF;
t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
if ( s_wc != t_wc )
{
return ((int) s_wc) - ((int) t_wc);
}
s+=s_res;
t+=t_res;
}
diff = ( (se-s) - (te-t) );
return t_is_prefix ? t-te : ((diff == 0) ? save_diff : diff);
}
static int my_strnncollsp_utf8_cs(CHARSET_INFO *cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
int s_res,t_res;
my_wc_t s_wc,t_wc;
const uchar *se= s+slen;
const uchar *te= t+tlen;
int save_diff = 0;
while ( s < se && t < te )
{
int plane;
s_res=my_utf8_uni(cs,&s_wc, s, se);
t_res=my_utf8_uni(cs,&t_wc, t, te);
if ( s_res <= 0 || t_res <= 0 )
{
/* Incorrect string, compare by char value */
return ((int)s[0]-(int)t[0]);
}
if ( save_diff == 0 )
{
save_diff = ((int)s_wc) - ((int)t_wc);
}
plane=(s_wc>>8) & 0xFF;
s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
plane=(t_wc>>8) & 0xFF;
t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
if ( s_wc != t_wc )
{
return ((int) s_wc) - ((int) t_wc);
}
s+=s_res;
t+=t_res;
}
slen= se-s;
tlen= te-t;
if (slen != tlen)
{
int swap= 0;
if (slen < tlen)
{
slen= tlen;
s= t;
se= te;
swap= -1;
}
/*
This following loop uses the fact that in UTF-8
all multibyte characters are greater than space,
and all multibyte head characters are greater than
space. It means if we meet a character greater
than space, it always means that the longer string
is greater. So we can reuse the same loop from the
8bit version, without having to process full multibute
sequences.
*/
for ( ; s < se; s++)
{
if (*s != ' ')
return ((int)*s - (int) ' ') ^ swap;
}
}
return save_diff;
}
static MY_COLLATION_HANDLER my_collation_cs_handler =
{
NULL, /* init */
my_strnncoll_utf8_cs,
my_strnncollsp_utf8_cs,
my_strnxfrm_utf8,
my_like_range_simple,
my_wildcmp_mb,
my_strcasecmp_utf8,
my_instr_mb,
my_hash_sort_utf8
};
CHARSET_INFO my_charset_utf8_general_cs=
{
254,0,0, /* number */
MY_CS_COMPILED|MY_CS_UNICODE, /* state */
"utf8", /* cs name */
"utf8_general_cs", /* name */
"", /* comment */
NULL, /* tailoring */
ctype_utf8, /* ctype */
to_lower_utf8, /* to_lower */
to_upper_utf8, /* to_upper */
to_upper_utf8, /* sort_order */
NULL, /* contractions */
NULL, /* sort_order_big*/
NULL, /* tab_to_uni */
NULL, /* tab_from_uni */
NULL, /* state_map */
NULL, /* ident_map */
1, /* strxfrm_multiply */
1, /* mbminlen */
3, /* mbmaxlen */
0, /* min_sort_char */
255, /* max_sort_char */
&my_charset_utf8_handler,
&my_collation_cs_handler
};
#endif /* Cybozu Hack */
#ifdef MY_TEST_UTF8
#include <stdio.h>

View file

@ -394,7 +394,7 @@ my_strtoll10:
popl %ebp
ret
my_strtoll10_end:
.my_strtoll10_end:
.size my_strtoll10,.my_strtoll10_end-my_strtoll10
.comm res,240,32
.comm end_ptr,120,32

View file

@ -87,10 +87,23 @@ parse_arguments() {
}
wait_for_pid () {
for((i=0; i<35; i++)); do
i=0
while test $i -lt 35 ; do
sleep 1
test -s $pid_file && i='' && break
case "$1" in
'created')
test -s $pid_file && i='' && break
;;
'removed')
test ! -s $pid_file && i='' && break
;;
*)
echo "wait_for_pid () usage: wait_for_pid created|removed"
exit 1
;;
esac
echo $echo_n ".$echo_c"
i=`expr $i + 1`
done
if test -z "$i" ; then
@ -178,7 +191,7 @@ case "$mode" in
# be overwritten at next upgrade.
echo $echo_n "Starting MySQL"
$bindir/mysqld_safe --datadir=$datadir --pid-file=$pid_file >/dev/null 2>&1 &
wait_for_pid
wait_for_pid created
# Make lock for RedHat / SuSE
if test -w /var/lock/subsys
@ -199,7 +212,7 @@ case "$mode" in
echo $echo_n "Shutting down MySQL"
kill $mysqld_pid
# mysqld should remove the pid_file when it exits, so wait for it.
wait_for_pid
wait_for_pid removed
# delete lock for RedHat / SuSE
if test -f /var/lock/subsys/mysql

View file

@ -115,7 +115,7 @@ main(int argc, char** argv)
{
/* child, therefore, client */
char xbuf[100];
int r = client_vio->read(client_vio,xbuf, sizeof(xbuf));
int r = vio_read(client_vio,xbuf, sizeof(xbuf));
if (r<=0) {
my_free((gptr)ssl_acceptor,MYF(0));
my_free((gptr)ssl_connector,MYF(0));
@ -130,7 +130,7 @@ main(int argc, char** argv)
else
{
const char* s = "Huhuhuh";
int r = server_vio->write(server_vio,(gptr)s, strlen(s));
int r = vio_write(server_vio,(gptr)s, strlen(s));
if (r<=0) {
my_free((gptr)ssl_acceptor,MYF(0));
my_free((gptr)ssl_connector,MYF(0));

View file

@ -77,13 +77,13 @@ main( int argc __attribute__((unused)),
sa.sin_port = htons (1111); /* Server Port number */
err = connect(client_vio->sd, (struct sockaddr*) &sa,
sizeof(sa));
sizeof(sa));
/* ----------------------------------------------- */
/* Now we have TCP conncetion. Start SSL negotiation. */
read(client_vio->sd,xbuf, sizeof(xbuf));
sslconnect(ssl_connector,client_vio,60L);
err = client_vio->read(client_vio,xbuf, sizeof(xbuf));
err = vio_read(client_vio,xbuf, sizeof(xbuf));
if (err<=0) {
my_free((gptr)ssl_connector,MYF(0));
fatal_error("client:SSL_read");