This commit is contained in:
monty@mysql.com 2005-01-04 13:23:04 +02:00
commit 3c6d5e43f9
53 changed files with 3551 additions and 157 deletions

View File

@ -698,6 +698,8 @@ ndb/examples/ndbapi_example2/ndbapi_example2
ndb/examples/ndbapi_example3/ndbapi_example3 ndb/examples/ndbapi_example3/ndbapi_example3
ndb/examples/ndbapi_example5/ndbapi_example5 ndb/examples/ndbapi_example5/ndbapi_example5
ndb/examples/select_all/select_all ndb/examples/select_all/select_all
ndb/include/ndb_global.h
ndb/include/ndb_version.h
ndb/lib/libMGM_API.so ndb/lib/libMGM_API.so
ndb/lib/libNDB_API.so ndb/lib/libNDB_API.so
ndb/lib/libNDB_ODBC.so ndb/lib/libNDB_ODBC.so

47
BUILD/compile-dist Executable file
View File

@ -0,0 +1,47 @@
#!/bin/sh
#
# This script's purpose is to update the automake/autoconf helper scripts and
# to run a plain "configure" without any special compile flags. Only features
# that affect the content of the source distribution are enabled. The resulting
# tree can then be picked up by "make dist" to create the "pristine source
# package" that is used as the basis for all other binary builds.
#
make distclean
aclocal
autoheader
libtoolize --automake --force --copy
automake --force --add-missing --copy
autoconf
(cd bdb/dist && sh s_all)
(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
# Default to gcc for CC and CXX
if test -z "$CXX" ; then
export CXX=gcc
fi
if test -z "$CC" ; then
export CC=gcc
fi
# Use ccache, if available
if ccache -V > /dev/null 2>&1
then
if ! (echo "$CC" | grep "ccache" > /dev/null)
then
export CC="ccache $CC"
fi
if ! (echo "$CXX" | grep "ccache" > /dev/null)
then
export CXX="ccache $CXX"
fi
fi
# Make sure to enable all features that affect "make dist"
./configure \
--with-embedded-server \
--with-berkeley-db \
--with-innodb \
--enable-thread-safe-client \
--with-ndbcluster
make

View File

@ -171,6 +171,7 @@ paul@frost.snake.net
paul@ice.local paul@ice.local
paul@ice.snake.net paul@ice.snake.net
paul@kite-hub.kitebird.com paul@kite-hub.kitebird.com
paul@snake-hub.snake.net
paul@teton.kitebird.com paul@teton.kitebird.com
pekka@mysql.com pekka@mysql.com
pem@mysql.com pem@mysql.com

View File

@ -26,7 +26,7 @@ else
} }
# Some predefined settings # Some predefined settings
$build_command= "BUILD/compile-pentium-max"; $build_command= "BUILD/compile-dist";
$PWD= cwd(); $PWD= cwd();
$opt_docdir= $PWD . "/mysqldoc"; $opt_docdir= $PWD . "/mysqldoc";
$opt_archive_log= undef; $opt_archive_log= undef;
@ -70,7 +70,7 @@ GetOptions(
"test|t", "test|t",
"verbose|v", "verbose|v",
"win-dist|w", "win-dist|w",
"quiet|q", "quiet|q",
) || print_help(""); ) || print_help("");
# #
@ -122,18 +122,8 @@ if (($opt_directory ne $PWD) && (!-d $opt_directory && !$opt_dry_run))
# #
if ($opt_pull) if ($opt_pull)
{ {
&logger("Updating BK tree $REPO to latest ChangeSet first"); &bk_pull("$REPO");
chdir ($REPO) or &abort("Could not chdir to $REPO!"); &bk_pull("$opt_docdir") unless ($opt_skip_manual);
&run_command("bk pull", "Could not update $REPO!");
chdir ($PWD) or &abort("Could not chdir to $PWD!");
unless ($opt_skip_manual)
{
&logger("Updating manual tree in $opt_docdir");
chdir ($opt_docdir) or &abort("Could not chdir to $opt_docdir!");
&run_command("bk pull", "Could not update $opt_docdir!");
chdir ($PWD) or &abort("Could not chdir to $PWD!");
}
} }
# #
@ -270,7 +260,7 @@ if (defined $opt_changelog)
$command.= " " . $REPO . " > $target_dir/ChangeLog"; $command.= " " . $REPO . " > $target_dir/ChangeLog";
&logger($command); &logger($command);
# We cannot use run_command here because of output redirection # We cannot use run_command here because of output redirection
if (!$opt_dry_run) unless ($opt_dry_run)
{ {
system($command) == 0 or &abort("Could not create $target_dir/ChangeLog!"); system($command) == 0 or &abort("Could not create $target_dir/ChangeLog!");
} }
@ -281,17 +271,17 @@ if (defined $opt_changelog)
# #
unless ($opt_skip_manual) unless ($opt_skip_manual)
{ {
$msg= "Updating manual files"; &logger("Updating manual files");
&logger($msg);
foreach $file qw/internals manual reservedwords/ foreach $file qw/internals manual reservedwords/
{ {
system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0 system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0
or &abort("Could not update $file.texi in $target_dir/Docs/!"); or &abort("Could not update $file.texi in $target_dir/Docs/!");
} }
system ("rm -f $target_dir/Docs/Images/Makefile*") == 0
or &abort("Could not remove Makefiles in $target_dir/Docs/Images/!"); &run_command("rm -f $target_dir/Docs/Images/Makefile*",
system ("cp $opt_docdir/Docs/Images/*.* $target_dir/Docs/Images") == 0 "Could not remove Makefiles in $target_dir/Docs/Images/!");
or &abort("Could not copy image files in $target_dir/Docs/Images/!"); &run_command("cp $opt_docdir/Docs/Images/*.* $target_dir/Docs/Images",
"Could not copy image files in $target_dir/Docs/Images/!");
} }
# #
@ -377,6 +367,18 @@ if ($opt_archive_log)
exit 0; exit 0;
#
# Run a BK pull on the given BK tree
#
sub bk_pull
{
my $bk_tree= $_[0];
&logger("Updating BK tree $bk_tree to latest ChangeSet first");
chdir ($bk_tree) or &abort("Could not chdir to $bk_tree!");
&run_command("bk pull", "Could not update $bk_tree!");
chdir ($PWD) or &abort("Could not chdir to $PWD!");
}
# #
# Print the help text message (with an optional message on top) # Print the help text message (with an optional message on top)
# #

View File

@ -23,14 +23,14 @@ EXTRA_DIST = INSTALL-SOURCE README COPYING EXCEPTIONS-CLIENT
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
@readline_topdir@ sql-common \ @readline_topdir@ sql-common \
@thread_dirs@ pstack \ @thread_dirs@ pstack \
@sql_server_dirs@ @sql_client_dirs@ scripts man tests \ @sql_union_dirs@ scripts man tests \
netware @libmysqld_dirs@ \ netware @libmysqld_dirs@ \
@bench_dirs@ support-files @fs_dirs@ @tools_dirs@ @bench_dirs@ support-files @fs_dirs@ @tools_dirs@
DIST_SUBDIRS = . include @docs_dirs@ zlib \ DIST_SUBDIRS = . include @docs_dirs@ zlib \
@readline_topdir@ sql-common \ @readline_topdir@ sql-common \
@thread_dirs@ pstack \ @thread_dirs@ pstack \
@sql_server_dirs@ @sql_client_dirs@ scripts @man_dirs@ tests SSL\ @sql_union_dirs@ scripts @man_dirs@ tests SSL\
BUILD netware os2 @libmysqld_dirs@ \ BUILD netware os2 @libmysqld_dirs@ \
@bench_dirs@ support-files @fs_dirs@ @tools_dirs@ @bench_dirs@ support-files @fs_dirs@ @tools_dirs@

View File

@ -2449,7 +2449,7 @@ thread_dirs=
dnl This probably should be cleaned up more - for now the threaded dnl This probably should be cleaned up more - for now the threaded
dnl client is just using plain-old libs. dnl client is just using plain-old libs.
sql_client_dirs="libmysql client" sql_client_dirs="libmysql strings regex client"
linked_client_targets="linked_libmysql_sources" linked_client_targets="linked_libmysql_sources"
CLIENT_LIBS=$NON_THREADED_CLIENT_LIBS CLIENT_LIBS=$NON_THREADED_CLIENT_LIBS
if test "$THREAD_SAFE_CLIENT" != "no" if test "$THREAD_SAFE_CLIENT" != "no"
@ -2623,6 +2623,20 @@ AC_SUBST(sql_server_dirs)
AC_SUBST(thread_dirs) AC_SUBST(thread_dirs)
AC_SUBST(server_scripts) AC_SUBST(server_scripts)
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
# Start with the (longer) server list, add each client item not yet present.
sql_union_dirs=" $sql_server_dirs "
for DIR in $sql_client_dirs
do
if echo $sql_union_dirs | grep " $DIR " >/dev/null
then
: # already present, skip
else
sql_union_dirs="$sql_union_dirs $DIR "
fi
done
AC_SUBST(sql_union_dirs)
#if test "$with_posix_threads" = "no" -o "$with_mit_threads" = "yes" #if test "$with_posix_threads" = "no" -o "$with_mit_threads" = "yes"
#then #then
# MIT pthreads does now support connecting with unix sockets # MIT pthreads does now support connecting with unix sockets

View File

