Merge
This commit is contained in:
commit
3c6d5e43f9
@ -698,6 +698,8 @@ ndb/examples/ndbapi_example2/ndbapi_example2
|
||||
ndb/examples/ndbapi_example3/ndbapi_example3
|
||||
ndb/examples/ndbapi_example5/ndbapi_example5
|
||||
ndb/examples/select_all/select_all
|
||||
ndb/include/ndb_global.h
|
||||
ndb/include/ndb_version.h
|
||||
ndb/lib/libMGM_API.so
|
||||
ndb/lib/libNDB_API.so
|
||||
ndb/lib/libNDB_ODBC.so
|
||||
|
47
BUILD/compile-dist
Executable file
47
BUILD/compile-dist
Executable 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
|
@ -171,6 +171,7 @@ paul@frost.snake.net
|
||||
paul@ice.local
|
||||
paul@ice.snake.net
|
||||
paul@kite-hub.kitebird.com
|
||||
paul@snake-hub.snake.net
|
||||
paul@teton.kitebird.com
|
||||
pekka@mysql.com
|
||||
pem@mysql.com
|
||||
|
@ -26,7 +26,7 @@ else
|
||||
}
|
||||
|
||||
# Some predefined settings
|
||||
$build_command= "BUILD/compile-pentium-max";
|
||||
$build_command= "BUILD/compile-dist";
|
||||
$PWD= cwd();
|
||||
$opt_docdir= $PWD . "/mysqldoc";
|
||||
$opt_archive_log= undef;
|
||||
@ -70,7 +70,7 @@ GetOptions(
|
||||
"test|t",
|
||||
"verbose|v",
|
||||
"win-dist|w",
|
||||
"quiet|q",
|
||||
"quiet|q",
|
||||
) || print_help("");
|
||||
|
||||
#
|
||||
@ -122,18 +122,8 @@ if (($opt_directory ne $PWD) && (!-d $opt_directory && !$opt_dry_run))
|
||||
#
|
||||
if ($opt_pull)
|
||||
{
|
||||
&logger("Updating BK tree $REPO to latest ChangeSet first");
|
||||
chdir ($REPO) or &abort("Could not chdir to $REPO!");
|
||||
&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!");
|
||||
}
|
||||
&bk_pull("$REPO");
|
||||
&bk_pull("$opt_docdir") unless ($opt_skip_manual);
|
||||
}
|
||||
|
||||
#
|
||||
@ -270,7 +260,7 @@ if (defined $opt_changelog)
|
||||
$command.= " " . $REPO . " > $target_dir/ChangeLog";
|
||||
&logger($command);
|
||||
# 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!");
|
||||
}
|
||||
@ -281,17 +271,17 @@ if (defined $opt_changelog)
|
||||
#
|
||||
unless ($opt_skip_manual)
|
||||
{
|
||||
$msg= "Updating manual files";
|
||||
&logger($msg);
|
||||
&logger("Updating manual files");
|
||||
foreach $file qw/internals manual reservedwords/
|
||||
{
|
||||
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/!");
|
||||
}
|
||||
system ("rm -f $target_dir/Docs/Images/Makefile*") == 0
|
||||
or &abort("Could not remove Makefiles in $target_dir/Docs/Images/!");
|
||||
system ("cp $opt_docdir/Docs/Images/*.* $target_dir/Docs/Images") == 0
|
||||
or &abort("Could not copy image files in $target_dir/Docs/Images/!");
|
||||
|
||||
&run_command("rm -f $target_dir/Docs/Images/Makefile*",
|
||||
"Could not remove Makefiles 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;
|
||||
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
|
@ -23,14 +23,14 @@ EXTRA_DIST = INSTALL-SOURCE README COPYING EXCEPTIONS-CLIENT
|
||||
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
|
||||
@readline_topdir@ sql-common \
|
||||
@thread_dirs@ pstack \
|
||||
@sql_server_dirs@ @sql_client_dirs@ scripts man tests \
|
||||
@sql_union_dirs@ scripts man tests \
|
||||
netware @libmysqld_dirs@ \
|
||||
@bench_dirs@ support-files @fs_dirs@ @tools_dirs@
|
||||
|
||||
DIST_SUBDIRS = . include @docs_dirs@ zlib \
|
||||
@readline_topdir@ sql-common \
|
||||
@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@ \
|
||||
@bench_dirs@ support-files @fs_dirs@ @tools_dirs@
|
||||
|
||||
|
16
configure.in
16
configure.in
@ -2449,7 +2449,7 @@ thread_dirs=
|
||||
|
||||
dnl This probably should be cleaned up more - for now the threaded
|
||||
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"
|
||||
CLIENT_LIBS=$NON_THREADED_CLIENT_LIBS
|
||||
if test "$THREAD_SAFE_CLIENT" != "no"
|
||||
@ -2623,6 +2623,20 @@ AC_SUBST(sql_server_dirs)
|
||||
AC_SUBST(thread_dirs)
|
||||
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"
|
||||
#then
|
||||
# MIT pthreads does now support connecting with unix sockets
|
||||
|
@ -3040,8 +3040,7 @@ recv_reset_log_files_for_backup(
|
||||
memcpy(name + log_dir_len, logfilename, sizeof logfilename);
|
||||
|
||||
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++) {
|
||||
|
||||
|
@ -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))
|
||||
goto err;
|
||||
}
|
||||
#ifdef HAVE_SPATIAL
|
||||
else if (info->s->keyinfo[i].flag & HA_SPATIAL)
|
||||
{
|
||||
uint key_length=_mi_make_key(info,i,key,buff,filepos);
|
||||
if (rtree_insert(info, i, key, key_length))
|
||||
goto err;
|
||||
}
|
||||
#endif /*HAVE_SPATIAL*/
|
||||
else
|
||||
{
|
||||
uint key_length=_mi_make_key(info,i,key,buff,filepos);
|
||||
|
54
mysql-test/lib/init_db.sql
Normal file
54
mysql-test/lib/init_db.sql
Normal file
File diff suppressed because one or more lines are too long
44
mysql-test/lib/mtr_gcov.pl
Normal file
44
mysql-test/lib/mtr_gcov.pl
Normal 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;
|
50
mysql-test/lib/mtr_gprof.pl
Normal file
50
mysql-test/lib/mtr_gprof.pl
Normal 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
71
mysql-test/lib/mtr_io.pl
Normal 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;
|
67
mysql-test/lib/mtr_match.pl
Normal file
67
mysql-test/lib/mtr_match.pl
Normal 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;
|
50
mysql-test/lib/mtr_misc.pl
Normal file
50
mysql-test/lib/mtr_misc.pl
Normal 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;
|
467
mysql-test/lib/mtr_process.pl
Normal file
467
mysql-test/lib/mtr_process.pl
Normal 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;
|
262
mysql-test/lib/mtr_report.pl
Normal file
262
mysql-test/lib/mtr_report.pl
Normal 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
2182
mysql-test/mysql-test-run.pl
Executable file
File diff suppressed because it is too large
Load Diff
@ -178,3 +178,12 @@ aaa aa
|
||||
aab aa
|
||||
aac aa
|
||||
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
|
||||
|
@ -63,8 +63,4 @@ a0
|
||||
select 'a' union select concat('a', -0.0);
|
||||
a
|
||||
a
|
||||
a0.0
|
||||
select 'a' union select concat('a', -0.0000);
|
||||
a
|
||||
a
|
||||
a0.0000
|
||||
good
|
||||
|
@ -474,12 +474,15 @@ unix_timestamp(@a)
|
||||
select unix_timestamp('1969-12-01 19:00:01');
|
||||
unix_timestamp('1969-12-01 19:00:01')
|
||||
0
|
||||
select from_unixtime(0);
|
||||
from_unixtime(0)
|
||||
select from_unixtime(-1);
|
||||
from_unixtime(-1)
|
||||
NULL
|
||||
select from_unixtime(2145916800);
|
||||
from_unixtime(2145916800)
|
||||
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);
|
||||
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;
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -143,3 +143,13 @@ t
|
||||
0000-00-00 00:00:00
|
||||
2003-01-01 00:00:00
|
||||
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;
|
||||
|
@ -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 CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a;
|
||||
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');
|
||||
|
@ -231,10 +231,14 @@ select unix_timestamp('1969-12-01 19:00:01');
|
||||
|
||||
#
|
||||
# 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(0);
|
||||
|
||||
#
|
||||
# Test types from + INTERVAL
|
||||
|
@ -6,9 +6,9 @@
|
||||
drop table if exists t1,t2,t3;
|
||||
drop database if exists mysqltest;
|
||||
drop view if exists v1;
|
||||
--error 0,1141
|
||||
--error 0,1141,1147
|
||||
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;
|
||||
delete from mysql.user where user=_binary'mysqltest_1';
|
||||
--enable_warnings
|
||||
|
@ -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");
|
||||
select * from 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;
|
||||
|
@ -382,8 +382,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
||||
}
|
||||
l_time->neg= 0;
|
||||
|
||||
if (year_length == 2 && i >= format_position[1] && i >=format_position[2] &&
|
||||
(l_time->month || l_time->day))
|
||||
if (year_length == 2 && not_zero_date)
|
||||
l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900);
|
||||
|
||||
if (!not_zero_date && (flags & TIME_NO_ZERO_DATE))
|
||||
|
@ -2683,7 +2683,7 @@ void ha_ndbcluster::info(uint flag)
|
||||
if ((my_errno= check_ndb_connection()))
|
||||
DBUG_VOID_RETURN;
|
||||
Ndb *ndb= get_ndb();
|
||||
Uint64 rows;
|
||||
Uint64 rows= 100;
|
||||
if (current_thd->variables.ndb_use_exact_count)
|
||||
ndb_get_table_statistics(ndb, m_tabname, &rows, 0);
|
||||
records= rows;
|
||||
|
@ -1603,6 +1603,7 @@ void Item_func_from_unixtime::fix_length_and_dec()
|
||||
collation.set(&my_charset_bin);
|
||||
decimals=0;
|
||||
max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
maybe_null= 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,
|
||||
uint fuzzy_date __attribute__((unused)))
|
||||
{
|
||||
longlong tmp= args[0]->val_int();
|
||||
|
||||
if ((null_value= (args[0]->null_value ||
|
||||
tmp < TIMESTAMP_MIN_VALUE ||
|
||||
tmp > TIMESTAMP_MAX_VALUE)))
|
||||
ulonglong tmp= (ulonglong)(args[0]->val_int());
|
||||
/*
|
||||
"tmp > TIMESTAMP_MAX_VALUE" check also covers case of negative
|
||||
from_unixtime() argument since tmp is unsigned.
|
||||
*/
|
||||
if ((null_value= (args[0]->null_value || tmp > TIMESTAMP_MAX_VALUE)))
|
||||
return 1;
|
||||
|
||||
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 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;
|
||||
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 res= get_arg0_date(ltime, TIME_FUZZY_DATE);
|
||||
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
|
||||
ltime->time_type= MYSQL_TIMESTAMP_DATE;
|
||||
return res;
|
||||
}
|
||||
|
@ -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,
|
||||
List<Item> &fields_arg,
|
||||
enum enum_duplicates handle_dup,
|
||||
bool using_trans)
|
||||
bool ignore, bool using_trans)
|
||||
:Log_event(thd_arg, !thd_arg->tmp_table_used ?
|
||||
0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans),
|
||||
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;
|
||||
|
||||
switch (handle_dup) {
|
||||
case DUP_IGNORE:
|
||||
sql_ex.opt_flags|= IGNORE_FLAG;
|
||||
break;
|
||||
case DUP_REPLACE:
|
||||
sql_ex.opt_flags|= REPLACE_FLAG;
|
||||
break;
|
||||
@ -2176,6 +2173,8 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
|
||||
case DUP_ERROR:
|
||||
break;
|
||||
}
|
||||
if (ignore)
|
||||
sql_ex.opt_flags|= IGNORE_FLAG;
|
||||
|
||||
if (!ex->field_term->length())
|
||||
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];
|
||||
enum enum_duplicates handle_dup;
|
||||
bool ignore= 0;
|
||||
/*
|
||||
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.
|
||||
@ -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)
|
||||
handle_dup= DUP_REPLACE;
|
||||
else if (sql_ex.opt_flags & IGNORE_FLAG)
|
||||
handle_dup= DUP_IGNORE;
|
||||
{
|
||||
ignore= 1;
|
||||
handle_dup= DUP_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
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,
|
||||
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
|
||||
(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
|
||||
the slave to discover the problem.
|
||||
|
||||
If reading from net (a 3.23 master), mysql_load() will change this
|
||||
to DUP_IGNORE.
|
||||
to IGNORE.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
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))
|
||||
thd->query_error = 1;
|
||||
if (thd->cuted_fields)
|
||||
@ -3495,8 +3498,9 @@ Create_file_log_event::
|
||||
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
|
||||
const char* db_arg, const char* table_name_arg,
|
||||
List<Item>& fields_arg, enum enum_duplicates handle_dup,
|
||||
bool ignore,
|
||||
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),
|
||||
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())
|
||||
|
@ -783,7 +783,7 @@ public:
|
||||
|
||||
Load_log_event(THD* thd, sql_exchange* ex, 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,
|
||||
bool using_trans);
|
||||
void set_fields(const char* db, List<Item> &fields_arg);
|
||||
const char* get_db() { return db; }
|
||||
@ -1170,7 +1170,7 @@ public:
|
||||
Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
|
||||
const char* table_name_arg,
|
||||
List<Item>& fields_arg,
|
||||
enum enum_duplicates handle_dup,
|
||||
enum enum_duplicates handle_dup, bool ignore,
|
||||
char* block_arg, uint block_len_arg,
|
||||
bool using_trans);
|
||||
#ifdef HAVE_REPLICATION
|
||||
|
@ -613,6 +613,7 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
||||
List<Key> &keys,
|
||||
uint order_num, ORDER *order,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
bool ignore,
|
||||
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_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,
|
||||
List<Item> &values,COND *conds,
|
||||
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,
|
||||
List<Item> *fields, List<Item> *values,
|
||||
COND *conds, ulong options,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_duplicates handle_duplicates, bool ignore,
|
||||
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex);
|
||||
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
|
||||
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);
|
||||
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &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);
|
||||
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,
|
||||
@ -882,8 +884,7 @@ bool eval_const_cond(COND *cond);
|
||||
/* sql_load.cc */
|
||||
bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
|
||||
List<Item> &fields, enum enum_duplicates handle_duplicates,
|
||||
bool local_file, thr_lock_type lock_type,
|
||||
bool ignore_check_option_errors);
|
||||
bool ignore, bool local_file, thr_lock_type lock_type);
|
||||
int write_record(THD *thd, TABLE *table, COPY_INFO *info);
|
||||
|
||||
/* sql_manager.cc */
|
||||
|
@ -3054,7 +3054,7 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
|
||||
enum db_type db_type;
|
||||
if (!(res=var->value->val_str(&str)) ||
|
||||
!(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)
|
||||
{
|
||||
value= res ? res->c_ptr() : "NULL";
|
||||
|
@ -32,7 +32,7 @@ class sp_cache;
|
||||
|
||||
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
|
||||
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_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
|
||||
DELAY_KEY_WRITE_ALL };
|
||||
@ -225,7 +225,8 @@ typedef struct st_copy_info {
|
||||
ha_rows error_count;
|
||||
enum enum_duplicates handle_duplicates;
|
||||
int escape_char, last_errno;
|
||||
/* for INSERT ... UPDATE */
|
||||
bool ignore;
|
||||
/* for INSERT ... UPDATE */
|
||||
List<Item> *update_fields;
|
||||
List<Item> *update_values;
|
||||
/* for VIEW ... WITH CHECK OPTION */
|
||||
@ -1375,8 +1376,7 @@ class select_insert :public select_result_interceptor {
|
||||
select_insert(TABLE_LIST *table_list_par,
|
||||
TABLE *table_par, List<Item> *fields_par,
|
||||
List<Item> *update_fields, List<Item> *update_values,
|
||||
enum_duplicates duplic,
|
||||
bool ignore_check_option_errors);
|
||||
enum_duplicates duplic, bool ignore);
|
||||
~select_insert();
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
bool send_data(List<Item> &items);
|
||||
@ -1401,8 +1401,8 @@ public:
|
||||
HA_CREATE_INFO *create_info_par,
|
||||
List<create_field> &fields_par,
|
||||
List<Key> &keys_par,
|
||||
List<Item> &select_fields,enum_duplicates duplic)
|
||||
:select_insert (NULL, NULL, &select_fields, 0, 0, duplic, 0), create_table(table),
|
||||
List<Item> &select_fields,enum_duplicates duplic, bool ignore)
|
||||
: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),
|
||||
lock(0)
|
||||
{}
|
||||
@ -1673,12 +1673,12 @@ class multi_update :public select_result_interceptor
|
||||
uint table_count;
|
||||
Copy_field *copy_field;
|
||||
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:
|
||||
multi_update(THD *thd_arg, TABLE_LIST *ut, TABLE_LIST *leaves_list,
|
||||
List<Item> *fields, List<Item> *values,
|
||||
enum_duplicates handle_duplicates);
|
||||
enum_duplicates handle_duplicates, bool ignore);
|
||||
~multi_update();
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
bool send_data(List<Item> &items);
|
||||
|
@ -68,8 +68,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
if (thd->lex->duplicates == DUP_IGNORE)
|
||||
select_lex->no_error= 1;
|
||||
select_lex->no_error= thd->lex->ignore;
|
||||
|
||||
/*
|
||||
Test if the user wants to delete all rows and deletion doesn't have
|
||||
|
@ -25,7 +25,7 @@
|
||||
static int check_null_fields(THD *thd,TABLE *entry);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
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);
|
||||
static void end_delayed_insert(THD *thd);
|
||||
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<Item> &update_fields,
|
||||
List<Item> &update_values,
|
||||
enum_duplicates duplic)
|
||||
enum_duplicates duplic,
|
||||
bool ignore)
|
||||
{
|
||||
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 transactional_table, log_delayed;
|
||||
bool ignore_err= (thd->lex->duplicates == DUP_IGNORE);
|
||||
uint value_count;
|
||||
ulong counter = 1;
|
||||
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.ignore= ignore;
|
||||
info.handle_duplicates=duplic;
|
||||
info.update_fields=&update_fields;
|
||||
info.update_values=&update_values;
|
||||
info.update_fields= &update_fields;
|
||||
info.update_values= &update_values;
|
||||
info.view= (table_list->view ? table_list : 0);
|
||||
info.ignore= ignore_err;
|
||||
|
||||
/*
|
||||
Count warnings for all inserts.
|
||||
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,
|
||||
(values_list.elements == 1 ?
|
||||
0 :
|
||||
ignore_err))) ==
|
||||
ignore))) ==
|
||||
VIEW_CHECK_SKIP)
|
||||
continue;
|
||||
else if (res == VIEW_CHECK_ERROR)
|
||||
@ -377,7 +378,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
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;
|
||||
}
|
||||
else
|
||||
@ -490,7 +491,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
else
|
||||
{
|
||||
char buff[160];
|
||||
if (duplic == DUP_IGNORE)
|
||||
if (ignore)
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(lock_type == TL_WRITE_DELAYED) ? (ulong) 0 :
|
||||
(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])))
|
||||
{
|
||||
if (info->handle_duplicates != DUP_IGNORE ||
|
||||
if (!info->ignore ||
|
||||
(error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE))
|
||||
goto err;
|
||||
table->file->restore_auto_increment();
|
||||
@ -906,13 +907,13 @@ public:
|
||||
char *record,*query;
|
||||
enum_duplicates dup;
|
||||
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;
|
||||
timestamp_auto_set_type timestamp_field_type;
|
||||
uint query_length;
|
||||
|
||||
delayed_row(enum_duplicates dup_arg, bool log_query_arg)
|
||||
:record(0),query(0),dup(dup_arg),log_query(log_query_arg) {}
|
||||
delayed_row(enum_duplicates dup_arg, bool ignore_arg, bool log_query_arg)
|
||||
:record(0), query(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg) {}
|
||||
~delayed_row()
|
||||
{
|
||||
x_free(record);
|
||||
@ -1224,7 +1225,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
|
||||
if (!query)
|
||||
@ -1600,8 +1601,9 @@ bool delayed_insert::handle_inserts(void)
|
||||
thd.insert_id_used=row->insert_id_used;
|
||||
table->timestamp_field_type= row->timestamp_field_type;
|
||||
|
||||
info.ignore= row->ignore;
|
||||
info.handle_duplicates= row->dup;
|
||||
if (info.handle_duplicates == DUP_IGNORE ||
|
||||
if (info.ignore ||
|
||||
info.handle_duplicates == DUP_REPLACE)
|
||||
{
|
||||
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
|
||||
table->next_number_field=table->found_next_number_field;
|
||||
thd->cuted_fields=0;
|
||||
if (info.handle_duplicates == DUP_IGNORE ||
|
||||
if (info.ignore ||
|
||||
info.handle_duplicates == DUP_REPLACE)
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
table->file->start_bulk_insert((ha_rows) 0);
|
||||
@ -1965,7 +1967,7 @@ bool select_insert::send_eof()
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
char buff[160];
|
||||
if (info.handle_duplicates == DUP_IGNORE)
|
||||
if (info.ignore)
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
|
||||
else
|
||||
@ -2008,7 +2010,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
|
||||
restore_record(table,default_values); // Get empty record
|
||||
thd->cuted_fields=0;
|
||||
if (info.handle_duplicates == DUP_IGNORE ||
|
||||
if (info.ignore ||
|
||||
info.handle_duplicates == DUP_REPLACE)
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
table->file->start_bulk_insert((ha_rows) 0);
|
||||
|
@ -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->sql_command=SQLCOM_END;
|
||||
lex->duplicates= DUP_ERROR;
|
||||
lex->ignore= 0;
|
||||
lex->sphead= NULL;
|
||||
lex->spcont= NULL;
|
||||
lex->proc_list.first= 0;
|
||||
|
@ -721,7 +721,7 @@ typedef struct st_lex
|
||||
/* special JOIN::prepare mode: changing of query is prohibited */
|
||||
bool view_prepare_mode;
|
||||
bool safe_to_cache_query;
|
||||
bool subqueries;
|
||||
bool subqueries, ignore;
|
||||
bool variables_used;
|
||||
ALTER_INFO alter_info;
|
||||
/* Prepared statements SQL syntax:*/
|
||||
|
@ -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,
|
||||
List<Item> &fields, enum enum_duplicates handle_duplicates,
|
||||
bool read_file_from_client,thr_lock_type lock_type,
|
||||
bool ignore_check_option_errors)
|
||||
bool ignore,
|
||||
bool read_file_from_client,thr_lock_type lock_type)
|
||||
{
|
||||
char name[FN_REFLEN];
|
||||
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 */
|
||||
if (read_file_from_client && handle_duplicates == DUP_ERROR)
|
||||
handle_duplicates=DUP_IGNORE;
|
||||
ignore= 1;
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (read_file_from_client)
|
||||
@ -237,6 +237,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
|
||||
COPY_INFO info;
|
||||
bzero((char*) &info,sizeof(info));
|
||||
info.ignore= ignore;
|
||||
info.handle_duplicates=handle_duplicates;
|
||||
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.table_name = table_list->real_name;
|
||||
lf_info.fields = &fields;
|
||||
lf_info.ignore= ignore;
|
||||
lf_info.handle_dup = handle_duplicates;
|
||||
lf_info.wrote_create_file = 0;
|
||||
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->next_number_field=table->found_next_number_field;
|
||||
if (handle_duplicates == DUP_IGNORE ||
|
||||
if (ignore ||
|
||||
handle_duplicates == DUP_REPLACE)
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
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())
|
||||
error= read_fixed_length(thd, info, table_list, fields,read_info,
|
||||
skip_lines, ignore_check_option_errors);
|
||||
skip_lines, ignore);
|
||||
else
|
||||
error= read_sep_field(thd, info, table_list, fields, read_info,
|
||||
*enclosed, skip_lines,
|
||||
ignore_check_option_errors);
|
||||
ignore);
|
||||
if (table->file->end_bulk_insert())
|
||||
error=1; /* purecov: inspected */
|
||||
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);
|
||||
}
|
||||
|
||||
switch(table_list->view_check_option(thd,
|
||||
ignore_check_option_errors))
|
||||
{
|
||||
switch (table_list->view_check_option(thd,
|
||||
ignore_check_option_errors)) {
|
||||
case VIEW_CHECK_SKIP:
|
||||
read_info.next_line();
|
||||
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,
|
||||
ignore_check_option_errors))
|
||||
{
|
||||
switch (table_list->view_check_option(thd,
|
||||
ignore_check_option_errors)) {
|
||||
case VIEW_CHECK_SKIP:
|
||||
read_info.next_line();
|
||||
goto continue_loop;
|
||||
|
@ -2628,7 +2628,8 @@ mysql_execute_command(THD *thd)
|
||||
lex->create_list,
|
||||
lex->key_list,
|
||||
select_lex->item_list,
|
||||
lex->duplicates)))
|
||||
lex->duplicates,
|
||||
lex->ignore)))
|
||||
{
|
||||
/*
|
||||
CREATE from SELECT give its SELECT_LEX for SELECT,
|
||||
@ -2768,7 +2769,7 @@ create_error:
|
||||
lex->key_list,
|
||||
select_lex->order_list.elements,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
lex->duplicates, &lex->alter_info);
|
||||
lex->duplicates, lex->ignore, &lex->alter_info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2933,7 +2934,7 @@ create_error:
|
||||
select_lex->order_list.elements,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
select_lex->select_limit,
|
||||
lex->duplicates));
|
||||
lex->duplicates, lex->ignore));
|
||||
/* mysql_update return 2 if we need to switch to multi-update */
|
||||
if (result != 2)
|
||||
break;
|
||||
@ -2954,7 +2955,7 @@ create_error:
|
||||
&lex->value_list,
|
||||
select_lex->where,
|
||||
select_lex->options,
|
||||
lex->duplicates, unit, select_lex);
|
||||
lex->duplicates, lex->ignore, unit, select_lex);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_REPLACE:
|
||||
@ -2965,8 +2966,7 @@ create_error:
|
||||
break;
|
||||
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
|
||||
lex->update_list, lex->value_list,
|
||||
(lex->value_list.elements ?
|
||||
DUP_UPDATE : lex->duplicates));
|
||||
lex->duplicates, lex->ignore);
|
||||
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
|
||||
break;
|
||||
@ -2997,8 +2997,7 @@ create_error:
|
||||
if (!res && (result= new select_insert(first_table, first_table->table,
|
||||
&lex->field_list,
|
||||
&lex->update_list, &lex->value_list,
|
||||
lex->duplicates,
|
||||
lex->duplicates == DUP_IGNORE)))
|
||||
lex->duplicates, lex->ignore)))
|
||||
{
|
||||
/*
|
||||
insert/replace from SELECT give its SELECT_LEX for SELECT,
|
||||
@ -3194,8 +3193,8 @@ create_error:
|
||||
goto error;
|
||||
}
|
||||
res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
|
||||
lex->duplicates, (bool) lex->local_file,
|
||||
lex->lock_option, lex->duplicates == DUP_IGNORE);
|
||||
lex->duplicates, lex->ignore, (bool) lex->local_file,
|
||||
lex->lock_option);
|
||||
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,
|
||||
&create_info, table_list,
|
||||
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,
|
||||
&create_info, table_list,
|
||||
fields, keys, 0, (ORDER*)0,
|
||||
DUP_ERROR, alter_info));
|
||||
DUP_ERROR, 0, alter_info));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1510,7 +1510,7 @@ err:
|
||||
|
||||
int log_loaded_block(IO_CACHE* file)
|
||||
{
|
||||
LOAD_FILE_INFO* lf_info;
|
||||
LOAD_FILE_INFO *lf_info;
|
||||
uint block_len ;
|
||||
|
||||
/* 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,
|
||||
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);
|
||||
mysql_bin_log.write(&c);
|
||||
lf_info->wrote_create_file = 1;
|
||||
|
@ -67,7 +67,7 @@ typedef struct st_load_file_info
|
||||
enum enum_duplicates handle_dup;
|
||||
char* db;
|
||||
char* table_name;
|
||||
bool wrote_create_file, log_delayed;
|
||||
bool wrote_create_file, log_delayed, ignore;
|
||||
} LOAD_FILE_INFO;
|
||||
|
||||
int log_loaded_block(IO_CACHE* file);
|
||||
|
@ -529,7 +529,7 @@ JOIN::optimize()
|
||||
optimized= 1;
|
||||
|
||||
// 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;
|
||||
#ifdef HAVE_REF_TO_FIELDS // Not done yet
|
||||
/* Add HAVING to WHERE if possible */
|
||||
|
@ -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,
|
||||
List<create_field> &create,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
bool ignore,
|
||||
uint order_num, ORDER *order,
|
||||
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,
|
||||
List<create_field> &fields, List<Key> &keys,
|
||||
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)
|
||||
{
|
||||
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->next_number_field=new_table->found_next_number_field;
|
||||
error=copy_data_between_tables(table,new_table,create_list,
|
||||
handle_duplicates,
|
||||
handle_duplicates, ignore,
|
||||
order_num, order, &copied, &deleted);
|
||||
}
|
||||
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,
|
||||
List<create_field> &create,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
bool ignore,
|
||||
uint order_num, ORDER *order,
|
||||
ha_rows *copied,
|
||||
ha_rows *deleted)
|
||||
@ -3660,7 +3662,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
current query id */
|
||||
from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
||||
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
|
||||
if (handle_duplicates == DUP_IGNORE ||
|
||||
if (ignore ||
|
||||
handle_duplicates == DUP_REPLACE)
|
||||
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
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 ((handle_duplicates != DUP_IGNORE &&
|
||||
if ((!ignore &&
|
||||
handle_duplicates != DUP_REPLACE) ||
|
||||
(error != HA_ERR_FOUND_DUPP_KEY &&
|
||||
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,
|
||||
table_list, lex->create_list,
|
||||
lex->key_list, 0, (ORDER *) 0,
|
||||
DUP_ERROR, &lex->alter_info, do_send_ok));
|
||||
DUP_ERROR, 0, &lex->alter_info, do_send_ok));
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,10 +51,10 @@ select_union::select_union(TABLE *table_par)
|
||||
{
|
||||
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
|
||||
*/
|
||||
info.handle_duplicates= DUP_IGNORE;
|
||||
info.ignore= 1;
|
||||
}
|
||||
|
||||
select_union::~select_union()
|
||||
|
@ -113,7 +113,7 @@ int mysql_update(THD *thd,
|
||||
COND *conds,
|
||||
uint order_num, ORDER *order,
|
||||
ha_rows limit,
|
||||
enum enum_duplicates handle_duplicates)
|
||||
enum enum_duplicates handle_duplicates, bool ignore)
|
||||
{
|
||||
bool using_limit= limit != HA_POS_ERROR;
|
||||
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);
|
||||
|
||||
if (select && select->quick && select->quick->reset())
|
||||
@ -433,8 +433,7 @@ int mysql_update(THD *thd,
|
||||
updated++;
|
||||
thd->no_trans_update= !transactional_table;
|
||||
}
|
||||
else if (handle_duplicates != DUP_IGNORE ||
|
||||
error != HA_ERR_FOUND_DUPP_KEY)
|
||||
else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
|
||||
{
|
||||
thd->fatal_error(); // Force error message
|
||||
table->file->print_error(error,MYF(0));
|
||||
@ -812,7 +811,7 @@ bool mysql_multi_update(THD *thd,
|
||||
List<Item> *values,
|
||||
COND *conds,
|
||||
ulong options,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_duplicates handle_duplicates, bool ignore,
|
||||
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
|
||||
{
|
||||
bool res= FALSE;
|
||||
@ -825,7 +824,7 @@ bool mysql_multi_update(THD *thd,
|
||||
if (!(result= new multi_update(thd, table_list,
|
||||
thd->lex->select_lex.leaf_tables,
|
||||
fields, values,
|
||||
handle_duplicates)))
|
||||
handle_duplicates, ignore)))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
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,
|
||||
TABLE_LIST *leaves_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),
|
||||
thd(thd_arg), tmp_tables(0), updated(0), found(0), fields(field_list),
|
||||
values(value_list), table_count(0), copy_field(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> ¬_used_values)
|
||||
table->record[0])))
|
||||
{
|
||||
updated--;
|
||||
if (handle_duplicates != DUP_IGNORE ||
|
||||
error != HA_ERR_FOUND_DUPP_KEY)
|
||||
if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
|
||||
{
|
||||
thd->fatal_error(); // Force error message
|
||||
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],
|
||||
table->record[0])))
|
||||
{
|
||||
if (local_error != HA_ERR_FOUND_DUPP_KEY ||
|
||||
handle_duplicates != DUP_IGNORE)
|
||||
if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY)
|
||||
goto err;
|
||||
}
|
||||
updated++;
|
||||
|
@ -3220,8 +3220,9 @@ alter:
|
||||
{
|
||||
THD *thd= YYTHD;
|
||||
LEX *lex= thd->lex;
|
||||
lex->sql_command = SQLCOM_ALTER_TABLE;
|
||||
lex->name=0;
|
||||
lex->sql_command= SQLCOM_ALTER_TABLE;
|
||||
lex->name= 0;
|
||||
lex->duplicates= DUP_ERROR;
|
||||
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
|
||||
TL_OPTION_UPDATING))
|
||||
YYABORT;
|
||||
@ -3449,8 +3450,9 @@ opt_column:
|
||||
| COLUMN_SYM {};
|
||||
|
||||
opt_ignore:
|
||||
/* empty */ { Lex->duplicates=DUP_ERROR; }
|
||||
| IGNORE_SYM { Lex->duplicates=DUP_IGNORE; };
|
||||
/* empty */ { Lex->ignore= 0;}
|
||||
| IGNORE_SYM { Lex->ignore= 1;}
|
||||
;
|
||||
|
||||
opt_restrict:
|
||||
/* empty */ { Lex->drop_mode= DROP_DEFAULT; }
|
||||
@ -5573,7 +5575,8 @@ insert:
|
||||
INSERT
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->sql_command = SQLCOM_INSERT;
|
||||
lex->sql_command= SQLCOM_INSERT;
|
||||
lex->duplicates= DUP_ERROR;
|
||||
/* for subselects */
|
||||
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
|
||||
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
|
||||
@ -5734,6 +5737,7 @@ update:
|
||||
mysql_init_select(lex);
|
||||
lex->sql_command= SQLCOM_UPDATE;
|
||||
lex->lock_option= TL_UNLOCK; /* Will be set later */
|
||||
lex->duplicates= DUP_ERROR;
|
||||
}
|
||||
opt_low_priority opt_ignore join_table_list
|
||||
SET update_list
|
||||
@ -5793,6 +5797,7 @@ delete:
|
||||
LEX *lex= Lex;
|
||||
lex->sql_command= SQLCOM_DELETE;
|
||||
lex->lock_option= lex->thd->update_lock_default;
|
||||
lex->ignore= 0;
|
||||
lex->select_lex.init_order();
|
||||
}
|
||||
opt_delete_options single_multi {}
|
||||
@ -5849,7 +5854,7 @@ opt_delete_options:
|
||||
opt_delete_option:
|
||||
QUICK { Select->options|= OPTION_QUICK; }
|
||||
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
|
||||
| IGNORE_SYM { Lex->duplicates= DUP_IGNORE; };
|
||||
| IGNORE_SYM { Lex->ignore= 1; };
|
||||
|
||||
truncate:
|
||||
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->lock_option= $3;
|
||||
lex->local_file= $4;
|
||||
lex->duplicates= DUP_ERROR;
|
||||
lex->ignore= 0;
|
||||
if (!(lex->exchange= new sql_exchange($6.str,0)))
|
||||
YYABORT;
|
||||
lex->field_list.empty();
|
||||
@ -6394,7 +6401,7 @@ load_data_lock:
|
||||
opt_duplicate:
|
||||
/* empty */ { Lex->duplicates=DUP_ERROR; }
|
||||
| REPLACE { Lex->duplicates=DUP_REPLACE; }
|
||||
| IGNORE_SYM { Lex->duplicates=DUP_IGNORE; };
|
||||
| IGNORE_SYM { Lex->ignore= 1; };
|
||||
|
||||
opt_field_term:
|
||||
/* empty */
|
||||
|
@ -152,15 +152,22 @@ languages and applications need to dynamically load and use MySQL.
|
||||
|
||||
%package Max
|
||||
Release: %{release}
|
||||
Summary: MySQL - server with Berkeley DB, RAID and UDF support
|
||||
Summary: MySQL - server with extended functionality
|
||||
Group: Applications/Databases
|
||||
Provides: mysql-Max
|
||||
Obsoletes: mysql-Max
|
||||
Requires: MySQL-server >= 4.0
|
||||
|
||||
%description Max
|
||||
Optional MySQL server binary that supports additional features like
|
||||
Berkeley DB, RAID and User Defined Functions (UDFs).
|
||||
Optional MySQL server binary that supports additional features like:
|
||||
|
||||
- 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
|
||||
the standard MySQL package.
|
||||
|
||||
@ -273,6 +280,9 @@ BuildMySQL "--enable-shared \
|
||||
--with-berkeley-db \
|
||||
--with-innodb \
|
||||
--with-raid \
|
||||
--with-archive \
|
||||
--with-csv-storage-engine \
|
||||
--with-example-storage-engine \
|
||||
--with-embedded-server \
|
||||
--with-server-suffix='-Max'"
|
||||
|
||||
@ -595,6 +605,12 @@ fi
|
||||
- ISAM and merge storage engines were purged. As well as appropriate
|
||||
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>
|
||||
|
||||
- MySQL-Max now requires MySQL-server instead of MySQL (BUG 3860)
|
||||
|
Loading…
x
Reference in New Issue
Block a user