@ -3040,8 +3040,7 @@ recv_reset_log_files_for_backup(
memcpy(name + log_dir_len, logfilename, sizeof logfilename); memcpy(name + log_dir_len, logfilename, sizeof logfilename);
buf = ut_malloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE); buf = ut_malloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
memset(buf, LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE, '\0'); memset(buf, '\0', LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
for (i = 0; i < n_log_files; i++) { for (i = 0; i < n_log_files; i++) {

View File

@ -1467,12 +1467,14 @@ static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff,
if (_mi_ft_add(info,i,(char*) key,buff,filepos)) if (_mi_ft_add(info,i,(char*) key,buff,filepos))
goto err; goto err;
} }
#ifdef HAVE_SPATIAL
else if (info->s->keyinfo[i].flag & HA_SPATIAL) else if (info->s->keyinfo[i].flag & HA_SPATIAL)
{ {
uint key_length=_mi_make_key(info,i,key,buff,filepos); uint key_length=_mi_make_key(info,i,key,buff,filepos);
if (rtree_insert(info, i, key, key_length)) if (rtree_insert(info, i, key, key_length))
goto err; goto err;
} }
#endif /*HAVE_SPATIAL*/
else else
{ {
uint key_length=_mi_make_key(info,i,key,buff,filepos); uint key_length=_mi_make_key(info,i,key,buff,filepos);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,44 @@
# -*- 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 strict;
# These are not to be prefixed with "mtr_"
sub gcov_prepare ();
sub gcov_collect ();
##############################################################################
#
#
#
##############################################################################
sub gcov_prepare () {
`find $::glob_basedir -name \*.gcov \
-or -name \*.da | xargs rm`;
}
sub gcov_collect () {
print "Collecting source coverage info...\n";
-f $::opt_gcov_msg and unlink($::opt_gcov_msg);
-f $::opt_gcov_err and unlink($::opt_gcov_err);
foreach my $d ( @::mysqld_src_dirs )
{
chdir("$::glob_basedir/$d");
foreach my $f ( (glob("*.h"), glob("*.cc"), glob("*.c")) )
{
`$::opt_gcov $f 2>>$::opt_gcov_err >>$::opt_gcov_msg`;
}
chdir($::glob_mysql_test_dir);
}
print "gcov info in $::opt_gcov_msg, errors in $::opt_gcov_err\n";
}
1;

View File

@ -0,0 +1,50 @@
# -*- 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 strict;
# These are not to be prefixed with "mtr_"
sub gprof_prepare ();
sub gprof_collect ();
##############################################################################
#
#
#
##############################################################################
sub gprof_prepare () {
rmtree($::opt_gprof_dir);
mkdir($::opt_gprof_dir);
}
# FIXME what about master1 and slave1?!
sub gprof_collect () {
if ( -f "$::master->[0]->{'path_myddir'}/gmon.out" )
{
# FIXME check result code?!
mtr_run("gprof",
[$::exe_master_mysqld,
"$::master->[0]->{'path_myddir'}/gmon.out"],
$::opt_gprof_master, "", "", "");
print "Master execution profile has been saved in $::opt_gprof_master\n";
}
if ( -f "$::slave->[0]->{'path_myddir'}/gmon.out" )
{
# FIXME check result code?!
mtr_run("gprof",
[$::exe_slave_mysqld,
"$::slave->[0]->{'path_myddir'}/gmon.out"],
$::opt_gprof_slave, "", "", "");
print "Slave execution profile has been saved in $::opt_gprof_slave\n";
}
}
1;

71
mysql-test/lib/mtr_io.pl Normal file
View File

@ -0,0 +1,71 @@
# -*- 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 strict;
sub mtr_get_pid_from_file ($);
sub mtr_get_opts_from_file ($);
sub mtr_tofile ($@);
sub mtr_tonewfile($@);
##############################################################################
#
#
#
##############################################################################
sub mtr_get_pid_from_file ($) {
my $file= shift;
open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!");
my $pid= <FILE>;
chomp($pid);
close FILE;
return $pid;
}
sub mtr_get_opts_from_file ($) {
my $file= shift;
open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!");
my @args;
while ( <FILE> )
{
chomp;
s/\$MYSQL_TEST_DIR/$::glob_mysql_test_dir/g;
push(@args, split(' ', $_));
}
close FILE;
return \@args;
}
sub mtr_fromfile ($) {
my $file= shift;
open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!");
my $text= join('', <FILE>);
close FILE;
return $text;
}
sub mtr_tofile ($@) {
my $file= shift;
open(FILE,">>",$file) or mtr_error("can't open file \"$file\": $!");
print FILE join("", @_);
close FILE;
}
sub mtr_tonewfile ($@) {
my $file= shift;
open(FILE,">",$file) or mtr_error("can't open file \"$file\": $!");
print FILE join("", @_);
close FILE;
}
1;

View File

@ -0,0 +1,67 @@
# -*- 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 strict;
sub mtr_match_prefix ($$);
sub mtr_match_extension ($$);
sub mtr_match_any_exact ($$);
##############################################################################
#
#
#
##############################################################################
# Match a prefix and return what is after the prefix
sub mtr_match_prefix ($$) {
my $string= shift;
my $prefix= shift;
if ( $string =~ /^\Q$prefix\E(.*)$/ ) # strncmp
{
return $1;
}
else
{
return undef; # NULL
}
}
# Match extension and return the name without extension
sub mtr_match_extension ($$) {
my $file= shift;
my $ext= shift;
if ( $file =~ /^(.*)\.\Q$ext\E$/ ) # strchr+strcmp or something
{
return $1;
}
else
{
return undef; # NULL
}
}
sub mtr_match_any_exact ($$) {
my $string= shift;
my $mlist= shift;
foreach my $m (@$mlist)
{
if ( $string eq $m )
{
return 1;
}
}
return 0;
}
1;

View File

@ -0,0 +1,50 @@
# -*- 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 strict;
sub mtr_full_hostname ();
sub mtr_init_args ($);
sub mtr_add_arg ($$);
##############################################################################
#
# Misc
#
##############################################################################
# We want the fully qualified host name and hostname() may have returned
# only the short name. So we use the resolver to find out.
sub mtr_full_hostname () {
my $hostname= hostname();
if ( $hostname !~ /\./ )
{
my $address= gethostbyname($hostname)
or die "Couldn't resolve $hostname : $!";
my $fullname= gethostbyaddr($address, AF_INET);
$hostname= $fullname if $fullname;
}
return $hostname;
}
# FIXME move to own lib
sub mtr_init_args ($) {
my $args = shift;
$$args = []; # Empty list
}
sub mtr_add_arg ($$) {
my $args= shift;
my $format= shift;
my @fargs = @_;
push(@$args, sprintf($format, @fargs));
}
1;

View File

@ -0,0 +1,467 @@
# -*- 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 Carp qw(cluck);
use strict;
use POSIX ":sys_wait_h";
sub mtr_run ($$$$$$);
sub mtr_spawn ($$$$$$);
sub mtr_stop_mysqld_servers ($$);
sub mtr_kill_leftovers ();
# static in C
sub spawn_impl ($$$$$$$);
##############################################################################
#
# Execute an external command
#
##############################################################################
# This function try to mimic the C version used in "netware/mysql_test_run.c"
# FIXME learn it to handle append mode as well, a "new" flag or a "append"
sub mtr_run ($$$$$$) {
my $path= shift;
my $arg_list_t= shift;
my $input= shift;
my $output= shift;
my $error= shift;
my $pid_file= shift;
return spawn_impl($path,$arg_list_t,1,$input,$output,$error,$pid_file);
}
sub mtr_spawn ($$$$$$) {
my $path= shift;
my $arg_list_t= shift;
my $input= shift;
my $output= shift;
my $error= shift;
my $pid_file= shift;
return spawn_impl($path,$arg_list_t,0,$input,$output,$error,$pid_file);
}
##############################################################################
#
# If $join is set, we return the error code, else we return the PID
#
##############################################################################
sub spawn_impl ($$$$$$$) {
my $path= shift;
my $arg_list_t= shift;
my $join= shift;
my $input= shift;
my $output= shift;
my $error= shift;
my $pid_file= shift; # FIXME
# FIXME really needing a PATH???
# $ENV{'PATH'}= "/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$ENV{'PATH'}";
$ENV{'TZ'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work
$ENV{'LC_COLLATE'}= "C";
$ENV{'MYSQL_TEST_DIR'}= $::glob_mysql_test_dir;
$ENV{'MASTER_MYPORT'}= $::opt_master_myport;
$ENV{'SLAVE_MYPORT'}= $::opt_slave_myport;
# $ENV{'MYSQL_TCP_PORT'}= '@MYSQL_TCP_PORT@'; # FIXME
$ENV{'MYSQL_TCP_PORT'}= 3306;
$ENV{'MASTER_MYSOCK'}= $::master->[0]->{'path_mysock'};
if ( $::opt_script_debug )
{
print STDERR "\n";
print STDERR "#### ", "-" x 78, "\n";
print STDERR "#### ", "STDIN $input\n" if $input;
print STDERR "#### ", "STDOUT $output\n" if $output;
print STDERR "#### ", "STDERR $error\n" if $error;
if ( $join )
{
print STDERR "#### ", "run";
}
else
{
print STDERR "#### ", "spawn";
}
print STDERR "$path ", join(" ",@$arg_list_t), "\n";
print STDERR "#### ", "-" x 78, "\n";
}
my $pid= fork();
if ( $pid )
{
# Parent, i.e. the main script
if ( $join )
{
# We run a command and wait for the result
# FIXME this need to be improved
waitpid($pid,0);
my $exit_value= $? >> 8;
my $signal_num= $? & 127;
my $dumped_core= $? & 128;
if ( $signal_num )
{
mtr_error("spawn got signal $signal_num");
}
if ( $dumped_core )
{
mtr_error("spawn dumped core");
}
return $exit_value;
}
else
{
# We spawned a process we don't wait for
return $pid;
}
}
else
{
# Child, redirect output and exec
# FIXME I tried POSIX::setsid() here to detach and, I hoped,
# avoid zombies. But everything went wild, somehow the parent
# became a deamon as well, and was hard to kill ;-)
# Need to catch SIGCHLD and do waitpid or something instead......
$SIG{INT}= 'DEFAULT'; # Parent do some stuff, we don't
if ( $output )
{
if ( ! open(STDOUT,">",$output) )
{
mtr_error("can't redirect STDOUT to \"$output\": $!");
}
}
if ( $error )
{
if ( $output eq $error )
{
if ( ! open(STDERR,">&STDOUT") )
{
mtr_error("can't dup STDOUT: $!");
}
}
else
{
if ( ! open(STDERR,">",$error) )
{
mtr_error("can't redirect STDERR to \"$output\": $!");
}
}
}
if ( $input )
{
if ( ! open(STDIN,"<",$input) )
{
mtr_error("can't redirect STDIN to \"$input\": $!");
}
}
exec($path,@$arg_list_t);
}
}
##############################################################################
#
# Kill processes left from previous runs
#
##############################################################################
sub mtr_kill_leftovers () {
# First, kill all masters and slaves that would conflict with
# this run. Make sure to remove the PID file, if any.
my @args;
for ( my $idx; $idx < 2; $idx++ )
{
push(@args,{
pid => 0, # We don't know the PID
pidfile => $::master->[$idx]->{'path_mypid'},
sockfile => $::master->[$idx]->{'path_mysock'},
port => $::master->[$idx]->{'path_myport'},
});
}
for ( my $idx; $idx < 3; $idx++ )
{
push(@args,{
pid => 0, # We don't know the PID
pidfile => $::slave->[$idx]->{'path_mypid'},
sockfile => $::slave->[$idx]->{'path_mysock'},
port => $::slave->[$idx]->{'path_myport'},
});
}
mtr_stop_mysqld_servers(\@args, 1);
# We scan the "var/run/" directory for other process id's to kill
my $rundir= "$::glob_mysql_test_dir/var/run"; # FIXME $path_run_dir or something
if ( -d $rundir )
{
opendir(RUNDIR, $rundir)
or mtr_error("can't open directory \"$rundir\": $!");
my @pids;
while ( my $elem= readdir(RUNDIR) )
{
my $pidfile= "$rundir/$elem";
if ( -f $pidfile )
{
my $pid= mtr_get_pid_from_file($pidfile);
if ( ! unlink($pidfile) )
{
mtr_error("can't remove $pidfile");
}
push(@pids, $pid);
}
}
closedir(RUNDIR);
start_reap_all();
if ( $::glob_cygwin_perl )
{
# We have no (easy) way of knowing the Cygwin controlling
# process, in the PID file we only have the Windows process id.
system("kill -f " . join(" ",@pids)); # Hope for the best....
}
else
{
my $retries= 10; # 10 seconds
do
{
kill(9, @pids);
} while ( $retries-- and kill(0, @pids) );
if ( kill(0, @pids) )
{
mtr_error("can't kill processes " . join(" ", @pids));
}
}
stop_reap_all();
}
}
##############################################################################
#
# Shut down mysqld servers
#
##############################################################################
# To speed things we kill servers in parallel.
# The argument is a list of 'pidfiles' and 'socketfiles'.
# We use the pidfiles and socketfiles to try to terminate the servers.
# This is not perfect, there could still be other server processes
# left.
# Force flag is to be set only for killing mysqld servers this script
# didn't create in this run, i.e. initial cleanup before we start working.
# If force flag is set, we try to kill all with mysqladmin, and
# give up if we have no PIDs.
# FIXME On some operating systems, $srv->{'pid'} and $srv->{'pidfile'}
# will not be the same PID. We need to try to kill both I think.
sub mtr_stop_mysqld_servers ($$) {
my $spec= shift;
my $force= shift;
# ----------------------------------------------------------------------
# If the process was not started from this file, we got no PID,
# we try to find it in the PID file.
# ----------------------------------------------------------------------
my $any_pid= 0; # If we have any PIDs
foreach my $srv ( @$spec )
{
if ( ! $srv->{'pid'} and -f $srv->{'pidfile'} )
{
$srv->{'pid'}= mtr_get_pid_from_file($srv->{'pidfile'});
}
if ( $srv->{'pid'} )
{
$any_pid= 1;
}
}
# If the processes where started from this script, and we know
# no PIDs, then we don't have to do anything.
if ( ! $any_pid and ! $force )
{
# cluck "This is how we got here!";
return;
}
# ----------------------------------------------------------------------
# First try nice normal shutdown using 'mysqladmin'
# ----------------------------------------------------------------------
start_reap_all(); # Don't require waitpid() of children
foreach my $srv ( @$spec )
{
if ( -e $srv->{'sockfile'} or $srv->{'port'} )
{
# FIXME wrong log.....
# FIXME, stderr.....
# Shutdown time must be high as slave may be in reconnect
my $args;
mtr_init_args(\$args);
mtr_add_arg($args, "--no-defaults");
mtr_add_arg($args, "-uroot");
if ( -e $srv->{'sockfile'} )
{
mtr_add_arg($args, "--socket=%s", $srv->{'sockfile'});
}
if ( $srv->{'port'} )
{
mtr_add_arg($args, "--port=%s", $srv->{'port'});
}
mtr_add_arg($args, "--connect_timeout=5");
mtr_add_arg($args, "--shutdown_timeout=70");
mtr_add_arg($args, "shutdown");
# We don't wait for termination of mysqladmin
mtr_spawn($::exe_mysqladmin, $args,
"", $::path_manager_log, $::path_manager_log, "");
}
}
# Wait for them all to remove their pid and socket file
PIDSOCKFILEREMOVED:
for (my $loop= $::opt_sleep_time_for_delete; $loop; $loop--)
{
my $pidsockfiles_left= 0;
foreach my $srv ( @$spec )
{
if ( -e $srv->{'sockfile'} or -f $srv->{'pidfile'} )
{
$pidsockfiles_left++; # Could be that pidfile is left
}
}
if ( ! $pidsockfiles_left )
{
last PIDSOCKFILEREMOVED;
}
mtr_debug("Sleep for 1 second waiting for pid and socket file removal");
sleep(1); # One second
}
# ----------------------------------------------------------------------
# If no known PIDs, we have nothing more to try
# ----------------------------------------------------------------------
if ( ! $any_pid )
{
stop_reap_all();
return;
}
# ----------------------------------------------------------------------
# We may have killed all that left a socket, but we are not sure we got
# them all killed. If we suspect it lives, try nice kill with SIG_TERM.
# Note that for true Win32 processes, kill(0,$pid) will not return 1.
# ----------------------------------------------------------------------
SIGNAL:
foreach my $sig (15,9)
{
my $process_left= 0;
foreach my $srv ( @$spec )
{
if ( $srv->{'pid'} and
( -f $srv->{'pidfile'} or kill(0,$srv->{'pid'}) ) )
{
$process_left++;
mtr_warning("process $srv->{'pid'} not cooperating, " .
"will send signal $sig to process");
kill($sig,$srv->{'pid'}); # SIG_TERM
}
if ( ! $process_left )
{
last SIGNAL;
}
}
mtr_debug("Sleep for 5 seconds waiting for processes to die");
sleep(5); # We wait longer than usual
}
# ----------------------------------------------------------------------
# Now, we check if all we can find using kill(0,$pid) are dead,
# and just assume the rest are. We cleanup socket and PID files.
# ----------------------------------------------------------------------
{
my $errors= 0;
foreach my $srv ( @$spec )
{
if ( $srv->{'pid'} )
{
if ( kill(0,$srv->{'pid'}) )
{
# FIXME In Cygwin there seem to be some fast reuse
# of PIDs, so dying may not be the right thing to do.
$errors++;
mtr_warning("can't kill process $srv->{'pid'}");
}
else
{
# We managed to kill it at last
# FIXME In Cygwin, we will get here even if the process lives.
# Not needed as we know the process is dead, but to be safe
# we unlink and check success in two steps. We first unlink
# without checking the error code, and then check if the
# file still exists.
foreach my $file ($srv->{'pidfile'}, $srv->{'sockfile'})
{
unlink($file);
if ( -e $file )
{
$errors++;
mtr_warning("couldn't delete $file");
}
}
}
}
}
if ( $errors )
{
# We are in trouble, just die....
mtr_error("we could not kill or clean up all processes");
}
}
stop_reap_all();
# FIXME We just assume they are all dead, we don't know....
}
sub start_reap_all {
$SIG{CHLD}= 'IGNORE'; # FIXME is this enough?
}
sub stop_reap_all {
$SIG{CHLD}= 'DEFAULT';
}
1;

View File

@ -0,0 +1,262 @@
# -*- 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 strict;
sub mtr_report_test_name($);
sub mtr_report_test_passed($);
sub mtr_report_test_failed($);
sub mtr_report_test_skipped($);
sub mtr_show_failed_diff ($);
sub mtr_report_stats ($);
sub mtr_print_line ();
sub mtr_print_thick_line ();
sub mtr_print_header ();
sub mtr_report (@);
sub mtr_warning (@);
sub mtr_error (@);
sub mtr_debug (@);
##############################################################################
#
#
#
##############################################################################
# We can't use diff -u or diff -a as these are not portable
sub mtr_show_failed_diff ($) {
my $tname= shift;
my $reject_file= "r/$tname.reject";
my $result_file= "r/$tname.result";
my $eval_file= "r/$tname.eval";
if ( -f $eval_file )
{
$result_file= $eval_file;
}
elsif ( $::opt_result_ext and
( $::opt_record or -f "$result_file$::opt_result_ext" ))
{
# If we have an special externsion for result files we use it if we are
# recording or a result file with that extension exists.
$result_file= "$result_file$::opt_result_ext";
}
if ( -f $reject_file )
{
print "Below are the diffs between actual and expected results:\n";
print "-------------------------------------------------------\n";
# FIXME check result code?!
mtr_run("diff",["-c",$result_file,$reject_file], "", "", "", "");
print "-------------------------------------------------------\n";
print "Please follow the instructions outlined at\n";
print "http://www.mysql.com/doc/en/Reporting_mysqltest_bugs.html\n";
print "to find the reason to this problem and how to report this.\n\n";
}
}
sub mtr_report_test_name ($) {
my $tinfo= shift;
printf "%-31s ", $tinfo->{'name'};
}
sub mtr_report_test_skipped ($) {
my $tinfo= shift;
$tinfo->{'result'}= 'MTR_RES_SKIPPED';
print "[ skipped ]\n";
}
sub mtr_report_test_passed ($) {
my $tinfo= shift;
my $timer= "";
# FIXME
# if ( $::opt_timer and -f "$::glob_mysql_test_dir/var/log/timer" )
# {
# $timer= `cat var/log/timer`;
# $timer= sprintf "%13s", $timer;
# }
$tinfo->{'result'}= 'MTR_RES_PASSED';
print "[ pass ] $timer\n";
}
sub mtr_report_test_failed ($) {
my $tinfo= shift;
$tinfo->{'result'}= 'MTR_RES_FAILED';
print "[ fail ]\n";
print "Errors are (from $::path_timefile) :\n";
print mtr_fromfile($::path_timefile); # FIXME print_file() instead
print "\n(the last lines may be the most important ones)\n";
}
sub mtr_report_stats ($) {
my $tests= shift;
# ----------------------------------------------------------------------
# Find out how we where doing
# ----------------------------------------------------------------------
my $tot_skiped= 0;
my $tot_passed= 0;
my $tot_failed= 0;
my $tot_tests= 0;
foreach my $tinfo (@$tests)
{
if ( $tinfo->{'result'} eq 'MTR_RES_SKIPPED' )
{
$tot_skiped++;
}
elsif ( $tinfo->{'result'} eq 'MTR_RES_PASSED' )
{
$tot_tests++;
$tot_passed++;
}
elsif ( $tinfo->{'result'} eq 'MTR_RES_FAILED' )
{
$tot_tests++;
$tot_failed++;
}
}
# ----------------------------------------------------------------------
# Print out a summary report to screen
# ----------------------------------------------------------------------
if ( ! $tot_failed )
{
print "All $tot_tests tests were successful.\n";
}
else
{
my $ratio= $tot_passed * 100 / $tot_tests;
printf "Failed $tot_failed/$tot_tests tests, " .
"%.2f\% successful.\n\n", $ratio;
print
"The log files in var/log may give you some hint\n",
"of what when wrong.\n",
"If you want to report this error, please read first ",
"the documentation at\n",
"http://www.mysql.com/doc/en/MySQL_test_suite.html\n";
}
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
if ( ! $::glob_use_running_server )
{
# Report if there was any fatal warnings/errors in the log files
#
unlink("$::glob_mysql_test_dir/var/log/warnings");
unlink("$::glob_mysql_test_dir/var/log/warnings.tmp");
# Remove some non fatal warnings from the log files
# FIXME what is going on ????? ;-)
# sed -e 's!Warning: Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' \
# var/log/*.err \
# | sed -e 's!Warning: Table:.* on rename!!g' \
# > var/log/warnings.tmp;
#
# found_error=0;
# # Find errors
# for i in "^Warning:" "^Error:" "^==.* at 0x"
# do
# if ( $GREP "$i" var/log/warnings.tmp >> var/log/warnings )
# {
# found_error=1
# }
# done
# unlink("$::glob_mysql_test_dir/var/log/warnings.tmp");
# if ( $found_error= "1" )
# {
# print "WARNING: Got errors/warnings while running tests. Please examine\n"
# print "$::glob_mysql_test_dir/var/log/warnings for details.\n"
# }
# }
}
print "\n";
if ( $tot_failed != 0 )
{
print "mysql-test-run: *** Failing the test(s):";
foreach my $tinfo (@$tests)
{
if ( $tinfo->{'result'} eq 'MTR_RES_FAILED' )
{
print " $tinfo->{'name'}";
}
}
print "\n";
mtr_error("there where failing test cases");
}
}
##############################################################################
#
# Text formatting
#
##############################################################################
sub mtr_print_line () {
print '-' x 55, "\n";
}
sub mtr_print_thick_line () {
print '=' x 55, "\n";
}
sub mtr_print_header () {
print "\n";
if ( $::opt_timer )
{
print "TEST RESULT TIME (ms)\n";
}
else
{
print "TEST RESULT\n";
}
mtr_print_line();
print "\n";
}
##############################################################################
#
# Misc
#
##############################################################################
sub mtr_report (@) {
print join(" ", @_),"\n";
}
sub mtr_warning (@) {
print STDERR "mysql-test-run: WARNING: ",join(" ", @_),"\n";
}
sub mtr_error (@) {
die "mysql-test-run: *** ERROR: ",join(" ", @_),"\n";
}
sub mtr_debug (@) {
if ( $::opt_script_debug )
{
print STDERR "####: ",join(" ", @_),"\n";
}
}
1;

2182
mysql-test/mysql-test-run.pl Executable file

File diff suppressed because it is too large Load Diff

View File

@ -178,3 +178,12 @@ aaa aa
aab aa aab aa
aac aa aac aa
DROP TABLE t1; DROP TABLE t1;
select date_add(cast('2004-12-30 12:00:00' as date), interval 0 hour);
date_add(cast('2004-12-30 12:00:00' as date), interval 0 hour)
2004-12-30 00:00:00
select timediff(cast('2004-12-30 12:00:00' as time), '12:00:00');
timediff(cast('2004-12-30 12:00:00' as time), '12:00:00')
00:00:00
select timediff(cast('1 12:00:00' as time), '12:00:00');
timediff(cast('1 12:00:00' as time), '12:00:00')
24:00:00

View File

@ -63,8 +63,4 @@ a0
select 'a' union select concat('a', -0.0); select 'a' union select concat('a', -0.0);
a a
a a
a0.0 good
select 'a' union select concat('a', -0.0000);
a
a
a0.0000

View File

@ -474,12 +474,15 @@ unix_timestamp(@a)
select unix_timestamp('1969-12-01 19:00:01'); select unix_timestamp('1969-12-01 19:00:01');
unix_timestamp('1969-12-01 19:00:01') unix_timestamp('1969-12-01 19:00:01')
0 0
select from_unixtime(0); select from_unixtime(-1);
from_unixtime(0) from_unixtime(-1)
NULL NULL
select from_unixtime(2145916800); select from_unixtime(2145916800);
from_unixtime(2145916800) from_unixtime(2145916800)
NULL NULL
select from_unixtime(0);
from_unixtime(0)
1970-01-01 03:00:00
CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time); CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time);
INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08"); INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08");
SELECT * from t1; SELECT * from t1;

View File

@ -3026,7 +3026,7 @@ c1 c13 c14 c15 c16 c17
42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
51 0010-00-00 0010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL 60 NULL NULL 1991-01-01 01:01:01 NULL NULL

View File

@ -3009,7 +3009,7 @@ c1 c13 c14 c15 c16 c17
42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
51 0010-00-00 0010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL 60 NULL NULL 1991-01-01 01:01:01 NULL NULL

View File

@ -3010,7 +3010,7 @@ c1 c13 c14 c15 c16 c17
42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
51 0010-00-00 0010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL 60 NULL NULL 1991-01-01 01:01:01 NULL NULL

View File

@ -2946,7 +2946,7 @@ c1 c13 c14 c15 c16 c17
42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
51 0010-00-00 0010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL 60 NULL NULL 1991-01-01 01:01:01 NULL NULL
@ -5955,7 +5955,7 @@ c1 c13 c14 c15 c16 c17
42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
51 0010-00-00 0010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL 60 NULL NULL 1991-01-01 01:01:01 NULL NULL

View File

@ -3009,7 +3009,7 @@ c1 c13 c14 c15 c16 c17
42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
51 0010-00-00 0010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL 60 NULL NULL 1991-01-01 01:01:01 NULL NULL

View File

@ -3009,7 +3009,7 @@ c1 c13 c14 c15 c16 c17
42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
51 0010-00-00 0010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000 53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL 60 NULL NULL 1991-01-01 01:01:01 NULL NULL

View File

@ -143,3 +143,13 @@ t
0000-00-00 00:00:00 0000-00-00 00:00:00
2003-01-01 00:00:00 2003-01-01 00:00:00
drop table t1; drop table t1;
create table t1 (dt datetime);
insert into t1 values ("12-00-00"), ("00-00-00 01:00:00");
insert into t1 values ("00-00-00"), ("00-00-00 00:00:00");
select * from t1;
dt
2012-00-00 00:00:00
2000-00-00 01:00:00
0000-00-00 00:00:00
0000-00-00 00:00:00
drop table t1;

View File

@ -108,3 +108,13 @@ SELECT a, CAST(a AS CHAR(3)) FROM t1 ORDER BY CAST(a AS CHAR(2)), a;
SELECT a, CAST(a AS UNSIGNED) FROM t1 ORDER BY CAST(a AS CHAR) ; SELECT a, CAST(a AS UNSIGNED) FROM t1 ORDER BY CAST(a AS CHAR) ;
SELECT a, CAST(a AS CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a; SELECT a, CAST(a AS CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a;
DROP TABLE t1; DROP TABLE t1;
#
# Test for bug #6914 "Problems using time()/date() output in expressions".
# When we are casting datetime value to DATE/TIME we should throw away
# time/date parts (correspondingly).
#
select date_add(cast('2004-12-30 12:00:00' as date), interval 0 hour);
select timediff(cast('2004-12-30 12:00:00' as time), '12:00:00');
# Still we should not throw away "days" part of time value
select timediff(cast('1 12:00:00' as time), '12:00:00');

View File

@ -231,10 +231,14 @@ select unix_timestamp('1969-12-01 19:00:01');
# #
# Test for bug #6439 "unix_timestamp() function returns wrong datetime # Test for bug #6439 "unix_timestamp() function returns wrong datetime
# values for too big argument". It should return error instead. # values for too big argument" and bug #7515 "from_unixtime(0) now
# returns NULL instead of the epoch". unix_timestamp() should return error
# for too big or negative argument. It should return Epoch value for zero
# argument since it seems that many user's rely on this fact.
# #
select from_unixtime(0); select from_unixtime(-1);
select from_unixtime(2145916800); select from_unixtime(2145916800);
select from_unixtime(0);
# #
# Test types from + INTERVAL # Test types from + INTERVAL

View File

@ -6,9 +6,9 @@
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
drop database if exists mysqltest; drop database if exists mysqltest;
drop view if exists v1; drop view if exists v1;
--error 0,1141 --error 0,1141,1147
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
--error 0,1141 --error 0,1141,1147
revoke all privileges on mysqltest.* from mysqltest_1@localhost; revoke all privileges on mysqltest.* from mysqltest_1@localhost;
delete from mysql.user where user=_binary'mysqltest_1'; delete from mysql.user where user=_binary'mysqltest_1';
--enable_warnings --enable_warnings

View File

@ -89,3 +89,15 @@ delete from t1;
insert into t1 values ("0000-00-00 00:00:00 some trailer"),("2003-01-01 00:00:00 some trailer"); insert into t1 values ("0000-00-00 00:00:00 some trailer"),("2003-01-01 00:00:00 some trailer");
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Test for bug #7297 "Two digit year should be interpreted correctly even
# with zero month and day"
#
create table t1 (dt datetime);
# These dates should be treated as dates in 21st century
insert into t1 values ("12-00-00"), ("00-00-00 01:00:00");
# Zero dates are still special :/
insert into t1 values ("00-00-00"), ("00-00-00 00:00:00");
select * from t1;
drop table t1;

View File

@ -382,8 +382,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
} }
l_time->neg= 0; l_time->neg= 0;
if (year_length == 2 && i >= format_position[1] && i >=format_position[2] && if (year_length == 2 && not_zero_date)
(l_time->month || l_time->day))
l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900);
if (!not_zero_date && (flags & TIME_NO_ZERO_DATE)) if (!not_zero_date && (flags & TIME_NO_ZERO_DATE))

View File

@ -2683,7 +2683,7 @@ void ha_ndbcluster::info(uint flag)
if ((my_errno= check_ndb_connection())) if ((my_errno= check_ndb_connection()))
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
Ndb *ndb= get_ndb(); Ndb *ndb= get_ndb();
Uint64 rows; Uint64 rows= 100;
if (current_thd->variables.ndb_use_exact_count) if (current_thd->variables.ndb_use_exact_count)
ndb_get_table_statistics(ndb, m_tabname, &rows, 0); ndb_get_table_statistics(ndb, m_tabname, &rows, 0);
records= rows; records= rows;

View File

@ -1603,6 +1603,7 @@ void Item_func_from_unixtime::fix_length_and_dec()
collation.set(&my_charset_bin); collation.set(&my_charset_bin);
decimals=0; decimals=0;
max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null= 1;
thd->time_zone_used= 1; thd->time_zone_used= 1;
} }
@ -1642,11 +1643,12 @@ longlong Item_func_from_unixtime::val_int()
bool Item_func_from_unixtime::get_date(TIME *ltime, bool Item_func_from_unixtime::get_date(TIME *ltime,
uint fuzzy_date __attribute__((unused))) uint fuzzy_date __attribute__((unused)))
{ {
longlong tmp= args[0]->val_int(); ulonglong tmp= (ulonglong)(args[0]->val_int());
/*
if ((null_value= (args[0]->null_value || "tmp > TIMESTAMP_MAX_VALUE" check also covers case of negative
tmp < TIMESTAMP_MIN_VALUE || from_unixtime() argument since tmp is unsigned.
tmp > TIMESTAMP_MAX_VALUE))) */
if ((null_value= (args[0]->null_value || tmp > TIMESTAMP_MAX_VALUE)))
return 1; return 1;
thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)tmp); thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)tmp);
@ -2202,6 +2204,12 @@ String *Item_datetime_typecast::val_str(String *str)
bool Item_time_typecast::get_time(TIME *ltime) bool Item_time_typecast::get_time(TIME *ltime)
{ {
bool res= get_arg0_time(ltime); bool res= get_arg0_time(ltime);
/*
For MYSQL_TIMESTAMP_TIME value we can have non-zero day part,
which we should not lose.
*/
if (ltime->time_type == MYSQL_TIMESTAMP_DATETIME)
ltime->year= ltime->month= ltime->day= 0;
ltime->time_type= MYSQL_TIMESTAMP_TIME; ltime->time_type= MYSQL_TIMESTAMP_TIME;
return res; return res;
} }
@ -2225,6 +2233,7 @@ String *Item_time_typecast::val_str(String *str)
bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date) bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date)
{ {
bool res= get_arg0_date(ltime, TIME_FUZZY_DATE); bool res= get_arg0_date(ltime, TIME_FUZZY_DATE);
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
ltime->time_type= MYSQL_TIMESTAMP_DATE; ltime->time_type= MYSQL_TIMESTAMP_DATE;
return res; return res;
} }

View File

@ -2128,7 +2128,7 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
const char *db_arg, const char *table_name_arg, const char *db_arg, const char *table_name_arg,
List<Item> &fields_arg, List<Item> &fields_arg,
enum enum_duplicates handle_dup, enum enum_duplicates handle_dup,
bool using_trans) bool ignore, bool using_trans)
:Log_event(thd_arg, !thd_arg->tmp_table_used ? :Log_event(thd_arg, !thd_arg->tmp_table_used ?
0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans),
thread_id(thd_arg->thread_id), thread_id(thd_arg->thread_id),
@ -2166,9 +2166,6 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
sql_ex.empty_flags= 0; sql_ex.empty_flags= 0;
switch (handle_dup) { switch (handle_dup) {
case DUP_IGNORE:
sql_ex.opt_flags|= IGNORE_FLAG;
break;
case DUP_REPLACE: case DUP_REPLACE:
sql_ex.opt_flags|= REPLACE_FLAG; sql_ex.opt_flags|= REPLACE_FLAG;
break; break;
@ -2176,6 +2173,8 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
case DUP_ERROR: case DUP_ERROR:
break; break;
} }
if (ignore)
sql_ex.opt_flags|= IGNORE_FLAG;
if (!ex->field_term->length()) if (!ex->field_term->length())
sql_ex.empty_flags |= FIELD_TERM_EMPTY; sql_ex.empty_flags |= FIELD_TERM_EMPTY;
@ -2511,6 +2510,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
{ {
char llbuff[22]; char llbuff[22];
enum enum_duplicates handle_dup; enum enum_duplicates handle_dup;
bool ignore= 0;
/* /*
Make a simplified LOAD DATA INFILE query, for the information of the Make a simplified LOAD DATA INFILE query, for the information of the
user in SHOW PROCESSLIST. Note that db is known in the 'db' column. user in SHOW PROCESSLIST. Note that db is known in the 'db' column.
@ -2527,21 +2527,24 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
if (sql_ex.opt_flags & REPLACE_FLAG) if (sql_ex.opt_flags & REPLACE_FLAG)
handle_dup= DUP_REPLACE; handle_dup= DUP_REPLACE;
else if (sql_ex.opt_flags & IGNORE_FLAG) else if (sql_ex.opt_flags & IGNORE_FLAG)
handle_dup= DUP_IGNORE; {
ignore= 1;
handle_dup= DUP_ERROR;
}
else else
{ {
/* /*
When replication is running fine, if it was DUP_ERROR on the When replication is running fine, if it was DUP_ERROR on the
master then we could choose DUP_IGNORE here, because if DUP_ERROR master then we could choose IGNORE here, because if DUP_ERROR
suceeded on master, and data is identical on the master and slave, suceeded on master, and data is identical on the master and slave,
then there should be no uniqueness errors on slave, so DUP_IGNORE is then there should be no uniqueness errors on slave, so IGNORE is
the same as DUP_ERROR. But in the unlikely case of uniqueness errors the same as DUP_ERROR. But in the unlikely case of uniqueness errors
(because the data on the master and slave happen to be different (because the data on the master and slave happen to be different
(user error or bug), we want LOAD DATA to print an error message on (user error or bug), we want LOAD DATA to print an error message on
the slave to discover the problem. the slave to discover the problem.
If reading from net (a 3.23 master), mysql_load() will change this If reading from net (a 3.23 master), mysql_load() will change this
to DUP_IGNORE. to IGNORE.
*/ */
handle_dup= DUP_ERROR; handle_dup= DUP_ERROR;
} }
@ -2575,7 +2578,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
*/ */
thd->net.pkt_nr = net->pkt_nr; thd->net.pkt_nr = net->pkt_nr;
} }
if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0, if (mysql_load(thd, &ex, &tables, field_list, handle_dup, ignore, net != 0,
TL_WRITE, 0)) TL_WRITE, 0))
thd->query_error = 1; thd->query_error = 1;
if (thd->cuted_fields) if (thd->cuted_fields)
@ -3495,8 +3498,9 @@ Create_file_log_event::
Create_file_log_event(THD* thd_arg, sql_exchange* ex, Create_file_log_event(THD* thd_arg, sql_exchange* ex,
const char* db_arg, const char* table_name_arg, const char* db_arg, const char* table_name_arg,
List<Item>& fields_arg, enum enum_duplicates handle_dup, List<Item>& fields_arg, enum enum_duplicates handle_dup,
bool ignore,
char* block_arg, uint block_len_arg, bool using_trans) char* block_arg, uint block_len_arg, bool using_trans)
:Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
using_trans), using_trans),
fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg), fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
file_id(thd_arg->file_id = mysql_bin_log.next_file_id()) file_id(thd_arg->file_id = mysql_bin_log.next_file_id())

View File

@ -783,7 +783,7 @@ public:
Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg, Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
const char* table_name_arg, const char* table_name_arg,
List<Item>& fields_arg, enum enum_duplicates handle_dup, List<Item>& fields_arg, enum enum_duplicates handle_dup, bool ignore,
bool using_trans); bool using_trans);
void set_fields(const char* db, List<Item> &fields_arg); void set_fields(const char* db, List<Item> &fields_arg);
const char* get_db() { return db; } const char* get_db() { return db; }
@ -1170,7 +1170,7 @@ public:
Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg, Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
const char* table_name_arg, const char* table_name_arg,
List<Item>& fields_arg, List<Item>& fields_arg,
enum enum_duplicates handle_dup, enum enum_duplicates handle_dup, bool ignore,
char* block_arg, uint block_len_arg, char* block_arg, uint block_len_arg,
bool using_trans); bool using_trans);
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION

View File

@ -613,6 +613,7 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
List<Key> &keys, List<Key> &keys,
uint order_num, ORDER *order, uint order_num, ORDER *order,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
bool ignore,
ALTER_INFO *alter_info, bool do_send_ok=1); ALTER_INFO *alter_info, bool do_send_ok=1);
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
bool mysql_create_like_table(THD *thd, TABLE_LIST *table, bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
@ -631,11 +632,11 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &values,COND *conds, List<Item> &values,COND *conds,
uint order_num, ORDER *order, ha_rows limit, uint order_num, ORDER *order, ha_rows limit,
enum enum_duplicates handle_duplicates); enum enum_duplicates handle_duplicates, bool ignore);
bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, bool mysql_multi_update(THD *thd, TABLE_LIST *table_list,
List<Item> *fields, List<Item> *values, List<Item> *fields, List<Item> *values,
COND *conds, ulong options, COND *conds, ulong options,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates, bool ignore,
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex);
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
List<Item> &fields, List_item *values, List<Item> &fields, List_item *values,
@ -644,7 +645,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
COND **where, bool select_insert); COND **where, bool select_insert);
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields, List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag); List<Item> &update_values, enum_duplicates flag,
bool ignore);
int check_that_all_fields_are_given_values(THD *thd, TABLE *entry); int check_that_all_fields_are_given_values(THD *thd, TABLE *entry);
bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
bool mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order, bool mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order,
@ -882,8 +884,7 @@ bool eval_const_cond(COND *cond);
/* sql_load.cc */ /* sql_load.cc */
bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list, bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates, List<Item> &fields, enum enum_duplicates handle_duplicates,
bool local_file, thr_lock_type lock_type, bool ignore, bool local_file, thr_lock_type lock_type);
bool ignore_check_option_errors);
int write_record(THD *thd, TABLE *table, COPY_INFO *info); int write_record(THD *thd, TABLE *table, COPY_INFO *info);
/* sql_manager.cc */ /* sql_manager.cc */

View File

@ -3054,7 +3054,7 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
enum db_type db_type; enum db_type db_type;
if (!(res=var->value->val_str(&str)) || if (!(res=var->value->val_str(&str)) ||
!(var->save_result.ulong_value= !(var->save_result.ulong_value=
(ulong) db_type= ha_resolve_by_name(res->ptr(), res->length())) || (ulong) (db_type= ha_resolve_by_name(res->ptr(), res->length()))) ||
ha_checktype(db_type) != db_type) ha_checktype(db_type) != db_type)
{ {
value= res ? res->c_ptr() : "NULL"; value= res ? res->c_ptr() : "NULL";

View File

@ -32,7 +32,7 @@ class sp_cache;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME }; enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE, DUP_UPDATE }; enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN}; enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN};
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
DELAY_KEY_WRITE_ALL }; DELAY_KEY_WRITE_ALL };
@ -225,7 +225,8 @@ typedef struct st_copy_info {
ha_rows error_count; ha_rows error_count;
enum enum_duplicates handle_duplicates; enum enum_duplicates handle_duplicates;
int escape_char, last_errno; int escape_char, last_errno;
/* for INSERT ... UPDATE */ bool ignore;
/* for INSERT ... UPDATE */
List<Item> *update_fields; List<Item> *update_fields;
List<Item> *update_values; List<Item> *update_values;
/* for VIEW ... WITH CHECK OPTION */ /* for VIEW ... WITH CHECK OPTION */
@ -1375,8 +1376,7 @@ class select_insert :public select_result_interceptor {
select_insert(TABLE_LIST *table_list_par, select_insert(TABLE_LIST *table_list_par,
TABLE *table_par, List<Item> *fields_par, TABLE *table_par, List<Item> *fields_par,
List<Item> *update_fields, List<Item> *update_values, List<Item> *update_fields, List<Item> *update_values,
enum_duplicates duplic, enum_duplicates duplic, bool ignore);
bool ignore_check_option_errors);
~select_insert(); ~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
@ -1401,8 +1401,8 @@ public:
HA_CREATE_INFO *create_info_par, HA_CREATE_INFO *create_info_par,
List<create_field> &fields_par, List<create_field> &fields_par,
List<Key> &keys_par, List<Key> &keys_par,
List<Item> &select_fields,enum_duplicates duplic) List<Item> &select_fields,enum_duplicates duplic, bool ignore)
:select_insert (NULL, NULL, &select_fields, 0, 0, duplic, 0), create_table(table), :select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore), create_table(table),
extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par), extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par),
lock(0) lock(0)
{} {}
@ -1673,12 +1673,12 @@ class multi_update :public select_result_interceptor
uint table_count; uint table_count;
Copy_field *copy_field; Copy_field *copy_field;
enum enum_duplicates handle_duplicates; enum enum_duplicates handle_duplicates;
bool do_update, trans_safe, transactional_tables, log_delayed; bool do_update, trans_safe, transactional_tables, log_delayed, ignore;
public: public:
multi_update(THD *thd_arg, TABLE_LIST *ut, TABLE_LIST *leaves_list, multi_update(THD *thd_arg, TABLE_LIST *ut, TABLE_LIST *leaves_list,
List<Item> *fields, List<Item> *values, List<Item> *fields, List<Item> *values,
enum_duplicates handle_duplicates); enum_duplicates handle_duplicates, bool ignore);
~multi_update(); ~multi_update();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);

View File

@ -68,8 +68,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
if (thd->lex->duplicates == DUP_IGNORE) select_lex->no_error= thd->lex->ignore;
select_lex->no_error= 1;
/* /*
Test if the user wants to delete all rows and deletion doesn't have Test if the user wants to delete all rows and deletion doesn't have

View File

@ -25,7 +25,7 @@
static int check_null_fields(THD *thd,TABLE *entry); static int check_null_fields(THD *thd,TABLE *entry);
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list); static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list);
static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, bool ignore,
char *query, uint query_length, bool log_on); char *query, uint query_length, bool log_on);
static void end_delayed_insert(THD *thd); static void end_delayed_insert(THD *thd);
extern "C" pthread_handler_decl(handle_delayed_insert,arg); extern "C" pthread_handler_decl(handle_delayed_insert,arg);
@ -158,7 +158,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
List<List_item> &values_list, List<List_item> &values_list,
List<Item> &update_fields, List<Item> &update_fields,
List<Item> &update_values, List<Item> &update_values,
enum_duplicates duplic) enum_duplicates duplic,
bool ignore)
{ {
int error, res; int error, res;
/* /*
@ -168,7 +169,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
*/ */
bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL)); bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL));
bool transactional_table, log_delayed; bool transactional_table, log_delayed;
bool ignore_err= (thd->lex->duplicates == DUP_IGNORE);
uint value_count; uint value_count;
ulong counter = 1; ulong counter = 1;
ulonglong id; ulonglong id;
@ -271,11 +271,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
*/ */
info.records= info.deleted= info.copied= info.updated= 0; info.records= info.deleted= info.copied= info.updated= 0;
info.ignore= ignore;
info.handle_duplicates=duplic; info.handle_duplicates=duplic;
info.update_fields=&update_fields; info.update_fields= &update_fields;
info.update_values=&update_values; info.update_values= &update_values;
info.view= (table_list->view ? table_list : 0); info.view= (table_list->view ? table_list : 0);
info.ignore= ignore_err;
/* /*
Count warnings for all inserts. Count warnings for all inserts.
For single line insert, generate an error if try to set a NOT NULL field For single line insert, generate an error if try to set a NOT NULL field
@ -366,7 +367,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if ((res= table_list->view_check_option(thd, if ((res= table_list->view_check_option(thd,
(values_list.elements == 1 ? (values_list.elements == 1 ?
0 : 0 :
ignore_err))) == ignore))) ==
VIEW_CHECK_SKIP) VIEW_CHECK_SKIP)
continue; continue;
else if (res == VIEW_CHECK_ERROR) else if (res == VIEW_CHECK_ERROR)
@ -377,7 +378,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED) if (lock_type == TL_WRITE_DELAYED)
{ {
error=write_delayed(thd,table,duplic,query, thd->query_length, log_on); error=write_delayed(thd, table, duplic, ignore, query, thd->query_length, log_on);
query=0; query=0;
} }
else else
@ -490,7 +491,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
else else
{ {
char buff[160]; char buff[160];
if (duplic == DUP_IGNORE) if (ignore)
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(lock_type == TL_WRITE_DELAYED) ? (ulong) 0 : (lock_type == TL_WRITE_DELAYED) ? (ulong) 0 :
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields); (ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
@ -851,7 +852,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
} }
else if ((error=table->file->write_row(table->record[0]))) else if ((error=table->file->write_row(table->record[0])))
{ {
if (info->handle_duplicates != DUP_IGNORE || if (!info->ignore ||
(error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)) (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE))
goto err; goto err;
table->file->restore_auto_increment(); table->file->restore_auto_increment();
@ -906,13 +907,13 @@ public:
char *record,*query; char *record,*query;
enum_duplicates dup; enum_duplicates dup;
time_t start_time; time_t start_time;
bool query_start_used,last_insert_id_used,insert_id_used, log_query; bool query_start_used,last_insert_id_used,insert_id_used, ignore, log_query;
ulonglong last_insert_id; ulonglong last_insert_id;
timestamp_auto_set_type timestamp_field_type; timestamp_auto_set_type timestamp_field_type;
uint query_length; uint query_length;
delayed_row(enum_duplicates dup_arg, bool log_query_arg) delayed_row(enum_duplicates dup_arg, bool ignore_arg, bool log_query_arg)
:record(0),query(0),dup(dup_arg),log_query(log_query_arg) {} :record(0), query(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg) {}
~delayed_row() ~delayed_row()
{ {
x_free(record); x_free(record);
@ -1224,7 +1225,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
/* Put a question in queue */ /* Put a question in queue */
static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, bool ignore,
char *query, uint query_length, bool log_on) char *query, uint query_length, bool log_on)
{ {
delayed_row *row=0; delayed_row *row=0;
@ -1237,7 +1238,7 @@ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic,
pthread_cond_wait(&di->cond_client,&di->mutex); pthread_cond_wait(&di->cond_client,&di->mutex);
thd->proc_info="storing row into queue"; thd->proc_info="storing row into queue";
if (thd->killed || !(row= new delayed_row(duplic, log_on))) if (thd->killed || !(row= new delayed_row(duplic, ignore, log_on)))
goto err; goto err;
if (!query) if (!query)
@ -1600,8 +1601,9 @@ bool delayed_insert::handle_inserts(void)
thd.insert_id_used=row->insert_id_used; thd.insert_id_used=row->insert_id_used;
table->timestamp_field_type= row->timestamp_field_type; table->timestamp_field_type= row->timestamp_field_type;
info.ignore= row->ignore;
info.handle_duplicates= row->dup; info.handle_duplicates= row->dup;
if (info.handle_duplicates == DUP_IGNORE || if (info.ignore ||
info.handle_duplicates == DUP_REPLACE) info.handle_duplicates == DUP_REPLACE)
{ {
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
@ -1803,7 +1805,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
restore_record(table,default_values); // Get empty record restore_record(table,default_values); // Get empty record
table->next_number_field=table->found_next_number_field; table->next_number_field=table->found_next_number_field;
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.handle_duplicates == DUP_IGNORE || if (info.ignore ||
info.handle_duplicates == DUP_REPLACE) info.handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
@ -1965,7 +1967,7 @@ bool select_insert::send_eof()
DBUG_RETURN(1); DBUG_RETURN(1);
} }
char buff[160]; char buff[160];
if (info.handle_duplicates == DUP_IGNORE) if (info.ignore)
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields); (ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
else else
@ -2008,7 +2010,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
restore_record(table,default_values); // Get empty record restore_record(table,default_values); // Get empty record
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.handle_duplicates == DUP_IGNORE || if (info.ignore ||
info.handle_duplicates == DUP_REPLACE) info.handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);

View File

@ -166,6 +166,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
lex->sql_command=SQLCOM_END; lex->sql_command=SQLCOM_END;
lex->duplicates= DUP_ERROR; lex->duplicates= DUP_ERROR;
lex->ignore= 0;
lex->sphead= NULL; lex->sphead= NULL;
lex->spcont= NULL; lex->spcont= NULL;
lex->proc_list.first= 0; lex->proc_list.first= 0;

View File

@ -721,7 +721,7 @@ typedef struct st_lex
/* special JOIN::prepare mode: changing of query is prohibited */ /* special JOIN::prepare mode: changing of query is prohibited */
bool view_prepare_mode; bool view_prepare_mode;
bool safe_to_cache_query; bool safe_to_cache_query;
bool subqueries; bool subqueries, ignore;
bool variables_used; bool variables_used;
ALTER_INFO alter_info; ALTER_INFO alter_info;
/* Prepared statements SQL syntax:*/ /* Prepared statements SQL syntax:*/

View File

@ -82,8 +82,8 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates, List<Item> &fields, enum enum_duplicates handle_duplicates,
bool read_file_from_client,thr_lock_type lock_type, bool ignore,
bool ignore_check_option_errors) bool read_file_from_client,thr_lock_type lock_type)
{ {
char name[FN_REFLEN]; char name[FN_REFLEN];
File file; File file;
@ -186,7 +186,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* We can't give an error in the middle when using LOCAL files */ /* We can't give an error in the middle when using LOCAL files */
if (read_file_from_client && handle_duplicates == DUP_ERROR) if (read_file_from_client && handle_duplicates == DUP_ERROR)
handle_duplicates=DUP_IGNORE; ignore= 1;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
if (read_file_from_client) if (read_file_from_client)
@ -237,6 +237,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
COPY_INFO info; COPY_INFO info;
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
info.ignore= ignore;
info.handle_duplicates=handle_duplicates; info.handle_duplicates=handle_duplicates;
info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX; info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
@ -258,6 +259,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
lf_info.db = db; lf_info.db = db;
lf_info.table_name = table_list->real_name; lf_info.table_name = table_list->real_name;
lf_info.fields = &fields; lf_info.fields = &fields;
lf_info.ignore= ignore;
lf_info.handle_dup = handle_duplicates; lf_info.handle_dup = handle_duplicates;
lf_info.wrote_create_file = 0; lf_info.wrote_create_file = 0;
lf_info.last_pos_in_file = HA_POS_ERROR; lf_info.last_pos_in_file = HA_POS_ERROR;
@ -288,7 +290,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
table->next_number_field=table->found_next_number_field; table->next_number_field=table->found_next_number_field;
if (handle_duplicates == DUP_IGNORE || if (ignore ||
handle_duplicates == DUP_REPLACE) handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
ha_enable_transaction(thd, FALSE); ha_enable_transaction(thd, FALSE);
@ -303,11 +305,11 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (!field_term->length() && !enclosed->length()) if (!field_term->length() && !enclosed->length())
error= read_fixed_length(thd, info, table_list, fields,read_info, error= read_fixed_length(thd, info, table_list, fields,read_info,
skip_lines, ignore_check_option_errors); skip_lines, ignore);
else else
error= read_sep_field(thd, info, table_list, fields, read_info, error= read_sep_field(thd, info, table_list, fields, read_info,
*enclosed, skip_lines, *enclosed, skip_lines,
ignore_check_option_errors); ignore);
if (table->file->end_bulk_insert()) if (table->file->end_bulk_insert())
error=1; /* purecov: inspected */ error=1; /* purecov: inspected */
ha_enable_transaction(thd, TRUE); ha_enable_transaction(thd, TRUE);
@ -485,9 +487,8 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
} }
switch(table_list->view_check_option(thd, switch (table_list->view_check_option(thd,
ignore_check_option_errors)) ignore_check_option_errors)) {
{
case VIEW_CHECK_SKIP: case VIEW_CHECK_SKIP:
read_info.next_line(); read_info.next_line();
goto continue_loop; goto continue_loop;
@ -607,9 +608,8 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
} }
} }
switch(table_list->view_check_option(thd, switch (table_list->view_check_option(thd,
ignore_check_option_errors)) ignore_check_option_errors)) {
{
case VIEW_CHECK_SKIP: case VIEW_CHECK_SKIP:
read_info.next_line(); read_info.next_line();
goto continue_loop; goto continue_loop;

View File

@ -2628,7 +2628,8 @@ mysql_execute_command(THD *thd)
lex->create_list, lex->create_list,
lex->key_list, lex->key_list,
select_lex->item_list, select_lex->item_list,
lex->duplicates))) lex->duplicates,
lex->ignore)))
{ {
/* /*
CREATE from SELECT give its SELECT_LEX for SELECT, CREATE from SELECT give its SELECT_LEX for SELECT,
@ -2768,7 +2769,7 @@ create_error:
lex->key_list, lex->key_list,
select_lex->order_list.elements, select_lex->order_list.elements,
(ORDER *) select_lex->order_list.first, (ORDER *) select_lex->order_list.first,
lex->duplicates, &lex->alter_info); lex->duplicates, lex->ignore, &lex->alter_info);
} }
break; break;
} }
@ -2933,7 +2934,7 @@ create_error:
select_lex->order_list.elements, select_lex->order_list.elements,
(ORDER *) select_lex->order_list.first, (ORDER *) select_lex->order_list.first,
select_lex->select_limit, select_lex->select_limit,
lex->duplicates)); lex->duplicates, lex->ignore));
/* mysql_update return 2 if we need to switch to multi-update */ /* mysql_update return 2 if we need to switch to multi-update */
if (result != 2) if (result != 2)
break; break;
@ -2954,7 +2955,7 @@ create_error:
&lex->value_list, &lex->value_list,
select_lex->where, select_lex->where,
select_lex->options, select_lex->options,
lex->duplicates, unit, select_lex); lex->duplicates, lex->ignore, unit, select_lex);
break; break;
} }
case SQLCOM_REPLACE: case SQLCOM_REPLACE:
@ -2965,8 +2966,7 @@ create_error:
break; break;
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values, res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
lex->update_list, lex->value_list, lex->update_list, lex->value_list,
(lex->value_list.elements ? lex->duplicates, lex->ignore);
DUP_UPDATE : lex->duplicates));
if (first_table->view && !first_table->contain_auto_increment) if (first_table->view && !first_table->contain_auto_increment)
thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it
break; break;
@ -2997,8 +2997,7 @@ create_error:
if (!res && (result= new select_insert(first_table, first_table->table, if (!res && (result= new select_insert(first_table, first_table->table,
&lex->field_list, &lex->field_list,
&lex->update_list, &lex->value_list, &lex->update_list, &lex->value_list,
lex->duplicates, lex->duplicates, lex->ignore)))
lex->duplicates == DUP_IGNORE)))
{ {
/* /*
insert/replace from SELECT give its SELECT_LEX for SELECT, insert/replace from SELECT give its SELECT_LEX for SELECT,
@ -3194,8 +3193,8 @@ create_error:
goto error; goto error;
} }
res= mysql_load(thd, lex->exchange, first_table, lex->field_list, res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
lex->duplicates, (bool) lex->local_file, lex->duplicates, lex->ignore, (bool) lex->local_file,
lex->lock_option, lex->duplicates == DUP_IGNORE); lex->lock_option);
break; break;
} }
@ -6043,7 +6042,7 @@ bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list, &create_info, table_list,
fields, keys, 0, (ORDER*)0, fields, keys, 0, (ORDER*)0,
DUP_ERROR, &alter_info)); DUP_ERROR, 0, &alter_info));
} }
@ -6061,7 +6060,7 @@ bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info)
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list, &create_info, table_list,
fields, keys, 0, (ORDER*)0, fields, keys, 0, (ORDER*)0,
DUP_ERROR, alter_info)); DUP_ERROR, 0, alter_info));
} }

View File

@ -1510,7 +1510,7 @@ err:
int log_loaded_block(IO_CACHE* file) int log_loaded_block(IO_CACHE* file)
{ {
LOAD_FILE_INFO* lf_info; LOAD_FILE_INFO *lf_info;
uint block_len ; uint block_len ;
/* file->request_pos contains position where we started last read */ /* file->request_pos contains position where we started last read */
@ -1532,7 +1532,7 @@ int log_loaded_block(IO_CACHE* file)
{ {
Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db, Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
lf_info->table_name, *lf_info->fields, lf_info->table_name, *lf_info->fields,
lf_info->handle_dup, buffer, lf_info->handle_dup, lf_info->ignore, buffer,
block_len, lf_info->log_delayed); block_len, lf_info->log_delayed);
mysql_bin_log.write(&c); mysql_bin_log.write(&c);
lf_info->wrote_create_file = 1; lf_info->wrote_create_file = 1;

View File

@ -67,7 +67,7 @@ typedef struct st_load_file_info
enum enum_duplicates handle_dup; enum enum_duplicates handle_dup;
char* db; char* db;
char* table_name; char* table_name;
bool wrote_create_file, log_delayed; bool wrote_create_file, log_delayed, ignore;
} LOAD_FILE_INFO; } LOAD_FILE_INFO;
int log_loaded_block(IO_CACHE* file); int log_loaded_block(IO_CACHE* file);

View File

@ -529,7 +529,7 @@ JOIN::optimize()
optimized= 1; optimized= 1;
// Ignore errors of execution if option IGNORE present // Ignore errors of execution if option IGNORE present
if (thd->lex->duplicates == DUP_IGNORE) if (thd->lex->ignore)
thd->lex->current_select->no_error= 1; thd->lex->current_select->no_error= 1;
#ifdef HAVE_REF_TO_FIELDS // Not done yet #ifdef HAVE_REF_TO_FIELDS // Not done yet
/* Add HAVING to WHERE if possible */ /* Add HAVING to WHERE if possible */

View File

@ -36,6 +36,7 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
static int copy_data_between_tables(TABLE *from,TABLE *to, static int copy_data_between_tables(TABLE *from,TABLE *to,
List<create_field> &create, List<create_field> &create,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
bool ignore,
uint order_num, ORDER *order, uint order_num, ORDER *order,
ha_rows *copied,ha_rows *deleted); ha_rows *copied,ha_rows *deleted);
@ -2806,7 +2807,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
TABLE_LIST *table_list, TABLE_LIST *table_list,
List<create_field> &fields, List<Key> &keys, List<create_field> &fields, List<Key> &keys,
uint order_num, ORDER *order, uint order_num, ORDER *order,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates, bool ignore,
ALTER_INFO *alter_info, bool do_send_ok) ALTER_INFO *alter_info, bool do_send_ok)
{ {
TABLE *table,*new_table=0; TABLE *table,*new_table=0;
@ -3348,7 +3349,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
new_table->next_number_field=new_table->found_next_number_field; new_table->next_number_field=new_table->found_next_number_field;
error=copy_data_between_tables(table,new_table,create_list, error=copy_data_between_tables(table,new_table,create_list,
handle_duplicates, handle_duplicates, ignore,
order_num, order, &copied, &deleted); order_num, order, &copied, &deleted);
} }
thd->last_insert_id=next_insert_id; // Needed for correct log thd->last_insert_id=next_insert_id; // Needed for correct log
@ -3567,6 +3568,7 @@ static int
copy_data_between_tables(TABLE *from,TABLE *to, copy_data_between_tables(TABLE *from,TABLE *to,
List<create_field> &create, List<create_field> &create,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
bool ignore,
uint order_num, ORDER *order, uint order_num, ORDER *order,
ha_rows *copied, ha_rows *copied,
ha_rows *deleted) ha_rows *deleted)
@ -3660,7 +3662,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
current query id */ current query id */
from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1); init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
if (handle_duplicates == DUP_IGNORE || if (ignore ||
handle_duplicates == DUP_REPLACE) handle_duplicates == DUP_REPLACE)
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->row_count= 0; thd->row_count= 0;
@ -3686,7 +3688,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
} }
if ((error=to->file->write_row((byte*) to->record[0]))) if ((error=to->file->write_row((byte*) to->record[0])))
{ {
if ((handle_duplicates != DUP_IGNORE && if ((!ignore &&
handle_duplicates != DUP_REPLACE) || handle_duplicates != DUP_REPLACE) ||
(error != HA_ERR_FOUND_DUPP_KEY && (error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE)) error != HA_ERR_FOUND_DUPP_UNIQUE))
@ -3764,7 +3766,7 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info, DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
table_list, lex->create_list, table_list, lex->create_list,
lex->key_list, 0, (ORDER *) 0, lex->key_list, 0, (ORDER *) 0,
DUP_ERROR, &lex->alter_info, do_send_ok)); DUP_ERROR, 0, &lex->alter_info, do_send_ok));
} }

View File

@ -51,10 +51,10 @@ select_union::select_union(TABLE *table_par)
{ {
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
/* /*
We can always use DUP_IGNORE because the temporary table will only We can always use IGNORE because the temporary table will only
contain a unique key if we are using not using UNION ALL contain a unique key if we are using not using UNION ALL
*/ */
info.handle_duplicates= DUP_IGNORE; info.ignore= 1;
} }
select_union::~select_union() select_union::~select_union()

View File

@ -113,7 +113,7 @@ int mysql_update(THD *thd,
COND *conds, COND *conds,
uint order_num, ORDER *order, uint order_num, ORDER *order,
ha_rows limit, ha_rows limit,
enum enum_duplicates handle_duplicates) enum enum_duplicates handle_duplicates, bool ignore)
{ {
bool using_limit= limit != HA_POS_ERROR; bool using_limit= limit != HA_POS_ERROR;
bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool safe_update= thd->options & OPTION_SAFE_UPDATES;
@ -380,7 +380,7 @@ int mysql_update(THD *thd,
} }
} }
if (handle_duplicates == DUP_IGNORE) if (ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (select && select->quick && select->quick->reset()) if (select && select->quick && select->quick->reset())
@ -433,8 +433,7 @@ int mysql_update(THD *thd,
updated++; updated++;
thd->no_trans_update= !transactional_table; thd->no_trans_update= !transactional_table;
} }
else if (handle_duplicates != DUP_IGNORE || else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
error != HA_ERR_FOUND_DUPP_KEY)
{ {
thd->fatal_error(); // Force error message thd->fatal_error(); // Force error message
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
@ -812,7 +811,7 @@ bool mysql_multi_update(THD *thd,
List<Item> *values, List<Item> *values,
COND *conds, COND *conds,
ulong options, ulong options,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates, bool ignore,
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
{ {
bool res= FALSE; bool res= FALSE;
@ -825,7 +824,7 @@ bool mysql_multi_update(THD *thd,
if (!(result= new multi_update(thd, table_list, if (!(result= new multi_update(thd, table_list,
thd->lex->select_lex.leaf_tables, thd->lex->select_lex.leaf_tables,
fields, values, fields, values,
handle_duplicates))) handle_duplicates, ignore)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
thd->no_trans_update= 0; thd->no_trans_update= 0;
@ -851,12 +850,12 @@ bool mysql_multi_update(THD *thd,
multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list,
TABLE_LIST *leaves_list, TABLE_LIST *leaves_list,
List<Item> *field_list, List<Item> *value_list, List<Item> *field_list, List<Item> *value_list,
enum enum_duplicates handle_duplicates_arg) enum enum_duplicates handle_duplicates_arg, bool ignore_arg)
:all_tables(table_list), leaves(leaves_list), update_tables(0), :all_tables(table_list), leaves(leaves_list), update_tables(0),
thd(thd_arg), tmp_tables(0), updated(0), found(0), fields(field_list), thd(thd_arg), tmp_tables(0), updated(0), found(0), fields(field_list),
values(value_list), table_count(0), copy_field(0), values(value_list), table_count(0), copy_field(0),
handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(0), handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(0),
transactional_tables(1) transactional_tables(1), ignore(ignore_arg)
{} {}
@ -1201,8 +1200,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
table->record[0]))) table->record[0])))
{ {
updated--; updated--;
if (handle_duplicates != DUP_IGNORE || if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
error != HA_ERR_FOUND_DUPP_KEY)
{ {
thd->fatal_error(); // Force error message thd->fatal_error(); // Force error message
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
@ -1336,8 +1334,7 @@ int multi_update::do_updates(bool from_send_error)
if ((local_error=table->file->update_row(table->record[1], if ((local_error=table->file->update_row(table->record[1],
table->record[0]))) table->record[0])))
{ {
if (local_error != HA_ERR_FOUND_DUPP_KEY || if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY)
handle_duplicates != DUP_IGNORE)
goto err; goto err;
} }
updated++; updated++;

View File

@ -3220,8 +3220,9 @@ alter:
{ {
THD *thd= YYTHD; THD *thd= YYTHD;
LEX *lex= thd->lex; LEX *lex= thd->lex;
lex->sql_command = SQLCOM_ALTER_TABLE; lex->sql_command= SQLCOM_ALTER_TABLE;
lex->name=0; lex->name= 0;
lex->duplicates= DUP_ERROR;
if (!lex->select_lex.add_table_to_list(thd, $4, NULL, if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
TL_OPTION_UPDATING)) TL_OPTION_UPDATING))
YYABORT; YYABORT;
@ -3449,8 +3450,9 @@ opt_column:
| COLUMN_SYM {}; | COLUMN_SYM {};
opt_ignore: opt_ignore:
/* empty */ { Lex->duplicates=DUP_ERROR; } /* empty */ { Lex->ignore= 0;}
| IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; | IGNORE_SYM { Lex->ignore= 1;}
;
opt_restrict: opt_restrict:
/* empty */ { Lex->drop_mode= DROP_DEFAULT; } /* empty */ { Lex->drop_mode= DROP_DEFAULT; }
@ -5573,7 +5575,8 @@ insert:
INSERT INSERT
{ {
LEX *lex= Lex; LEX *lex= Lex;
lex->sql_command = SQLCOM_INSERT; lex->sql_command= SQLCOM_INSERT;
lex->duplicates= DUP_ERROR;
/* for subselects */ /* for subselects */
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
@ -5734,6 +5737,7 @@ update:
mysql_init_select(lex); mysql_init_select(lex);
lex->sql_command= SQLCOM_UPDATE; lex->sql_command= SQLCOM_UPDATE;
lex->lock_option= TL_UNLOCK; /* Will be set later */ lex->lock_option= TL_UNLOCK; /* Will be set later */
lex->duplicates= DUP_ERROR;
} }
opt_low_priority opt_ignore join_table_list opt_low_priority opt_ignore join_table_list
SET update_list SET update_list
@ -5793,6 +5797,7 @@ delete:
LEX *lex= Lex; LEX *lex= Lex;
lex->sql_command= SQLCOM_DELETE; lex->sql_command= SQLCOM_DELETE;
lex->lock_option= lex->thd->update_lock_default; lex->lock_option= lex->thd->update_lock_default;
lex->ignore= 0;
lex->select_lex.init_order(); lex->select_lex.init_order();
} }
opt_delete_options single_multi {} opt_delete_options single_multi {}
@ -5849,7 +5854,7 @@ opt_delete_options:
opt_delete_option: opt_delete_option:
QUICK { Select->options|= OPTION_QUICK; } QUICK { Select->options|= OPTION_QUICK; }
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
| IGNORE_SYM { Lex->duplicates= DUP_IGNORE; }; | IGNORE_SYM { Lex->ignore= 1; };
truncate: truncate:
TRUNCATE_SYM opt_table_sym table_name TRUNCATE_SYM opt_table_sym table_name
@ -6357,6 +6362,8 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING_sys
lex->sql_command= SQLCOM_LOAD; lex->sql_command= SQLCOM_LOAD;
lex->lock_option= $3; lex->lock_option= $3;
lex->local_file= $4; lex->local_file= $4;
lex->duplicates= DUP_ERROR;
lex->ignore= 0;
if (!(lex->exchange= new sql_exchange($6.str,0))) if (!(lex->exchange= new sql_exchange($6.str,0)))
YYABORT; YYABORT;
lex->field_list.empty(); lex->field_list.empty();
@ -6394,7 +6401,7 @@ load_data_lock:
opt_duplicate: opt_duplicate:
/* empty */ { Lex->duplicates=DUP_ERROR; } /* empty */ { Lex->duplicates=DUP_ERROR; }
| REPLACE { Lex->duplicates=DUP_REPLACE; } | REPLACE { Lex->duplicates=DUP_REPLACE; }
| IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; | IGNORE_SYM { Lex->ignore= 1; };
opt_field_term: opt_field_term:
/* empty */ /* empty */

View File

@ -152,15 +152,22 @@ languages and applications need to dynamically load and use MySQL.
%package Max %package Max
Release: %{release} Release: %{release}
Summary: MySQL - server with Berkeley DB, RAID and UDF support Summary: MySQL - server with extended functionality
Group: Applications/Databases Group: Applications/Databases
Provides: mysql-Max Provides: mysql-Max
Obsoletes: mysql-Max Obsoletes: mysql-Max
Requires: MySQL-server >= 4.0 Requires: MySQL-server >= 4.0
%description Max %description Max
Optional MySQL server binary that supports additional features like Optional MySQL server binary that supports additional features like:
Berkeley DB, RAID and User Defined Functions (UDFs).
- Berkeley DB Storage Engine
- Archive Storage Engine
- CSV Storage Engine
- Example Storage Engine
- MyISAM RAID
- User Defined Functions (UDFs).
To activate this binary, just install this package in addition to To activate this binary, just install this package in addition to
the standard MySQL package. the standard MySQL package.
@ -273,6 +280,9 @@ BuildMySQL "--enable-shared \
--with-berkeley-db \ --with-berkeley-db \
--with-innodb \ --with-innodb \
--with-raid \ --with-raid \
--with-archive \
--with-csv-storage-engine \
--with-example-storage-engine \
--with-embedded-server \ --with-embedded-server \
--with-server-suffix='-Max'" --with-server-suffix='-Max'"
@ -595,6 +605,12 @@ fi
- ISAM and merge storage engines were purged. As well as appropriate - ISAM and merge storage engines were purged. As well as appropriate
tools and manpages (isamchk and isamlog) tools and manpages (isamchk and isamlog)
* Thu Dec 31 2004 Lenz Grimmer <lenz@mysql.com>
- enabled the "Archive" storage engine for the max binary
- enabled the "CSV" storage engine for the max binary
- enabled the "Example" storage engine for the max binary
* Thu Aug 26 2004 Lenz Grimmer <lenz@mysql.com> * Thu Aug 26 2004 Lenz Grimmer <lenz@mysql.com>
- MySQL-Max now requires MySQL-server instead of MySQL (BUG 3860) - MySQL-Max now requires MySQL-server instead of MySQL (BUG 3860)