diff --git a/.bzrignore b/.bzrignore index f27193d0adf..608a414ae20 100644 --- a/.bzrignore +++ b/.bzrignore @@ -754,6 +754,7 @@ 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_types.h ndb/include/ndb_version.h ndb/lib/libMGM_API.so ndb/lib/libNDB_API.so diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index d378276a0a3..fa20fd14571 100644 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -43,7 +43,13 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch c_warnings="$global_warnings -Wunused" cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" +base_max_configs="--with-innodb --with-bdb --with-ndbcluster --with-archive-storage-engine --with-raid --with-openssl --with-raid --with-vio" +max_leave_isam_configs="--with-innodb --with-bdb --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-raid --with-openssl --with-raid --with-vio --with-embedded-server" +max_no_es_configs="$max_leave_isam_configs --without-isam" +max_configs="$max_no_es_configs --with-embedded-server" + alpha_cflags="-mcpu=ev6 -Wa,-mev6" # Not used yet +amd64_cflags="-DBIG_TABLES" pentium_cflags="-mcpu=pentiumpro" pentium64_cflags="-mcpu=nocona -m64" ppc_cflags="-mpowerpc -mcpu=powerpc" @@ -58,9 +64,11 @@ reckless_cflags="-O3 -fomit-frame-pointer " debug_cflags="-DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX" base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti" +amd64_cxxflags="-DBIG_TABLES" base_configs="--prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-readline" static_link="--with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static" +amd64_configs="" alpha_configs="" # Not used yet pentium_configs="" sparc_configs="" diff --git a/BUILD/compile-amd64-debug-max b/BUILD/compile-amd64-debug-max index 46291db48b1..530bdba009b 100755 --- a/BUILD/compile-amd64-debug-max +++ b/BUILD/compile-amd64-debug-max @@ -1,15 +1,9 @@ #! /bin/sh path=`dirname $0` . "$path/SETUP.sh" -amd64_cflags="-DBIG_TABLES" -amd64_cxx_flags="-DBIG_TABLES" -amd64_configs="" -base_cxxflags="$amd64_cxx_flags $base_cxxflags" -extra_flags="$amd64_cflags $debug_cflags" +extra_flags="$amd64_cflags $debug_cflags $max_cflags" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" -extra_configs="$amd64_configs $debug_configs" - -extra_configs="$extra_configs --with-berkeley-db --with-innodb --without-isam --with-embedded-server --with-openssl --with-raid --with-vio --with-ndbcluster" +extra_configs="$amd64_configs $debug_configs $max_configs" . "$path/FINISH.sh" diff --git a/BUILD/compile-amd64-max b/BUILD/compile-amd64-max index 087dba7f94a..228448f6392 100755 --- a/BUILD/compile-amd64-max +++ b/BUILD/compile-amd64-max @@ -2,16 +2,7 @@ path=`dirname $0` . "$path/SETUP.sh" -amd64_cflags="-DBIG_TABLES" -amd64_cxx_flags="-DBIG_TABLES" -amd64_configs="" -base_cxxflags="$amd64_cxx_flags $base_cxxflags" -extra_flags="$amd64_cflags $fast_cflags -g" -extra_configs="$amd64_configs" -#strip=yes - -extra_configs="$extra_configs --with-innodb --with-berkeley-db \ - --with-embedded-server --enable-thread-safe-client \ - --with-openssl --with-vio --with-raid --with-ndbcluster" +extra_flags="$amd64_cflags $fast_cflags $max_cflags -g" +extra_configs="$amd64_configs $max_configs" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max index 8894782050c..420657e0b73 100755 --- a/BUILD/compile-pentium-debug-max +++ b/BUILD/compile-pentium-debug-max @@ -3,11 +3,9 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$pentium_cflags $debug_cflags" +extra_flags="$pentium_cflags $debug_cflags $max_cflags" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" -extra_configs="$pentium_configs $debug_configs" - -extra_configs="$extra_configs --with-berkeley-db --with-innodb --without-isam --with-embedded-server --with-openssl --with-raid --with-vio --with-ndbcluster" +extra_configs="$pentium_configs $debug_configs $max_configs" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium-debug-max-no-embedded b/BUILD/compile-pentium-debug-max-no-embedded index 4554e38fdc1..803a6a9d6d3 100755 --- a/BUILD/compile-pentium-debug-max-no-embedded +++ b/BUILD/compile-pentium-debug-max-no-embedded @@ -3,11 +3,9 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$pentium_cflags $debug_cflags" +extra_flags="$pentium_cflags $debug_cflags $max_cflags" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" -extra_configs="$pentium_configs $debug_configs" - -extra_configs="$extra_configs --with-berkeley-db --with-innodb --without-isam --with-openssl --with-raid" +extra_configs="$pentium_configs $debug_configs $max_no_es_configs" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium-max b/BUILD/compile-pentium-max index caf657a2049..595581f604e 100755 --- a/BUILD/compile-pentium-max +++ b/BUILD/compile-pentium-max @@ -3,12 +3,7 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$pentium_cflags $fast_cflags -g" -extra_configs="$pentium_configs" -#strip=yes - -extra_configs="$extra_configs --with-innodb --with-berkeley-db \ - --with-embedded-server --enable-thread-safe-client \ - --with-openssl --with-vio --with-raid --with-ndbcluster" +extra_flags="$pentium_cflags $fast_cflags $max_cflags -g" +extra_configs="$pentium_configs $max_configs" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium-valgrind-max b/BUILD/compile-pentium-valgrind-max index fd9543163d6..f0dc92c2ffd 100755 --- a/BUILD/compile-pentium-valgrind-max +++ b/BUILD/compile-pentium-valgrind-max @@ -3,13 +3,13 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$pentium_cflags $debug_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max" +extra_flags="$pentium_cflags $debug_cflags $max_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs" # We want to test isam when building with valgrind -extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-isam --with-embedded-server --with-openssl --with-vio --with-raid --with-ndbcluster" +extra_configs="$extra_configs $max_leave_isam_configs --with-isam" . "$path/FINISH.sh" diff --git a/BUILD/compile-ppc-debug-max b/BUILD/compile-ppc-debug-max index 9d67b46601a..49d1442fd45 100755 --- a/BUILD/compile-ppc-debug-max +++ b/BUILD/compile-ppc-debug-max @@ -3,11 +3,9 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$ppc_cflags $debug_cflags" +extra_flags="$ppc_cflags $debug_cflags $max_cflags" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" -extra_configs="$debug_configs" - -extra_configs="$extra_configs --with-berkeley-db --with-innodb --without-isam --with-embedded-server --with-openssl --with-raid --with-vio --with-ndbcluster" +extra_configs="$debug_configs $max_configs" . "$path/FINISH.sh" diff --git a/BUILD/compile-ppc-max b/BUILD/compile-ppc-max index f7193eb8aca..1d89be81c9c 100755 --- a/BUILD/compile-ppc-max +++ b/BUILD/compile-ppc-max @@ -3,11 +3,7 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$ppc_cflags $fast_cflags -g" -#strip=yes - -extra_configs="$extra_configs --with-innodb --with-berkeley-db \ - --with-embedded-server --enable-thread-safe-client \ - --with-openssl --with-vio --with-raid --with-ndbcluster" +extra_flags="$ppc_cflags $fast_cflags $max_cflags -g" +extra_configs="$extra_configs $max_configs" . "$path/FINISH.sh" diff --git a/BUILD/compile-solaris-sparc-purify b/BUILD/compile-solaris-sparc-purify index 71a60e45cb0..c895d99c2cf 100755 --- a/BUILD/compile-solaris-sparc-purify +++ b/BUILD/compile-solaris-sparc-purify @@ -3,28 +3,27 @@ while test $# -gt 0 do case "$1" in - --debug) EXTRA_CONFIG_FLAGS=--with-debug; shift ;; - -h | --help ) cat <; $SUPFILEDIR= <$SRCBASEDIR/support-files/MacOSX>; -$TAR= <$BUILDDIR/$NAME-apple-darwin*-powerpc.tar.gz>; +$TAR= <$BUILDDIR/$NAME-apple-darwin*-powerpc*.tar.gz>; $TAR =~ /.*\/$NAME(.*)\.tar\.gz$/; $ARCH= $1; $NAME= $NAME . $ARCH; diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm index da06e1f58e4..23602debfb1 100755 --- a/Build-tools/Do-rpm +++ b/Build-tools/Do-rpm @@ -22,7 +22,6 @@ use Getopt::Long; Getopt::Long::Configure ("bundling"); use Sys::Hostname; -$opt_nobuild = undef; $opt_cc= undef; $opt_cflags= undef; $opt_clean= undef; @@ -33,6 +32,9 @@ $opt_help= undef; $opt_log= undef; $opt_mail= ""; $opt_verbose= undef; +$opt_susebuild= undef; +$opt_susebuildroot= undef; +$opt_suserpms= undef; # Set a dummy version until we know the correct one $VERSION= "x.y.z"; @@ -49,7 +51,9 @@ GetOptions( "help|h", "log|l:s", "mail|m=s", - "nobuild", + "susebuild|s", + "susebuildroot|r=s", + "suserpms=s", "verbose|v", ) || &print_help; @@ -57,6 +61,20 @@ GetOptions( defined($SPECFILE=$ARGV[0]) || print_help("Please provide the spec file name!"); +&print_help("Please define the location of the RPM repository!") if $opt_susebuild && !($opt_suserpms || $ENV{BUILD_RPMS}); + +unless ($opt_susebuildroot) +{ + if ($ENV{BUILD_ROOT}) + { + $opt_susebuildroot= $ENV{BUILD_ROOT}; + } + else + { + $opt_susebuildroot="/var/tmp/build-root"; + } +} + # Include helper functions $PWD= cwd(); $LOGGER= "$PWD/logger.pm"; @@ -72,7 +90,7 @@ else $subject= "RPM build for $SPECFILE failed" if $opt_mail; # Open the spec file and extract the version number -open(SPEC, $SPECFILE) or &abort("Unable to open \"$ARGV[0]\": $!"); +open(SPEC, $SPECFILE) or die "Unable to open \"$ARGV[0]\": $!"; @spec= ; close SPEC; @@ -94,7 +112,7 @@ $HOST= hostname(); $HOST=~ /^([^.-]*)/; $HOST= $1; $LOGFILE= "$PWD/Logs/Do-rpm-$HOST-$MAJOR.$MINOR.log"; -&logger("Using spec file for version: $VERSION"); +&logger("Logging to $LOGFILE"); # # Override predefined Log file name @@ -114,111 +132,157 @@ if (defined $opt_log) } } -# -# Newer RPM versions ship with a separate tool "rpmbuild" to build RPMs -# -if (-x "/usr/bin/rpmbuild") +&logger("Using spec file for version: $VERSION"); + +if ($opt_susebuild) { - $RPM= "/usr/bin/rpmbuild"; - $RMSOURCE= "--rmsource --rmspec"; + &susebuild; } else -{ - $RPM= "/bin/rpm"; - $RMSOURCE= "--rmspec"; +{ + &rpmbuild; } -if ($RPM) -{ - &logger("Found rpm binary: $RPM"); -} -else -{ - &abort("Unable to find RPM binary!"); -} - -# -# determine some RPM settings for this host -# -chomp($RPMARCH= `$RPM --eval "%{_arch}" 2> /dev/null`); -chomp($RPMDIR= `$RPM --eval "%{_rpmdir}" 2> /dev/null`); -chomp($SOURCEDIR= `$RPM --eval "%{_sourcedir}" 2> /dev/null`); -chomp($SPECDIR= `$RPM --eval "%{_specdir}" 2> /dev/null`); -chomp($SRCRPMDIR= `$RPM --eval "%{_srcrpmdir}" 2> /dev/null`); - -$SOURCEFILE= glob "mysql*-$VERSION.tar.gz"; - -unless($opt_nobuild) { - - &logger("Starting RPM build of MySQL-$VERSION on $HOST"); - - foreach $file ($SOURCEFILE, $SPECFILE) - { - &abort("Unable to find $file!") unless (-f "$file"); - } - -# -# Install source and spec file -# - &logger("Copying SOURCE and SPEC file to build directories."); - unless ($opt_dry_run) - { - copy($SOURCEFILE, $SOURCEDIR) - or &abort("Unable to copy $SOURCEFILE to $SOURCEDIR!"); - copy($SPECFILE, $SPECDIR) - or &abort("Unable to copy $SPECFILE to $SPECDIR!"); - } - -# -# Set environment variables - these are being used in the -# official MySQL RPM spec file -# - &logger("Setting special build environment variables") - if ($opt_cc) or ($opt_cflags) or ($opt_cxxflags) or ($opt_cxx); - $ENV{MYSQL_BUILD_CC}=$opt_cc if ($opt_cc); - $ENV{MYSQL_BUILD_CFLAGS}=$opt_cflags if ($opt_cflags); - $ENV{MYSQL_BUILD_CXXFLAGS}=$opt_cxxflags if ($opt_cxxflags); - $ENV{MYSQL_BUILD_CXX}=$opt_cxx if ($opt_cxx); - -# -# Build the RPMs -# - $command= "$RPM"; - $command.= " -v" if ($opt_verbose); - $command.= " -ba"; - $command.= " --clean $RMSOURCE" if $opt_clean; - $command.= " $SPECDIR/"; - $command.= basename($SPECFILE); - &logger("Building RPM."); - &run_command($command, "Error while building the RPMs!"); -} - -# -# Move the resulting RPMs into the pwd -# -$command= "mv"; -$command.= " -v " if ($opt_verbose); -$command.= " $SRCRPMDIR/MySQL*$VERSION_SRPM*.src.rpm $PWD"; -&logger("Moving source RPM to current dir."); -&run_command($command, "Error moving source RPM!"); - -$command= "mv"; -$command.= " -v " if ($opt_verbose); -# $command.= " $RPMDIR/$RPMARCH/MySQL*$VERSION*.$RPMARCH.rpm $PWD"; -$command.= " $RPMDIR/$RPMARCH/MySQL*$VERSION_SRPM*.$RPMARCH.rpm $PWD"; -&logger("Moving binary RPMs to current dir."); -&run_command($command, "Error moving binary RPMs!"); - &logger("SUCCESS: RPM files successfully created.") unless ($opt_dry_run); exit 0; +# +# Build using SUSE's "build" script +# +sub susebuild +{ + $BUILD= "/usr/bin/build"; + ( -x $BUILD) ? &logger("$BUILD found, proceeding.") : &abort("$BUILD could not be found!"); + $command= "sudo $BUILD --clean"; + $command.= " --root=$opt_susebuildroot"; + $command.= " --rpms=$opt_suserpms" if $opt_suserpms; + $command.= " $SPECFILE"; + &logger("Building RPMs using SUSE build."); + &run_command($command, "Error while running the SUSE RPM build!"); + + # + # Move the resulting RPMs into the pwd - we can use broad globs here + # as the build root has been cleaned up before so there should not be + # any residuals from previous build runs + # + $command= "cp"; + $command.= " -v " if ($opt_verbose); + $command.= " $opt_susebuildroot/usr/src/packages/SRPMS/MySQL*.src.rpm $PWD"; + &logger("Copying source RPM to current dir."); + &run_command($command, "Error moving source RPM!"); + + $command= "cp"; + $command.= " -v " if ($opt_verbose); + $command.= " $opt_susebuildroot/usr/src/packages/RPMS/*/MySQL*.rpm $PWD"; + &logger("Copying binary RPMs to current dir."); + &run_command($command, "Error moving binary RPMs!"); +} + +# +# Build using "plain" RPM +# +sub rpmbuild +{ + + # + # Newer RPM versions ship with a separate tool "rpmbuild" to build RPMs + # + if (-x "/usr/bin/rpmbuild") + { + $RPM= "/usr/bin/rpmbuild"; + $RMSOURCE= "--rmsource --rmspec"; + } + else + { + $RPM= "/bin/rpm"; + $RMSOURCE= "--rmspec"; + } + + if ($RPM) + { + &logger("Found rpm binary: $RPM"); + } + else + { + &abort("Unable to find RPM binary!"); + } + + # + # determine some RPM settings for this host + # + chomp($RPMARCH= `$RPM --eval "%{_arch}" 2> /dev/null`); + chomp($RPMDIR= `$RPM --eval "%{_rpmdir}" 2> /dev/null`); + chomp($SOURCEDIR= `$RPM --eval "%{_sourcedir}" 2> /dev/null`); + chomp($SPECDIR= `$RPM --eval "%{_specdir}" 2> /dev/null`); + chomp($SRCRPMDIR= `$RPM --eval "%{_srcrpmdir}" 2> /dev/null`); + + $SOURCEFILE= glob "mysql*-$VERSION.tar.gz"; + + &logger("Starting RPM build of MySQL-$VERSION on $HOST"); + + foreach $file ($SOURCEFILE, $SPECFILE) + { + &abort("Unable to find $file!") unless (-f "$file"); + } + + # + # Install source and spec file + # + &logger("Copying SOURCE and SPEC file to build directories."); + unless ($opt_dry_run) + { + copy($SOURCEFILE, $SOURCEDIR) + or &abort("Unable to copy $SOURCEFILE to $SOURCEDIR!"); + copy($SPECFILE, $SPECDIR) + or &abort("Unable to copy $SPECFILE to $SPECDIR!"); + } + + # + # Set environment variables - these are being used in the + # official MySQL RPM spec file + # + &logger("Setting special build environment variables") + if ($opt_cc) or ($opt_cflags) or ($opt_cxxflags) or ($opt_cxx); + $ENV{MYSQL_BUILD_CC}=$opt_cc if ($opt_cc); + $ENV{MYSQL_BUILD_CFLAGS}=$opt_cflags if ($opt_cflags); + $ENV{MYSQL_BUILD_CXXFLAGS}=$opt_cxxflags if ($opt_cxxflags); + $ENV{MYSQL_BUILD_CXX}=$opt_cxx if ($opt_cxx); + + # + # Build the RPMs + # + $command= "$RPM"; + $command.= " -v" if ($opt_verbose); + $command.= " -ba"; + $command.= " --clean $RMSOURCE" if $opt_clean; + $command.= " $SPECDIR/"; + $command.= basename($SPECFILE); + &logger("Building RPM."); + &run_command($command, "Error while building the RPMs!"); + + # + # Move the resulting RPMs into the pwd + # + $command= "mv"; + $command.= " -v " if ($opt_verbose); + $command.= " $SRCRPMDIR/MySQL*$VERSION_SRPM*.src.rpm $PWD"; + &logger("Moving source RPM to current dir."); + &run_command($command, "Error moving source RPM!"); + + $command= "mv"; + $command.= " -v " if ($opt_verbose); + $command.= " $RPMDIR/$RPMARCH/MySQL*$VERSION_SRPM*.$RPMARCH.rpm $PWD"; + &logger("Moving binary RPMs to current dir."); + &run_command($command, "Error moving binary RPMs!"); +} + sub print_help { my $message= $_[0]; if ($message ne "") { print "\n"; - print "ERROR: $message\n\n}"; + print "ERROR: $message\n\n"; } print <] Write a log file [to ] - (default is "$LOGFILE") -m, --mail=
Mail a failure report to the given address (and include a log file snippet, if logging is enabled) Note that the \@-Sign needs to be quoted! Example: --mail=user\\\@domain.com +-s, --susebuild Use the SUSE "build" script instead of RPM + directly (requires sudo privileges to run the + /usr/bin/build command) +-r, --susebuildroot= Use as the build root directory for the + SUSE "build" (default is /var/tmp/build-root + or defined by the BUILD_ROOT environment + variable) +--suserpms= Path to the SUSE RPM repository to build up + the build root (mandatory option when using + --susebuild and the BUILD_RPMS environment + variable is not set.) -v, --verbose Verbose execution Example: diff --git a/client/Makefile.am b/client/Makefile.am index bd39ad6c664..9b62d698e38 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -20,9 +20,8 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/regex \ $(openssl_includes) -I$(top_srcdir)/extra LIBS = @CLIENT_LIBS@ -DEPLIB= ../libmysql/libmysqlclient.la -REGEXLIB= ../regex/libregex.a -LDADD = @CLIENT_EXTRA_LDFLAGS@ $(DEPLIB) +LDADD= @CLIENT_EXTRA_LDFLAGS@ \ + $(top_builddir)/libmysql/libmysqlclient.la bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ @@ -31,19 +30,10 @@ mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc mysqladmin_SOURCES = mysqladmin.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS) -mysql_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqladmin_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqlcheck_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqlshow_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqldump_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqlimport_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqltest_SOURCES= mysqltest.c ../mysys/my_getsystime.c -mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(REGEXLIB) $(DEPLIB) -mysqltest_LDADD = $(REGEXLIB) $(LDADD) -mysqlbinlog_SOURCES = mysqlbinlog.cc ../mysys/mf_tempdir.c -mysqlbinlog_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) +mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c +mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) +mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c mysqlmanagerc_SOURCES = mysqlmanagerc.c -mysqlmanagerc_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) sql_src=log_event.h mysql_priv.h log_event.cc # Fix for mit-threads diff --git a/client/mysql.cc b/client/mysql.cc index 7e7b2e291d5..e178f79bcf3 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -172,7 +172,7 @@ static char *shared_memory_base_name=0; #endif static uint opt_protocol=0; static CHARSET_INFO *charset_info= &my_charset_latin1; - + #include "sslopt-vars.h" const char *default_dbug_option="d:t:o,/tmp/mysql.trace"; @@ -1520,7 +1520,7 @@ You can turn off this feature to get a quicker startup with -A\n\n"); j=0; while ((sql_field=mysql_fetch_field(fields))) { - sprintf(buf,"%s.%s",table_row[0],sql_field->name); + sprintf(buf,"%.64s.%.64s",table_row[0],sql_field->name); field_names[i][j] = strdup_root(&hash_mem_root,buf); add_word(&ht,field_names[i][j]); field_names[i][num_fields+j] = strdup_root(&hash_mem_root, @@ -1597,7 +1597,7 @@ int mysql_real_query_for_lazy(const char *buf, int length) for (uint retry=0;; retry++) { if (!mysql_real_query(&mysql,buf,length)) - return 0; + return 0; int error= put_error(&mysql); if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 || !opt_reconnect) @@ -2526,7 +2526,7 @@ com_connect(String *buffer, char *line) { sprintf(buff,"Connection id: %lu",mysql_thread_id(&mysql)); put_info(buff,INFO_INFO); - sprintf(buff,"Current database: %s\n", + sprintf(buff,"Current database: %.128s\n", current_db ? current_db : "*** NONE ***"); put_info(buff,INFO_INFO); } @@ -3234,13 +3234,20 @@ static const char* construct_prompt() break; } case 'p': + { #ifndef EMBEDDED_LIBRARY if (!connected) { processed_prompt.append("not_connected"); break; } - if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || + + const char *host_info = mysql_get_host_info(&mysql); + if (strstr(host_info, "memory")) + { + processed_prompt.append( mysql.host ); + } + else if (strstr(host_info,"TCP/IP") || !mysql.unix_socket) add_int_to_prompt(mysql.port); else @@ -3249,6 +3256,7 @@ static const char* construct_prompt() processed_prompt.append(pos ? pos+1 : mysql.unix_socket); } #endif + } break; case 'U': if (!full_username) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index e62ec8d7cea..3bef8fb0452 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -833,7 +833,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (argv[1][0]) { char *pw= argv[1]; - bool old= find_type(argv[0], &command_typelib, 2) == ADMIN_OLD_PASSWORD; + bool old= (find_type(argv[0], &command_typelib, 2) == + ADMIN_OLD_PASSWORD); #ifdef __WIN__ uint pw_len= strlen(pw); if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'') @@ -844,21 +845,29 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) If we don't already know to use an old-style password, see what the server is using */ - if (!old) { - if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'")) { + if (!old) + { + if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'")) + { my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'", MYF(ME_BELL),mysql_error(mysql)); return -1; - } else { + } + else + { MYSQL_RES *res= mysql_store_result(mysql); - if (!res) { - my_printf_error(0, "Could not get old_passwords setting from server; error: '%s'", + if (!res) + { + my_printf_error(0, + "Could not get old_passwords setting from " + "server; error: '%s'", MYF(ME_BELL),mysql_error(mysql)); return -1; } - if (!mysql_num_rows(res)) { + if (!mysql_num_rows(res)) old= 1; - } else { + else + { MYSQL_ROW row= mysql_fetch_row(res); old= !strncmp(row[1], "ON", 2); } diff --git a/client/mysqldump.c b/client/mysqldump.c index 876e4ef55e1..9b707af6107 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -305,6 +305,9 @@ static struct my_option my_long_options[] = {"opt", OPT_OPTIMIZE, "Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"order-by-primary", OPT_ORDER_BY_PRIMARY, + "Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.", + (gptr*) &opt_order_by_primary, (gptr*) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server. If password is not given it's solicited on the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -356,9 +359,6 @@ static struct my_option my_long_options[] = {"socket", 'S', "Socket file to use for connection.", (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"order-by-primary", OPT_ORDER_BY_PRIMARY, - "Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.", - (gptr*) &opt_order_by_primary, (gptr*) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #include {"tab",'T', "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.", @@ -2308,8 +2308,15 @@ static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now) We use BEGIN for old servers. --single-transaction --master-data will fail on old servers, but that's ok as it was already silently broken (it didn't do a consistent read, so better tell people frankly, with the error). + + We want the first consistent read to be used for all tables to dump so we + need the REPEATABLE READ level (not anything lower, for example READ + COMMITTED would give one new consistent read per dumped table). */ return (mysql_query_with_error_report(mysql_con, 0, + "SET SESSION TRANSACTION ISOLATION " + "LEVEL REPEATABLE READ") || + mysql_query_with_error_report(mysql_con, 0, consistent_read_now ? "START TRANSACTION " "WITH CONSISTENT SNAPSHOT" : diff --git a/client/mysqltest.c b/client/mysqltest.c index 05ac68e3176..9e887f61160 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -123,6 +123,17 @@ typedef struct } code; } match_err; +typedef struct +{ + const char *name; + long code; +} st_error; + +static st_error global_error[] = { +#include + { 0, 0 } +}; + static match_err global_expected_errno[MAX_EXPECTED_ERRORS]; static uint global_expected_errors; @@ -1340,6 +1351,7 @@ static uint get_errcodes(match_err *to,struct st_query* q) { char* p= q->first_argument; uint count= 0; + DBUG_ENTER("get_errcodes"); if (!*p) @@ -1350,19 +1362,41 @@ static uint get_errcodes(match_err *to,struct st_query* q) if (*p == 'S') { /* SQLSTATE string */ - int i; - p++; - for (i = 0; my_isalnum(charset_info, *p) && i < SQLSTATE_LENGTH; p++, i++) - to[count].code.sqlstate[i]= *p; - to[count].code.sqlstate[i]= '\0'; + char *end= ++p + SQLSTATE_LENGTH; + char *to_ptr= to[count].code.sqlstate; + + for (; my_isalnum(charset_info, *p) && p != end; p++) + *to_ptr++= *p; + *to_ptr= 0; + to[count].type= ERR_SQLSTATE; } + else if (*p == 'E') + { + /* SQL error as string */ + st_error *e= global_error; + char *start= p++; + + for (; *p == '_' || my_isalnum(charset_info, *p); p++) + ; + for (; e->name; e++) + { + if (!strncmp(start, e->name, (int) (p - start))) + { + to[count].code.errnum= (uint) e->code; + to[count].type= ERR_ERRNO; + break; + } + } + if (!e->name) + die("Unknown SQL error '%s'\n", start); + } else { long val; - p=str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val); - if (p == NULL) - die("Invalid argument in %s\n", q->query); + + if (!(p= str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val))) + die("Invalid argument in %s\n", q->query); to[count].code.errnum= (uint) val; to[count].type= ERR_ERRNO; } @@ -2855,6 +2889,7 @@ static int normal_handle_error(const char *query, struct st_query *q, mysql_error(mysql)); DBUG_RETURN(0); } + return 0; /* Keep compiler happy */ } diff --git a/config/ac-macros/ha_ndbcluster.m4 b/config/ac-macros/ha_ndbcluster.m4 index 433bba95e91..751a11d1895 100644 --- a/config/ac-macros/ha_ndbcluster.m4 +++ b/config/ac-macros/ha_ndbcluster.m4 @@ -61,7 +61,12 @@ AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [ --without-ndb-debug Disable special ndb debug features], [ndb_debug="$withval"], [ndb_debug="default"]) - + AC_ARG_WITH([ndb-ccflags], + [ + --with-ndb-ccflags Extra CC options for ndb compile], + [ndb_cxxflags_fix=$withval], + [ndb_cxxflags_fix=]) + AC_MSG_CHECKING([for NDB Cluster options]) AC_MSG_RESULT([]) diff --git a/configure.in b/configure.in index 198e2407541..e20edf97a72 100644 --- a/configure.in +++ b/configure.in @@ -361,7 +361,6 @@ AC_SUBST(INSTALL_SCRIPT) export CC CXX CFLAGS LD LDFLAGS AR -ndb_cxxflags_fix= if test "$GXX" = "yes" then # mysqld requires -fno-implicit-templates. @@ -1922,7 +1921,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \ pthread_key_delete pthread_rwlock_rdlock pthread_setprio \ pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \ realpath rename rint rwlock_init setupterm \ - shmget shmat shmdt shmctl sigaction \ + shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \ sighold sigset sigthreadmask \ snprintf socket stpcpy strcasecmp strerror strnlen strpbrk strstr strtol \ strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr) @@ -2629,7 +2628,7 @@ AC_SUBST(server_scripts) sql_union_dirs=" $sql_server_dirs " for DIR in $sql_client_dirs do - if echo $sql_union_dirs | grep " $DIR " >/dev/null + if echo " $sql_union_dirs " | grep " $DIR " >/dev/null then : # already present, skip else @@ -2709,7 +2708,10 @@ if test "$ac_cv_func_shmget" = "yes" && test "$ac_cv_func_shmat" = "yes" && test "$ac_cv_func_shmdt" = "yes" && test "$ac_cv_func_shmctl" = "yes" && - test "$ac_cv_func_sigaction" = "yes" + test "$ac_cv_func_sigaction" = "yes" && + test "$ac_cv_func_sigemptyset" = "yes" && + test "$ac_cv_func_sigaddset" = "yes" && + test "$ac_cv_func_pthread_sigmask" = "yes" then AC_DEFINE([NDB_SHM_TRANSPORTER], [1], [Including Ndb Cluster DB shared memory transporter]) diff --git a/heap/hp_create.c b/heap/hp_create.c index 0580c178498..17aa92c9201 100644 --- a/heap/hp_create.c +++ b/heap/hp_create.c @@ -154,15 +154,15 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, keyseg->flag= 0; keyseg->null_bit= 0; keyseg++; - - init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*), + + init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*), (qsort_cmp2)keys_compare, 1, NULL, NULL); keyinfo->delete_key= hp_rb_delete_key; keyinfo->write_key= hp_rb_write_key; } else { - init_block(&keyinfo->block, sizeof(HASH_INFO), min_records, + init_block(&keyinfo->block, sizeof(HASH_INFO), min_records, max_records); keyinfo->delete_key= hp_delete_key; keyinfo->write_key= hp_write_key; @@ -171,6 +171,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, } share->min_records= min_records; share->max_records= max_records; + share->max_table_size= create_info->max_table_size; share->data_length= share->index_length= 0; share->reclength= reclength; share->blength= 1; diff --git a/heap/hp_write.c b/heap/hp_write.c index 171998e9125..a60d32eecb6 100644 --- a/heap/hp_write.c +++ b/heap/hp_write.c @@ -143,7 +143,8 @@ static byte *next_free_record_pos(HP_SHARE *info) } if (!(block_pos=(info->records % info->block.records_in_block))) { - if (info->records > info->max_records && info->max_records) + if ((info->records > info->max_records && info->max_records) || + (info->data_length + info->index_length >= info->max_table_size)) { my_errno=HA_ERR_RECORD_FILE_FULL; DBUG_RETURN(NULL); diff --git a/include/heap.h b/include/heap.h index 5e83a6e2cb5..ac2b38d1f2d 100644 --- a/include/heap.h +++ b/include/heap.h @@ -125,8 +125,8 @@ typedef struct st_hp_keydef /* Key definition with open */ TREE rb_tree; int (*write_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, const byte *record, byte *recpos); - int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, - const byte *record, byte *recpos, int flag); + int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, + const byte *record, byte *recpos, int flag); uint (*get_key_length)(struct st_hp_keydef *keydef, const byte *key); } HP_KEYDEF; @@ -135,7 +135,7 @@ typedef struct st_heap_share HP_BLOCK block; HP_KEYDEF *keydef; ulong min_records,max_records; /* Params to open */ - ulong data_length,index_length; + ulong data_length,index_length,max_table_size; uint records; /* records */ uint blength; /* records rounded up to 2^n */ uint deleted; /* Deleted records in database */ @@ -185,6 +185,7 @@ typedef struct st_heap_create_info { uint auto_key; uint auto_key_type; + ulong max_table_size; ulonglong auto_increment; } HP_CREATE_INFO; diff --git a/include/m_string.h b/include/m_string.h index 97d34421537..d3465363beb 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -215,7 +215,7 @@ extern char *strstr(const char *, const char *); extern int is_prefix(const char *, const char *); /* Conversion routines */ -double my_strtod(const char *str, char **end); +double my_strtod(const char *str, char **end, int *error); double my_atof(const char *nptr); extern char *llstr(longlong value,char *buff); diff --git a/include/my_bitmap.h b/include/my_bitmap.h index fb1c3c69563..4caa3b85456 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -24,7 +24,7 @@ typedef struct st_bitmap { uchar *bitmap; - uint bitmap_size; + uint bitmap_size; /* number of bytes occupied by the above */ /* mutex will be acquired for the duration of each bitmap operation if thread_safe flag in bitmap_init was set. Otherwise, we optimize by not diff --git a/include/my_sys.h b/include/my_sys.h index 5b0390c7d72..d11dc4a3e46 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -688,6 +688,7 @@ extern int init_io_cache(IO_CACHE *info,File file,uint cachesize, extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type, my_off_t seek_offset,pbool use_async_io, pbool clear_cache); +extern void setup_io_cache(IO_CACHE* info); extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count); #ifdef THREAD extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count); diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index 9b8fb084e33..00048bf6fbb 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -165,6 +165,17 @@ dtype_is_non_binary_string_type( return(FALSE); } +/************************************************************************* +Gets the MySQL charset-collation code for MySQL string types. */ + +ulint +dtype_get_charset_coll_noninline( +/*=============================*/ + ulint prtype) /* in: precise data type */ +{ + return(dtype_get_charset_coll(prtype)); +} + /************************************************************************* Forms a precise type from the < 4.1.2 format precise type plus the charset-collation code. */ diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c index e500b92252f..0f6d55c9341 100644 --- a/innobase/dict/dict0boot.c +++ b/innobase/dict/dict0boot.c @@ -223,6 +223,7 @@ dict_boot(void) dict_index_t* index; dict_hdr_t* dict_hdr; mtr_t mtr; + ibool success; mtr_start(&mtr); @@ -275,20 +276,20 @@ dict_boot(void) dict_mem_index_add_field(index, "NAME", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLES, - MLOG_4BYTES, &mtr); index->id = DICT_TABLES_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_TABLES, MLOG_4BYTES, &mtr)); + ut_a(success); /*-------------------------*/ index = dict_mem_index_create("SYS_TABLES", "ID_IND", DICT_HDR_SPACE, DICT_UNIQUE, 1); dict_mem_index_add_field(index, "ID", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS, - MLOG_4BYTES, &mtr); index->id = DICT_TABLE_IDS_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_TABLE_IDS, MLOG_4BYTES, &mtr)); + ut_a(success); /*-------------------------*/ table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, FALSE); @@ -311,10 +312,10 @@ dict_boot(void) dict_mem_index_add_field(index, "TABLE_ID", 0, 0); dict_mem_index_add_field(index, "POS", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS, - MLOG_4BYTES, &mtr); index->id = DICT_COLUMNS_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_COLUMNS, MLOG_4BYTES, &mtr)); + ut_a(success); /*-------------------------*/ table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, FALSE); @@ -332,6 +333,9 @@ dict_boot(void) #endif #if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2 #error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2" +#endif +#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2 +#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2" #endif table->id = DICT_INDEXES_ID; @@ -344,10 +348,10 @@ dict_boot(void) dict_mem_index_add_field(index, "TABLE_ID", 0, 0); dict_mem_index_add_field(index, "ID", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES, - MLOG_4BYTES, &mtr); index->id = DICT_INDEXES_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_INDEXES, MLOG_4BYTES, &mtr)); + ut_a(success); /*-------------------------*/ table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, FALSE); @@ -365,10 +369,10 @@ dict_boot(void) dict_mem_index_add_field(index, "INDEX_ID", 0, 0); dict_mem_index_add_field(index, "POS", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS, - MLOG_4BYTES, &mtr); index->id = DICT_FIELDS_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_FIELDS, MLOG_4BYTES, &mtr)); + ut_a(success); mtr_commit(&mtr); /*-------------------------*/ diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 747a99ebdc9..3c496bae5b4 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -544,9 +544,7 @@ dict_build_index_def_step( table in the same tablespace */ index->space = table->space; - - index->page_no = FIL_NULL; - + node->page_no = FIL_NULL; row = dict_create_sys_indexes_tuple(index, node->heap); node->ind_row = row; @@ -624,18 +622,18 @@ dict_create_index_tree_step( btr_pcur_move_to_next_user_rec(&pcur, &mtr); - index->page_no = btr_create(index->type, index->space, index->id, + node->page_no = btr_create(index->type, index->space, index->id, table->comp, &mtr); /* printf("Created a new index tree in space %lu root page %lu\n", index->space, index->page_no); */ page_rec_write_index_page_no(btr_pcur_get_rec(&pcur), DICT_SYS_INDEXES_PAGE_NO_FIELD, - index->page_no, &mtr); + node->page_no, &mtr); btr_pcur_close(&pcur); mtr_commit(&mtr); - if (index->page_no == FIL_NULL) { + if (node->page_no == FIL_NULL) { return(DB_OUT_OF_FILE_SPACE); } @@ -706,6 +704,101 @@ dict_drop_index_tree( DICT_SYS_INDEXES_PAGE_NO_FIELD, FIL_NULL, mtr); } +/*********************************************************************** +Truncates the index tree associated with a row in SYS_INDEXES table. */ + +void +dict_truncate_index_tree( +/*=====================*/ + dict_table_t* table, /* in: the table the index belongs to */ + rec_t* rec, /* in: record in the clustered index of + SYS_INDEXES table */ + mtr_t* mtr) /* in: mtr having the latch + on the record page */ +{ + ulint root_page_no; + ulint space; + ulint type; + dulint index_id; + byte* ptr; + ulint len; + ibool comp; + dict_index_t* index; + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(dict_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ + + ut_a(!dict_sys->sys_indexes->comp); + ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); + + ut_ad(len == 4); + + root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); + + if (root_page_no == FIL_NULL) { + /* The tree has been freed. */ + + return; + } + + ptr = rec_get_nth_field_old(rec, + DICT_SYS_INDEXES_SPACE_NO_FIELD, &len); + + ut_ad(len == 4); + + space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); + + if (!fil_tablespace_exists_in_mem(space)) { + /* It is a single table tablespace and the .ibd file is + missing: do nothing */ + + return; + } + + ptr = rec_get_nth_field_old(rec, + DICT_SYS_INDEXES_TYPE_FIELD, &len); + ut_ad(len == 4); + type = mach_read_from_4(ptr); + + ptr = rec_get_nth_field_old(rec, 1, &len); + ut_ad(len == 8); + index_id = mach_read_from_8(ptr); + + /* We free all the pages but the root page first; this operation + may span several mini-transactions */ + + btr_free_but_not_root(space, root_page_no); + + /* Then we free the root page in the same mini-transaction where + we create the b-tree and write its new root page number to the + appropriate field in the SYS_INDEXES record: this mini-transaction + marks the B-tree totally truncated */ + + comp = page_is_comp(btr_page_get( + space, root_page_no, RW_X_LATCH, mtr)); + + btr_free_root(space, root_page_no, mtr); + + /* Find the index corresponding to this SYS_INDEXES record. */ + for (index = UT_LIST_GET_FIRST(table->indexes); + index; + index = UT_LIST_GET_NEXT(indexes, index)) { + if (!ut_dulint_cmp(index->id, index_id)) { + break; + } + } + + root_page_no = btr_create(type, space, index_id, comp, mtr); + if (index) { + index->tree->page = root_page_no; + } + + page_rec_write_index_page_no(rec, + DICT_SYS_INDEXES_PAGE_NO_FIELD, + root_page_no, mtr); +} + /************************************************************************* Creates a table create graph. */ @@ -762,6 +855,7 @@ ind_create_graph_create( node->index = index; node->state = INDEX_BUILD_INDEX_DEF; + node->page_no = FIL_NULL; node->heap = mem_heap_create(256); node->ind_def = ins_node_create(INS_DIRECT, @@ -981,7 +1075,8 @@ dict_create_index_step( if (node->state == INDEX_ADD_TO_CACHE) { - success = dict_index_add_to_cache(node->table, node->index); + success = dict_index_add_to_cache(node->table, node->index, + node->page_no); ut_a(success); diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index d5e0a46fd39..12749f7704f 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -1374,8 +1374,9 @@ dict_index_add_to_cache( /*====================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table on which the index is */ - dict_index_t* index) /* in, own: index; NOTE! The index memory + dict_index_t* index, /* in, own: index; NOTE! The index memory object is freed in this function! */ + ulint page_no)/* in: root page number of the index */ { dict_index_t* new_index; dict_tree_t* tree; @@ -1461,10 +1462,9 @@ dict_index_add_to_cache( tree = dict_index_get_tree( UT_LIST_GET_FIRST(cluster->indexes)); new_index->tree = tree; - new_index->page_no = tree->page; } else { /* Create an index tree memory object for the index */ - tree = dict_tree_create(new_index); + tree = dict_tree_create(new_index, page_no); ut_ad(tree); new_index->tree = tree; @@ -1749,7 +1749,6 @@ dict_index_build_internal_clust( new_index->n_user_defined_cols = index->n_fields; new_index->id = index->id; - new_index->page_no = index->page_no; if (table->type != DICT_TABLE_ORDINARY) { /* The index is mixed: copy common key prefix fields */ @@ -1928,7 +1927,6 @@ dict_index_build_internal_non_clust( new_index->n_user_defined_cols = index->n_fields; new_index->id = index->id; - new_index->page_no = index->page_no; /* Copy fields from index to new_index */ dict_index_copy(new_index, index, 0, index->n_fields); @@ -3565,9 +3563,10 @@ dict_tree_t* dict_tree_create( /*=============*/ /* out, own: created tree */ - dict_index_t* index) /* in: the index for which to create: in the + dict_index_t* index, /* in: the index for which to create: in the case of a mixed tree, this should be the index of the cluster object */ + ulint page_no)/* in: root page number of the index */ { dict_tree_t* tree; @@ -3577,7 +3576,7 @@ dict_tree_create( tree->type = index->type; tree->space = index->space; - tree->page = index->page_no; + tree->page = page_no; tree->id = index->id; diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index f835d1b949a..18910acb01d 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -681,12 +681,10 @@ dict_load_indexes( } else { index = dict_mem_index_create(table->name, name_buf, space, type, n_fields); - index->page_no = page_no; index->id = id; dict_load_fields(table, index, heap); - - dict_index_add_to_cache(table, index); + dict_index_add_to_cache(table, index, page_no); } btr_pcur_move_to_next_user_rec(&pcur, &mtr); diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index cd5ac0da231..5ad61e2590f 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -548,11 +548,9 @@ ibuf_data_init_for_space( dict_mem_index_add_field(index, "PAGE_NO", 0, 0); dict_mem_index_add_field(index, "TYPES", 0, 0); - index->page_no = FSP_IBUF_TREE_ROOT_PAGE_NO; - index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space); - dict_index_add_to_cache(table, index); + dict_index_add_to_cache(table, index, FSP_IBUF_TREE_ROOT_PAGE_NO); data->index = dict_table_get_first_index(table); diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index c263d2bf613..02c874836fd 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -234,6 +234,13 @@ dtype_get_prtype( dtype_t* type); /************************************************************************* Gets the MySQL charset-collation code for MySQL string types. */ + +ulint +dtype_get_charset_coll_noninline( +/*=============================*/ + ulint prtype);/* in: precise data type */ +/************************************************************************* +Gets the MySQL charset-collation code for MySQL string types. */ UNIV_INLINE ulint dtype_get_charset_coll( diff --git a/innobase/include/dict0boot.h b/innobase/include/dict0boot.h index 35eff5af29a..86702cbca05 100644 --- a/innobase/include/dict0boot.h +++ b/innobase/include/dict0boot.h @@ -119,6 +119,7 @@ dict_create(void); clustered index */ #define DICT_SYS_INDEXES_PAGE_NO_FIELD 8 #define DICT_SYS_INDEXES_SPACE_NO_FIELD 7 +#define DICT_SYS_INDEXES_TYPE_FIELD 6 /* When a row id which is zero modulo this number (which must be a power of two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is diff --git a/innobase/include/dict0crea.h b/innobase/include/dict0crea.h index 8b6944fc605..7164e53bceb 100644 --- a/innobase/include/dict0crea.h +++ b/innobase/include/dict0crea.h @@ -54,6 +54,17 @@ dict_create_index_step( /* out: query thread to run next or NULL */ que_thr_t* thr); /* in: query thread */ /*********************************************************************** +Truncates the index tree associated with a row in SYS_INDEXES table. */ + +void +dict_truncate_index_tree( +/*=====================*/ + dict_table_t* table, /* in: the table the index belongs to */ + rec_t* rec, /* in: record in the clustered index of + SYS_INDEXES table */ + mtr_t* mtr); /* in: mtr having the latch + on the record page */ +/*********************************************************************** Drops the index tree associated with a row in SYS_INDEXES table. */ void @@ -142,6 +153,7 @@ struct ind_node_struct{ /*----------------------*/ /* Local storage for this graph node */ ulint state; /* node execution state */ + ulint page_no;/* root page number of the index */ dict_table_t* table; /* table which owns the index */ dtuple_t* ind_row;/* index definition row built */ ulint field_no;/* next field definition to insert */ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index eaf5b06b2a9..fdcb6c1c4e1 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -508,8 +508,9 @@ dict_index_add_to_cache( /*====================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table on which the index is */ - dict_index_t* index); /* in, own: index; NOTE! The index memory + dict_index_t* index, /* in, own: index; NOTE! The index memory object is freed in this function! */ + ulint page_no);/* in: root page number of the index */ /************************************************************************ Gets the number of fields in the internal representation of an index, including fields added by the dictionary system. */ @@ -686,9 +687,10 @@ dict_tree_t* dict_tree_create( /*=============*/ /* out, own: created tree */ - dict_index_t* index); /* in: the index for which to create: in the + dict_index_t* index, /* in: the index for which to create: in the case of a mixed tree, this should be the index of the cluster object */ + ulint page_no);/* in: root page number of the index */ /************************************************************************** Frees an index tree struct. */ diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 670b3445a55..ff6c4ec9b28 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -218,7 +218,6 @@ struct dict_index_struct{ const char* table_name; /* table name */ dict_table_t* table; /* back pointer to table */ ulint space; /* space where the index tree is placed */ - ulint page_no;/* page number of the index tree root */ ulint trx_id_offset;/* position of the the trx id column in a clustered index record, if the fields before it are known to be of a fixed size, diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 575d8ee67bb..2ef260829fc 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -363,6 +363,15 @@ row_get_background_drop_list_len_low(void); /*======================================*/ /* out: how many tables in list */ /************************************************************************* +Truncates a table for MySQL. */ + +int +row_truncate_table_for_mysql( +/*=========================*/ + /* out: error code or DB_SUCCESS */ + dict_table_t* table, /* in: table handle */ + trx_t* trx); /* in: transaction handle */ +/************************************************************************* Drops a table for MySQL. If the name of the dropped table ends to characters INNODB_MONITOR, then this also stops printing of monitor output by the master thread. */ @@ -447,6 +456,8 @@ struct mysql_row_templ_struct { zero if column cannot be NULL */ ulint type; /* column type in Innobase mtype numbers DATA_CHAR... */ + ulint charset; /* MySQL charset-collation code + of the column, or zero */ ulint is_unsigned; /* if a column type is an integer type and this field is != 0, then it is an unsigned integer type */ diff --git a/innobase/include/row0mysql.ic b/innobase/include/row0mysql.ic index 4ecd66e06ec..fc922b52d0a 100644 --- a/innobase/include/row0mysql.ic +++ b/innobase/include/row0mysql.ic @@ -91,12 +91,33 @@ row_mysql_store_col_in_innobase_format( } } else if (type == DATA_VARCHAR || type == DATA_VARMYSQL || type == DATA_BINARY) { + /* Remove trailing spaces. */ + + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, we hardcode the + charset-collation codes here. In 5.0, the logic will + be based on mbminlen. */ + ulint cset = dtype_get_charset_coll( + dtype_get_prtype(dfield_get_type(dfield))); ptr = row_mysql_read_var_ref(&col_len, mysql_data); - - /* Remove trailing spaces */ - while (col_len > 0 && ptr[col_len - 1] == ' ') { - col_len--; - } + if (cset == 35/*ucs2_general_ci*/ + || cset == 90/*ucs2_bin*/ + || (cset >= 128/*ucs2_unicode_ci*/ + && cset <= 144/*ucs2_persian_ci*/)) { + /* space=0x0020 */ + /* Trim "half-chars", just in case. */ + col_len &= ~1; + + while (col_len >= 2 && ptr[col_len - 2] == 0x00 + && ptr[col_len - 1] == 0x20) { + col_len -= 2; + } + } else { + /* space=0x20 */ + while (col_len > 0 && ptr[col_len - 1] == 0x20) { + col_len--; + } + } } else if (type == DATA_BLOB) { ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len); } diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h index 75af1a212b4..8df0f97c4ff 100644 --- a/innobase/include/srv0start.h +++ b/innobase/include/srv0start.h @@ -75,6 +75,10 @@ extern dulint srv_start_lsn; void set_panic_flag_for_netware(void); #endif +#ifdef HAVE_DARWIN_THREADS +extern ibool srv_have_fullfsync; +#endif + extern ulint srv_sizeof_trx_t_in_ha_innodb_cc; extern ibool srv_is_being_started; diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index a30d14f07bb..64d80350275 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1773,19 +1773,31 @@ os_file_flush( #else int ret; -#if defined(HAVE_DARWIN_THREADS) && defined(F_FULLFSYNC) +#if defined(HAVE_DARWIN_THREADS) +# ifndef F_FULLFSYNC + /* The following definition is from the Mac OS X 10.3 */ +# define F_FULLFSYNC 51 /* fsync + ask the drive to flush to the media */ +# elif F_FULLFSYNC != 51 +# error "F_FULLFSYNC != 51: ABI incompatibility with Mac OS X 10.3" +# endif /* Apple has disabled fsync() for internal disk drives in OS X. That caused corruption for a user when he tested a power outage. Let us in OS X use a nonstandard flush method recommended by an Apple engineer. */ - ret = fcntl(file, F_FULLFSYNC, NULL); - - if (ret) { - /* If we are not on a file system that supports this, then - fall back to a plain fsync. */ + if (!srv_have_fullfsync) { + /* If we are not on an operating system that supports this, + then fall back to a plain fsync. */ ret = fsync(file); + } else { + ret = fcntl(file, F_FULLFSYNC, NULL); + + if (ret) { + /* If we are not on a file system that supports this, + then fall back to a plain fsync. */ + ret = fsync(file); + } } #elif HAVE_FDATASYNC ret = fdatasync(file); diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index 6473d356ba8..193bda75f24 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -262,22 +262,6 @@ cmp_whole_field( "InnoDB: comparison!\n"); } - /* MySQL does not pad the ends of strings with spaces in a - comparison. That would cause a foreign key check to fail for - non-latin1 character sets if we have different length columns. - To prevent that we remove trailing spaces here before doing - the comparison. NOTE that if we in the future map more MySQL - types to DATA_MYSQL or DATA_VARMYSQL, we have to change this - code. */ - - while (a_length > 0 && a[a_length - 1] == ' ') { - a_length--; - } - - while (b_length > 0 && b[b_length - 1] == ' ') { - b_length--; - } - return(innobase_mysql_cmp( (int)(type->prtype & DATA_MYSQL_TYPE_MASK), (uint)dtype_get_charset_coll(type->prtype), diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 380fcf236ed..6aaa0cbcf1b 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2421,6 +2421,294 @@ funct_exit: return((int) err); } +/************************************************************************* +Truncates a table for MySQL. */ + +int +row_truncate_table_for_mysql( +/*=========================*/ + /* out: error code or DB_SUCCESS */ + dict_table_t* table, /* in: table handle */ + trx_t* trx) /* in: transaction handle */ +{ + dict_foreign_t* foreign; + ulint err; + ibool locked_dictionary = FALSE; + mem_heap_t* heap; + byte* buf; + dtuple_t* tuple; + dfield_t* dfield; + dict_index_t* sys_index; + btr_pcur_t pcur; + mtr_t mtr; + dulint new_id; + char* sql; + que_thr_t* thr; + que_t* graph = NULL; + +/* How do we prevent crashes caused by ongoing operations on the table? Old +operations could try to access non-existent pages. + +1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock +on the table before we can do TRUNCATE TABLE. Then there are no running +queries on the table. +2) Purge and rollback: we assign a new table id for the table. Since purge and +rollback look for the table based on the table id, they see the table as +'dropped' and discard their operations. +3) Insert buffer: TRUNCATE TABLE is analogous to DROP TABLE, so we do not +have to remove insert buffer records, as the insert buffer works at a low +level. If a freed page is later reallocated, the allocator will remove +the ibuf entries for it. + +TODO: when we truncate *.ibd files (analogous to DISCARD TABLESPACE), we +will have to remove we remove all entries for the table in the insert +buffer tree! + +4) Linear readahead and random readahead: we use the same method as in 3) to +discard ongoing operations. (This will only be relevant for TRUNCATE TABLE +by DISCARD TABLESPACE.) +5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we +do not allow the TRUNCATE. We also reserve the data dictionary latch. */ + + static const char renumber_tablespace_proc[] = + "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n" + "old_id CHAR;\n" + "new_id CHAR;\n" + "old_id_low INT;\n" + "old_id_high INT;\n" + "new_id_low INT;\n" + "new_id_high INT;\n" + "BEGIN\n" + "old_id_high := %lu;\n" + "old_id_low := %lu;\n" + "new_id_high := %lu;\n" + "new_id_low := %lu;\n" + "old_id := CONCAT(TO_BINARY(old_id_high, 4), TO_BINARY(old_id_low, 4));\n" + "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n" + "UPDATE SYS_TABLES SET ID = new_id\n" + "WHERE ID = old_id;\n" + "UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n" + "WHERE TABLE_ID = old_id;\n" + "UPDATE SYS_INDEXES SET TABLE_ID = new_id\n" + "WHERE TABLE_ID = old_id;\n" + "COMMIT WORK;\n" + "END;\n"; + + ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); + ut_ad(table); + + if (srv_created_new_raw) { + fputs( + "InnoDB: A new raw disk partition was initialized or\n" + "InnoDB: innodb_force_recovery is on: we do not allow\n" + "InnoDB: database modifications by the user. Shut down\n" + "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); + + return(DB_ERROR); + } + + trx->op_info = "truncating table"; + + trx_start_if_not_started(trx); + + /* Serialize data dictionary operations with dictionary mutex: + no deadlocks can occur then in these operations */ + + if (trx->dict_operation_lock_mode != RW_X_LATCH) { + /* Prevent foreign key checks etc. while we are truncating the + table */ + + row_mysql_lock_data_dictionary(trx); + + locked_dictionary = TRUE; + } + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(dict_sys->mutex))); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + + /* Check if the table is referenced by foreign key constraints from + some other table (not the table itself) */ + + foreign = UT_LIST_GET_FIRST(table->referenced_list); + + while (foreign && foreign->foreign_table == table) { + foreign = UT_LIST_GET_NEXT(referenced_list, foreign); + } + + if (foreign && trx->check_foreigns) { + FILE* ef = dict_foreign_err_file; + + /* We only allow truncating a referenced table if + FOREIGN_KEY_CHECKS is set to 0 */ + + mutex_enter(&dict_foreign_err_mutex); + rewind(ef); + ut_print_timestamp(ef); + + fputs(" Cannot truncate table ", ef); + ut_print_name(ef, trx, table->name); + fputs("\n" + "because it is referenced by ", ef); + ut_print_name(ef, trx, foreign->foreign_table_name); + putc('\n', ef); + mutex_exit(&dict_foreign_err_mutex); + + err = DB_ERROR; + goto funct_exit; + } + + if (table->n_mysql_handles_opened > 1) { + ut_print_timestamp(stderr); +fputs(" InnoDB: Warning: MySQL is trying to truncate table ", stderr); + ut_print_name(stderr, trx, table->name); + fputs("\n" +"InnoDB: though there are still open handles to it.\n", stderr); + err = DB_ERROR; + + goto funct_exit; + } + + /* TODO: could we replace the counter n_foreign_key_checks_running + with lock checks on the table? Acquire here an exclusive lock on the + table, and rewrite lock0lock.c and the lock wait in srv0srv.c so that + they can cope with the table having been truncated here? Foreign key + checks take an IS or IX lock on the table. */ + + if (table->n_foreign_key_checks_running > 0) { + ut_print_timestamp(stderr); + fputs(" InnoDB: You are trying to truncate table ", stderr); + ut_print_name(stderr, trx, table->name); + fputs("\n" +"InnoDB: though there is a foreign key check running on it.\n", + stderr); + err = DB_ERROR; + + goto funct_exit; + } + + /* Remove any locks there are on the table or its records */ + + lock_reset_all_on_table(table); + + trx->dict_operation = TRUE; + trx->table_id = table->id; + + /* scan SYS_INDEXES for all indexes of the table */ + heap = mem_heap_create(800); + + tuple = dtuple_create(heap, 1); + dfield = dtuple_get_nth_field(tuple, 0); + + buf = mem_heap_alloc(heap, 8); + mach_write_to_8(buf, table->id); + + dfield_set_data(dfield, buf, 8); + sys_index = dict_table_get_first_index(dict_sys->sys_indexes); + dict_index_copy_types(tuple, sys_index, 1); + + mtr_start(&mtr); + btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, + BTR_MODIFY_LEAF, &pcur, &mtr); + for (;;) { + rec_t* rec; + const byte* field; + ulint len; + + if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { + /* The end of SYS_INDEXES has been reached. */ + break; + } + + rec = btr_pcur_get_rec(&pcur); + + field = rec_get_nth_field_old(rec, 0, &len); + ut_ad(len == 8); + + if (memcmp(buf, field, len) != 0) { + /* End of indexes for the table (TABLE_ID mismatch). */ + break; + } + + if (rec_get_deleted_flag(rec, FALSE)) { + /* The index has been dropped. */ + continue; + } + + dict_truncate_index_tree(table, rec, &mtr); + + btr_pcur_move_to_next_user_rec(&pcur, &mtr); + } + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); + + mem_heap_empty(heap); + sql = mem_heap_alloc(heap, (sizeof renumber_tablespace_proc) + 40); + sprintf(sql, renumber_tablespace_proc, + (ulong) ut_dulint_get_high(table->id), + (ulong) ut_dulint_get_low(table->id), + (ulong) ut_dulint_get_high(new_id), + (ulong) ut_dulint_get_low(new_id)); + + graph = pars_sql(sql); + + ut_a(graph); + + mem_heap_free(heap); + + graph->trx = trx; + trx->graph = NULL; + + graph->fork_type = QUE_FORK_MYSQL_INTERFACE; + + thr = que_fork_start_command(graph); + ut_a(thr); + + que_run_threads(thr); + + que_graph_free(graph); + + err = trx->error_state; + + if (err != DB_SUCCESS) { + trx->error_state = DB_SUCCESS; + trx_general_rollback_for_mysql(trx, FALSE, NULL); + trx->error_state = DB_SUCCESS; + ut_print_timestamp(stderr); +fputs(" InnoDB: Unable to assign a new identifier to table ", stderr); + ut_print_name(stderr, trx, table->name); + fputs("\n" +"InnoDB: after truncating it. Background processes may corrupt the table!\n", + stderr); + err = DB_ERROR; + } else { + dict_table_change_id_in_cache(table, new_id); + } + + dict_table_autoinc_initialize(table, 0); + dict_update_statistics(table); + + trx_commit_for_mysql(trx); + +funct_exit: + + if (locked_dictionary) { + row_mysql_unlock_data_dictionary(trx); + } + + trx->op_info = ""; + + srv_wake_master_thread(); + + return((int) err); +} + /************************************************************************* Drops a table for MySQL. If the name of the table to be dropped is equal with one of the predefined magic table names, then this also stops printing diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index f3a5f911171..8512e796a72 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2271,9 +2271,6 @@ row_sel_field_store_in_mysql_format( dest = row_mysql_store_var_len(dest, len); ut_memcpy(dest, data, len); - /* Pad with trailing spaces */ - memset(dest + len, ' ', col_len - len); - /* ut_ad(col_len >= len + 2); No real var implemented in MySQL yet! */ @@ -2406,7 +2403,45 @@ row_sel_store_mysql_rec( mysql_rec + templ->mysql_col_offset, templ->mysql_col_len, data, len, templ->type, templ->is_unsigned); - + + if (templ->type == DATA_VARCHAR + || templ->type == DATA_VARMYSQL + || templ->type == DATA_BINARY) { + /* Pad with trailing spaces */ + data = mysql_rec + templ->mysql_col_offset; + + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, we + hardcode the charset-collation codes here. + 5.0 will use a different approach. */ + if (templ->charset == 35 + || templ->charset == 90 + || (templ->charset >= 128 + && templ->charset <= 144)) { + /* space=0x0020 */ + ulint col_len = templ->mysql_col_len; + + ut_a(!(col_len & 1)); + if (len & 1) { + /* A 0x20 has been stripped + from the column. + Pad it back. */ + goto pad_0x20; + } + /* Pad the rest of the string + with 0x0020 */ + while (len < col_len) { + data[len++] = 0x00; + pad_0x20: + data[len++] = 0x20; + } + } else { + /* space=0x20 */ + memset(data + len, 0x20, + templ->mysql_col_len - len); + } + } + /* Cleanup */ if (extern_field_heap) { mem_heap_free(extern_field_heap); @@ -2442,8 +2477,29 @@ row_sel_store_mysql_rec( pad_char = '\0'; } - memset(mysql_rec + templ->mysql_col_offset, pad_char, - templ->mysql_col_len); + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, + we hardcode the charset-collation codes here. + 5.0 will use a different approach. */ + if (templ->charset == 35 + || templ->charset == 90 + || (templ->charset >= 128 + && templ->charset <= 144)) { + /* There are two bytes per char, so the length + has to be an even number. */ + ut_a(!(templ->mysql_col_len & 1)); + data = mysql_rec + templ->mysql_col_offset; + len = templ->mysql_col_len; + /* Pad with 0x0020. */ + while (len >= 2) { + *data++ = 0x00; + *data++ = 0x20; + len -= 2; + } + } else { + memset(mysql_rec + templ->mysql_col_offset, + pad_char, templ->mysql_col_len); + } } } diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 061bdb82d3e..983a8306773 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -61,6 +61,11 @@ dulint srv_start_lsn; /* Log sequence number at shutdown */ dulint srv_shutdown_lsn; +#ifdef HAVE_DARWIN_THREADS +# include +ibool srv_have_fullfsync = FALSE; +#endif + ibool srv_start_raw_disk_in_use = FALSE; static ibool srv_start_has_been_called = FALSE; @@ -935,6 +940,28 @@ innobase_start_or_create_for_mysql(void) ulint i; ibool srv_file_per_table_original_value = srv_file_per_table; mtr_t mtr; +#ifdef HAVE_DARWIN_THREADS +# ifdef F_FULLFSYNC + /* This executable has been compiled on Mac OS X 10.3 or later. + Assume that F_FULLFSYNC is available at run-time. */ + srv_have_fullfsync = TRUE; +# else /* F_FULLFSYNC */ + /* This executable has been compiled on Mac OS X 10.2 + or earlier. Determine if the executable is running + on Mac OS X 10.3 or later. */ + struct utsname utsname; + if (uname(&utsname)) { + fputs("InnoDB: cannot determine Mac OS X version!\n", stderr); + } else { + srv_have_fullfsync = strcmp(utsname.release, "7.") >= 0; + } + if (!srv_have_fullfsync) { + fputs( +"InnoDB: On Mac OS X, fsync() may be broken on internal drives,\n" +"InnoDB: making transactions unsafe!\n", stderr); + } +# endif /* F_FULLFSYNC */ +#endif /* HAVE_DARWIN_THREADS */ if (sizeof(ulint) != sizeof(void*)) { fprintf(stderr, diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 29c6f469098..7c6b4e31ab5 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -857,6 +857,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename) err: /* free up memory allocated with _init, usually */ (*options->local_infile_end)(li_ptr); + my_free(buf, MYF(0)); DBUG_RETURN(result); } @@ -1509,7 +1510,7 @@ ulong STDCALL mysql_thread_id(MYSQL *mysql) const char * STDCALL mysql_character_set_name(MYSQL *mysql) { - return mysql->charset->name; + return mysql->charset->csname; } diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 17410f02fe2..4cd53216434 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -42,7 +42,7 @@ sqlexamplessources = ha_example.cc ha_archive.cc ha_tina.cc noinst_HEADERS = embedded_priv.h emb_qcache.h sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ - ha_innodb.cc ha_berkeley.cc ha_heap.cc \ + ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_federated.cc \ ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \ hostname.cc init.cc password.c \ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \ diff --git a/myisam/mi_open.c b/myisam/mi_open.c index ab76235e6ef..9a6cfe9f33c 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -148,9 +148,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) goto err; } /* Don't call realpath() if the name can't be a link */ - if (strcmp(name_buff, org_name)) - (void) my_readlink(index_name, org_name, MYF(0)); - else + if (!strcmp(name_buff, org_name) || + my_readlink(index_name, org_name, MYF(0)) == -1) (void) strmov(index_name, org_name); (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,2+4+16); diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl index 14ea37dbb75..017ba11645b 100644 --- a/mysql-test/lib/mtr_io.pl +++ b/mysql-test/lib/mtr_io.pl @@ -35,13 +35,72 @@ sub mtr_get_opts_from_file ($) { while ( ) { chomp; - s/\$MYSQL_TEST_DIR/$::glob_mysql_test_dir/g; - push(@args, split(' ', $_)); + + # --set-variable=init_connect=set @a='a\\0c' + s/^\s+//; # Remove leading space + s/\s+$//; # Remove ending space + + # This is strange, but we need to fill whitespace inside + # quotes with something, to remove later. We do this to + # be able to split on space. Else, we have trouble with + # options like + # + # --someopt="--insideopt1 --insideopt2" + # + # But still with this, we are not 100% sure it is right, + # we need a shell to do it right. + +# print STDERR "\n"; +# print STDERR "AAA: $_\n"; + + s/\'([^\'\"]*)\'/unspace($1,"\x0a")/ge; + s/\"([^\'\"]*)\"/unspace($1,"\x0b")/ge; + s/\'([^\'\"]*)\'/unspace($1,"\x0a")/ge; + s/\"([^\'\"]*)\"/unspace($1,"\x0b")/ge; + +# print STDERR "BBB: $_\n"; + +# foreach my $arg (/(--?\w.*?)(?=\s+--?\w|$)/) + + # FIXME ENV vars should be expanded!!!! + + foreach my $arg (split(/[ \t]+/)) + { + $arg =~ tr/\x11\x0a\x0b/ \'\"/; # Put back real chars + # The outermost quotes has to go + $arg =~ s/^([^\'\"]*)\'(.*)\'([^\'\"]*)$/$1$2$3/ + or $arg =~ s/^([^\'\"]*)\"(.*)\"([^\'\"]*)$/$1$2$3/; + $arg =~ s/\\\\/\\/g; + + $arg =~ s/\$\{(\w+)\}/envsubst($1)/ge; + $arg =~ s/\$(\w+)/envsubst($1)/ge; + +# print STDERR "ARG: $arg\n"; + push(@args, $arg); + } } close FILE; return \@args; } +sub envsubst { + my $string= shift; + + if ( ! defined $ENV{$string} ) + { + mtr_error("opt file referense \$$string that is unknown"); + } + + return $ENV{$string}; +} + +sub unspace { + my $string= shift; + my $quote= shift; + $string =~ s/[ \t]/\x11/g; + return "$quote$string$quote"; +} + sub mtr_fromfile ($) { my $file= shift; diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 8c584802b8e..e832468d0cb 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -4,7 +4,7 @@ # and is part of the translation of the Bourne shell script with the # same name. -use Carp qw(cluck); +#use Carp qw(cluck); use strict; use POSIX ":sys_wait_h"; @@ -64,18 +64,6 @@ sub spawn_impl ($$$$$$$) { 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"; @@ -85,17 +73,21 @@ sub spawn_impl ($$$$$$$) { print STDERR "#### ", "STDERR $error\n" if $error; if ( $join ) { - print STDERR "#### ", "run"; + print STDERR "#### ", "RUN "; } else { - print STDERR "#### ", "spawn"; + print STDERR "#### ", "SPAWN "; } print STDERR "$path ", join(" ",@$arg_list_t), "\n"; print STDERR "#### ", "-" x 78, "\n"; } my $pid= fork(); + if ( ! defined $pid ) + { + mtr_error("$path ($pid) can't be forked"); + } if ( $pid ) { @@ -104,17 +96,22 @@ sub spawn_impl ($$$$$$$) { { # We run a command and wait for the result # FIXME this need to be improved - waitpid($pid,0); + my $res= waitpid($pid,0); + + if ( $res == -1 ) + { + mtr_error("$path ($pid) got lost somehow"); + } my $exit_value= $? >> 8; my $signal_num= $? & 127; my $dumped_core= $? & 128; if ( $signal_num ) { - mtr_error("spawn got signal $signal_num"); + mtr_error("$path ($pid) got signal $signal_num"); } if ( $dumped_core ) { - mtr_error("spawn dumped core"); + mtr_error("$path ($pid) dumped core"); } return $exit_value; } @@ -326,7 +323,8 @@ sub mtr_stop_mysqld_servers ($$) { mtr_init_args(\$args); mtr_add_arg($args, "--no-defaults"); - mtr_add_arg($args, "-uroot"); + mtr_add_arg($args, "--user=%s", $::opt_user); + mtr_add_arg($args, "--password="); if ( -e $srv->{'sockfile'} ) { mtr_add_arg($args, "--socket=%s", $srv->{'sockfile'}); @@ -336,7 +334,8 @@ sub mtr_stop_mysqld_servers ($$) { 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_timeout=20"); + mtr_add_arg($args, "--protocol=tcp"); # FIXME new thing, will it help?! mtr_add_arg($args, "shutdown"); # We don't wait for termination of mysqladmin mtr_spawn($::exe_mysqladmin, $args, @@ -361,6 +360,10 @@ sub mtr_stop_mysqld_servers ($$) { { last PIDSOCKFILEREMOVED; } + if ( $loop % 20 == 1 ) + { + mtr_warning("Still processes alive after 10 seconds, retrying for $loop seconds..."); + } mtr_debug("Sleep for 1 second waiting for pid and socket file removal"); sleep(1); # One second } @@ -464,4 +467,40 @@ sub stop_reap_all { $SIG{CHLD}= 'DEFAULT'; } +############################################################################## +# +# Wait for a file to be created +# +############################################################################## + + +sub sleep_until_file_created ($$) { + my $pidfile= shift; + my $timeout= shift; + + my $loop= $timeout; + while ( $loop-- ) + { + if ( -r $pidfile ) + { + return; + } + mtr_debug("Sleep for 1 second waiting for creation of $pidfile"); + + if ( $loop % 20 == 1 ) + { + mtr_warning("Waiting for $pidfile to be created, still trying for $loop seconds..."); + } + + sleep(1); + } + + if ( ! -r $pidfile ) + { + mtr_error("No $pidfile was created"); + } +} + + + 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 01729aa1018..3bbdb48d98a 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -232,6 +232,8 @@ our $opt_local_master; our $master; # Will be struct in C our $slave; +our $opt_master_myport; +our $opt_slave_myport; our $opt_ndbcluster_port; our $opt_ndbconnectstring; @@ -248,16 +250,10 @@ our $opt_skip_rpl; our $opt_skip_test; our $opt_sleep; - our $opt_ps_protocol; -# FIXME all of the sleep time handling needs cleanup -our $opt_sleep_time_after_restart= 1; -our $opt_sleep_time_for_delete= 10; -our $opt_sleep_time_for_first_master= 400; # enough time create innodb tables -our $opt_sleep_time_for_second_master= 400; -our $opt_sleep_time_for_first_slave= 400; -our $opt_sleep_time_for_second_slave= 30; +our $opt_sleep_time_after_restart= 1; +our $opt_sleep_time_for_delete= 10; our $opt_socket; @@ -270,7 +266,7 @@ our $opt_strace_client; our $opt_timer; - +our $opt_user; our $opt_user_test; our $opt_valgrind; @@ -299,6 +295,7 @@ sub main (); sub initial_setup (); sub command_line_setup (); sub executable_setup (); +sub environment_setup (); sub kill_and_cleanup (); sub collect_test_cases ($); sub sleep_until_file_created ($$); @@ -332,6 +329,7 @@ sub main () { initial_setup(); command_line_setup(); executable_setup(); + environment_setup(); signal_setup(); if ( $opt_gcov ) @@ -449,12 +447,9 @@ sub command_line_setup () { $path_manager_log= "$glob_mysql_test_dir/var/log/manager.log"; $opt_current_test= "$glob_mysql_test_dir/var/log/current_test"; - my $opt_master_myport= 9306; - my $opt_slave_myport= 9308; - $opt_ndbcluster_port= 9350; - $opt_sleep_time_for_delete= 10; - - my $opt_user; + $opt_master_myport= 9306; + $opt_slave_myport= 9308; + $opt_ndbcluster_port= 9350; # Read the command line # Note: Keep list, and the order, in sync with usage at end of this file @@ -545,6 +540,7 @@ sub command_line_setup () { $master->[0]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/master.pid"; $master->[0]->{'path_mysock'}= "$opt_tmpdir/master.sock"; $master->[0]->{'path_myport'}= $opt_master_myport; + $master->[0]->{'start_timeout'}= 400; # enough time create innodb tables $master->[1]->{'path_myddir'}= "$glob_mysql_test_dir/var/master1-data"; $master->[1]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/master1.err"; @@ -552,6 +548,7 @@ sub command_line_setup () { $master->[1]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/master1.pid"; $master->[1]->{'path_mysock'}= "$opt_tmpdir/master1.sock"; $master->[1]->{'path_myport'}= $opt_master_myport + 1; + $master->[1]->{'start_timeout'}= 400; # enough time create innodb tables $slave->[0]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave-data"; $slave->[0]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave.err"; @@ -559,6 +556,7 @@ sub command_line_setup () { $slave->[0]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave.pid"; $slave->[0]->{'path_mysock'}= "$opt_tmpdir/slave.sock"; $slave->[0]->{'path_myport'}= $opt_slave_myport; + $slave->[0]->{'start_timeout'}= 400; $slave->[1]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave1-data"; $slave->[1]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave1.err"; @@ -566,6 +564,7 @@ sub command_line_setup () { $slave->[1]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave1.pid"; $slave->[1]->{'path_mysock'}= "$opt_tmpdir/slave1.sock"; $slave->[1]->{'path_myport'}= $opt_slave_myport + 1; + $slave->[1]->{'start_timeout'}= 30; $slave->[2]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave2-data"; $slave->[2]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave2.err"; @@ -573,6 +572,7 @@ sub command_line_setup () { $slave->[2]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave2.pid"; $slave->[2]->{'path_mysock'}= "$opt_tmpdir/slave2.sock"; $slave->[2]->{'path_myport'}= $opt_slave_myport + 2; + $slave->[2]->{'start_timeout'}= 30; # Do sanity checks of command line arguments @@ -594,16 +594,6 @@ sub command_line_setup () { $master->[0]->{'path_mysock'}= $opt_socket; } - # -------------------------------------------------------------------------- - # Set LD_LIBRARY_PATH if we are using shared libraries - # -------------------------------------------------------------------------- - $ENV{'LD_LIBRARY_PATH'}= - "$glob_basedir/lib:$glob_basedir/libmysql/.libs" . - ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : ""); - $ENV{'DYLD_LIBRARY_PATH'}= - "$glob_basedir/lib:$glob_basedir/libmysql/.libs" . - ($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : ""); - # -------------------------------------------------------------------------- # Look at the command line options and set script flags # -------------------------------------------------------------------------- @@ -741,7 +731,7 @@ sub executable_setup () { } else { - mtr_error("Cannot find embedded server 'mysqltest'"); + mtr_error("Can't find embedded server 'mysqltest'"); } $path_tests_bindir= "$glob_basedir/libmysqld/examples"; } @@ -831,6 +821,41 @@ sub executable_setup () { } +############################################################################## +# +# Set environment to be used by childs of this process +# +############################################################################## + +# Note that some env is setup in spawn/run, in "mtr_process.pl" + +sub environment_setup () { + + # -------------------------------------------------------------------------- + # Set LD_LIBRARY_PATH if we are using shared libraries + # -------------------------------------------------------------------------- + + $ENV{'LD_LIBRARY_PATH'}= + "$glob_basedir/lib:$glob_basedir/libmysql/.libs" . + ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : ""); + $ENV{'DYLD_LIBRARY_PATH'}= + "$glob_basedir/lib:$glob_basedir/libmysql/.libs" . + ($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : ""); + + # -------------------------------------------------------------------------- + # Also command lines in .opt files may contain env vars + # -------------------------------------------------------------------------- + + $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 we get a ^C, we try to clean up before termination @@ -922,6 +947,7 @@ sub collect_test_cases ($) { # ---------------------------------------------------------------------- $tinfo->{'path'}= $path; + $tinfo->{'timezone'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work if ( defined mtr_match_prefix($tname,"rpl") ) { @@ -967,7 +993,7 @@ sub collect_test_cases ($) { if ( defined $value ) { - $ENV{'TZ'}= $value; # FIXME pass this on somehow.... + $tinfo->{'timezone'}= $value; $extra_master_opt= []; $tinfo->{'master_restart'}= 0; last; @@ -1071,6 +1097,7 @@ sub kill_and_cleanup () { # leftovers from previous runs. mtr_report("Killing Possible Leftover Processes"); + mkpath("$glob_mysql_test_dir/var/log"); # Needed for mysqladmin log mtr_kill_leftovers(); } @@ -1092,52 +1119,28 @@ sub kill_and_cleanup () { mkpath("$glob_mysql_test_dir/var/tmp"); mkpath($opt_tmpdir); + # FIXME do we really need to create these all, or are they + # created for us when tables are created? + rmtree("$master->[0]->{'path_myddir'}"); - mkpath("$master->[0]->{'path_myddir'}/mysql"); # Need to create subdir?! + mkpath("$master->[0]->{'path_myddir'}/mysql"); mkpath("$master->[0]->{'path_myddir'}/test"); rmtree("$master->[1]->{'path_myddir'}"); - mkpath("$master->[1]->{'path_myddir'}/mysql"); # Need to create subdir?! + mkpath("$master->[1]->{'path_myddir'}/mysql"); mkpath("$master->[1]->{'path_myddir'}/test"); rmtree("$slave->[0]->{'path_myddir'}"); - mkpath("$slave->[0]->{'path_myddir'}/mysql"); # Need to create subdir?! + mkpath("$slave->[0]->{'path_myddir'}/mysql"); mkpath("$slave->[0]->{'path_myddir'}/test"); rmtree("$slave->[1]->{'path_myddir'}"); - mkpath("$slave->[1]->{'path_myddir'}/mysql"); # Need to create subdir?! + mkpath("$slave->[1]->{'path_myddir'}/mysql"); mkpath("$slave->[1]->{'path_myddir'}/test"); rmtree("$slave->[2]->{'path_myddir'}"); - mkpath("$slave->[2]->{'path_myddir'}/mysql"); # Need to create subdir?! + mkpath("$slave->[2]->{'path_myddir'}/mysql"); mkpath("$slave->[2]->{'path_myddir'}/test"); - - $opt_wait_for_master= $opt_sleep_time_for_first_master; - $opt_wait_for_slave= $opt_sleep_time_for_first_slave; -} - - -# FIXME - -sub sleep_until_file_created ($$) { - my $pidfile= shift; - my $timeout= shift; - - my $loop= $timeout * 2; - while ( $loop-- ) - { - if ( -r $pidfile ) - { - return; - } - mtr_debug("Sleep for 1 second waiting for creation of $pidfile"); - sleep(1); - } - - if ( ! -r $pidfile ) - { - mtr_error("No $pidfile was created"); - } } @@ -1251,11 +1254,11 @@ sub run_suite () { mtr_print_thick_line(); - mtr_report("Finding Tests in $suite suite"); + mtr_report("Finding Tests in the '$suite' suite"); my $tests= collect_test_cases($suite); - mtr_report("Starting Tests in $suite suite"); + mtr_report("Starting Tests in the '$suite' suite"); mtr_print_header(); @@ -1412,6 +1415,8 @@ sub run_testcase ($) { # the preparation. # ---------------------------------------------------------------------- + $ENV{'TZ'}= $tinfo->{'timezone'}; + mtr_report_test_name($tinfo); mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); @@ -1778,6 +1783,7 @@ sub mysqld_arguments ($$$$$) { } # FIXME strange,..... + # FIXME MYSQL_MYPORT is not set anythere?! if ( $opt_local_master ) { mtr_add_arg($args, "%s--host=127.0.0.1", $prefix); @@ -1888,8 +1894,7 @@ sub mysqld_start ($$$$) { $master->[$idx]->{'path_myerr'}, "") ) { sleep_until_file_created($master->[$idx]->{'path_mypid'}, - $opt_wait_for_master); - $opt_wait_for_master= $opt_sleep_time_for_second_master; + $master->[$idx]->{'start_timeout'}); return $pid; } } @@ -1901,8 +1906,7 @@ sub mysqld_start ($$$$) { $slave->[$idx]->{'path_myerr'}, "") ) { sleep_until_file_created($slave->[$idx]->{'path_mypid'}, - $opt_wait_for_slave); - $opt_wait_for_slave= $opt_sleep_time_for_second_slave; + $master->[$idx]->{'start_timeout'}); return $pid; } } @@ -1970,7 +1974,6 @@ sub run_mysqltest ($$) { my $tinfo= shift; my $master_opts= shift; - # FIXME set where???? my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " . "--socket=$master->[0]->{'path_mysock'} --password="; if ( $opt_debug ) @@ -1992,6 +1995,9 @@ sub run_mysqltest ($$) { "$exe_mysql --host=localhost --port=$master->[0]->{'path_myport'} " . "--socket=$master->[0]->{'path_mysock'} --user=root --password="; + # 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{'MYSQL'}= $exe_mysql; $ENV{'MYSQL_DUMP'}= $cmdline_mysqldump; $ENV{'MYSQL_BINLOG'}= $exe_mysqlbinlog; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 274f91550d4..a6cbea2d1e5 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -241,6 +241,9 @@ USE_EMBEDDED_SERVER="" RESULT_EXT="" TEST_MODE="default" +NDB_MGMD_EXTRA_OPTS= +NDBD_EXTRA_OPTS= + while test $# -gt 0; do case "$1" in --embedded-server) USE_EMBEDDED_SERVER=1 USE_MANAGER=0 NO_SLAVE=1 ; \ @@ -261,6 +264,10 @@ while test $# -gt 0; do --ndb-connectstring=*) USE_NDBCLUSTER="--ndbcluster" ; USE_RUNNING_NDBCLUSTER=`$ECHO "$1" | $SED -e "s;--ndb-connectstring=;;"` ;; + --ndb_mgmd-extra-opts=*) + NDB_MGMD_EXTRA_OPTS=`$ECHO "$1" | $SED -e "s;--ndb_mgmd-extra-opts=;;"` ;; + --ndbd-extra-opts=*) + NDBD_EXTRA_OPTS=`$ECHO "$1" | $SED -e "s;--ndbd-extra-opts=;;"` ;; --tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;; --local-master) MASTER_MYPORT=3306; @@ -427,6 +434,9 @@ while test $# -gt 0; do --fast) FAST_START=1 ;; + --use-old-data) + USE_OLD_DATA=1; + ;; -- ) shift; break ;; --* ) $ECHO "Unrecognized option: $1"; exit 1 ;; * ) break ;; @@ -460,7 +470,7 @@ SMALL_SERVER="--key_buffer_size=1M --sort_buffer=256K --max_heap_table_size=1M" export MASTER_MYPORT MASTER_MYPORT1 SLAVE_MYPORT MYSQL_TCP_PORT MASTER_MYSOCK MASTER_MYSOCK1 NDBCLUSTER_BASE_PORT=`expr $NDBCLUSTER_PORT + 2` -NDBCLUSTER_OPTS="--port=$NDBCLUSTER_PORT --port-base=$NDBCLUSTER_BASE_PORT --data-dir=$MYSQL_TEST_DIR/var" +NDBCLUSTER_OPTS="--port=$NDBCLUSTER_PORT --port-base=$NDBCLUSTER_BASE_PORT --data-dir=$MYSQL_TEST_DIR/var --ndb_mgmd-extra-opts=\"$NDB_MGMD_EXTRA_OPTS\" --ndbd-extra-opts=\"$NDBD_EXTRA_OPTS\"" if [ x$SOURCE_DIST = x1 ] ; then MY_BASEDIR=$MYSQL_TEST_DIR @@ -530,6 +540,7 @@ if [ x$SOURCE_DIST = x1 ] ; then INSTALL_DB="./install_test_db" MYSQL_FIX_SYSTEM_TABLES="$BASEDIR/scripts/mysql_fix_privilege_tables" NDB_TOOLS_DIR="$BASEDIR/ndb/tools" + NDB_MGM="$BASEDIR/ndb/src/mgmclient/ndb_mgm" else if test -x "$BASEDIR/libexec/mysqld" then @@ -538,7 +549,12 @@ else MYSQLD="$VALGRIND $BASEDIR/bin/mysqld" fi CLIENT_BINDIR="$BASEDIR/bin" - TESTS_BINDIR="$BASEDIR/bin" + if test -d "$BASEDIR/tests" + then + TESTS_BINDIR="$BASEDIR/tests" + else + TESTS_BINDIR="$BASEDIR/bin" + fi MYSQL_TEST="$CLIENT_BINDIR/mysqltest" MYSQL_DUMP="$CLIENT_BINDIR/mysqldump" MYSQL_BINLOG="$CLIENT_BINDIR/mysqlbinlog" @@ -551,6 +567,7 @@ else INSTALL_DB="./install_test_db --bin" MYSQL_FIX_SYSTEM_TABLES="$CLIENT_BINDIR/mysql_fix_privilege_tables" NDB_TOOLS_DIR="$CLIENT_BINDIR" + NDB_MGM="$CLIENT_BINDIR/ndb_mgm" if test -d "$BASEDIR/share/mysql/english" then LANGUAGE="$BASEDIR/share/mysql/english/" @@ -600,6 +617,7 @@ MYSQL="$MYSQL --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --u export MYSQL MYSQL_DUMP MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES export CLIENT_BINDIR TESTS_BINDIR CHARSETSDIR export NDB_TOOLS_DIR +export NDB_MGM MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \ --user=$DBUSER --password=$DBPASSWD --silent -v --skip-safemalloc \ @@ -768,12 +786,14 @@ report_stats () { mysql_install_db () { $ECHO "Removing Stale Files" - $RM -rf $MASTER_MYDDIR $MASTER_MYDDIR"1" $SLAVE_MYDDIR $MY_LOG_DIR/* - $ECHO "Installing Master Databases" - $INSTALL_DB - if [ $? != 0 ]; then + if [ -z "$USE_OLD_DATA" ]; then + $RM -rf $MASTER_MYDDIR $MASTER_MYDDIR"1" + $ECHO "Installing Master Databases" + $INSTALL_DB + if [ $? != 0 ]; then error "Could not install master test DBs" - exit 1 + exit 1 + fi fi if [ ! -z "$USE_NDBCLUSTER" ] then @@ -785,6 +805,7 @@ mysql_install_db () { fi fi $ECHO "Installing Slave Databases" + $RM -rf $SLAVE_MYDDIR $MY_LOG_DIR/* $INSTALL_DB -slave if [ $? != 0 ]; then error "Could not install slave test DBs" @@ -952,7 +973,13 @@ start_ndbcluster() else NDBCLUSTER_EXTRA_OPTS="--small" fi - ./ndb/ndbcluster $NDBCLUSTER_OPTS $NDBCLUSTER_EXTRA_OPTS --initial || exit 1 + NDB_STARTED=1 + ./ndb/ndbcluster $NDBCLUSTER_OPTS $NDBCLUSTER_EXTRA_OPTS --initial || NDB_STARTED=0 + if [ x$NDB_STARTED != x1 ] ; then + if [ x$FORCE != x1 ] ; then + exit 1 + fi + fi NDB_CONNECTSTRING="host=localhost:$NDBCLUSTER_PORT" else NDB_CONNECTSTRING="$USE_RUNNING_NDBCLUSTER" diff --git a/mysql-test/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh index 2d529f8fe0f..a86e482b2ab 100644 --- a/mysql-test/ndb/ndbcluster.sh +++ b/mysql-test/ndb/ndbcluster.sh @@ -58,6 +58,9 @@ ndb_con_op=105000 ndb_dmem=80M ndb_imem=24M +NDB_MGMD_EXTRA_OPTS= +NDBD_EXTRA_OPTS= + while test $# -gt 0; do case "$1" in --test) @@ -94,6 +97,12 @@ while test $# -gt 0; do --port-base=*) port_base=`echo "$1" | sed -e "s;--port-base=;;"` ;; + --ndb_mgmd-extra-opts=*) + NDB_MGMD_EXTRA_OPTS=`echo "$1" | sed -e "s;--ndb_mgmd-extra-opts=;;"` + ;; + --ndbd-extra-opts=*) + NDBD_EXTRA_OPTS=`echo "$1" | sed -e "s;--ndbd-extra-opts=;;"` + ;; -- ) shift; break ;; --* ) $ECHO "Unrecognized option: $1"; exit 1 ;; * ) break ;; @@ -122,8 +131,8 @@ if [ ! -x "$exec_waiter" ]; then fi exec_mgmtclient="$exec_mgmtclient --no-defaults" -exec_mgmtsrvr="$exec_mgmtsrvr --no-defaults" -exec_ndb="$exec_ndb --no-defaults" +exec_mgmtsrvr="$exec_mgmtsrvr --no-defaults $NDB_MGMD_EXTRA_OPTS" +exec_ndb="$exec_ndb --no-defaults $NDBD_EXTRA_OPTS" exec_waiter="$exec_waiter --no-defaults" ndb_host="localhost" diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 3da828ebf9c..03d0ebf5433 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -493,3 +493,7 @@ select hex(a) from t1; hex(a) F2E5F1F2 drop table t1; +create table t1 ( a timestamp ); +alter table t1 add unique ( a(1) ); +ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys +drop table t1; diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result index d4128fb1bcc..83f70a69622 100644 --- a/mysql-test/r/analyse.result +++ b/mysql-test/r/analyse.result @@ -36,16 +36,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` varchar(255) NOT NULL default '', - `Min_value` varchar(255) default NULL, - `Max_value` varchar(255) default NULL, + `Field_name` varbinary(255) NOT NULL default '', + `Min_value` varbinary(255) default NULL, + `Max_value` varbinary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` varchar(255) NOT NULL default '', - `Std` varchar(255) default NULL, - `Optimal_fieldtype` varchar(64) NOT NULL default '' + `Avg_value_or_avg_length` varbinary(255) NOT NULL default '', + `Std` varbinary(255) default NULL, + `Optimal_fieldtype` varbinary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t1 where 0=1 procedure analyse(); Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype @@ -55,16 +55,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` varchar(255) NOT NULL default '', - `Min_value` varchar(255) default NULL, - `Max_value` varchar(255) default NULL, + `Field_name` varbinary(255) NOT NULL default '', + `Min_value` varbinary(255) default NULL, + `Max_value` varbinary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` varchar(255) NOT NULL default '', - `Std` varchar(255) default NULL, - `Optimal_fieldtype` varchar(64) NOT NULL default '' + `Avg_value_or_avg_length` varbinary(255) NOT NULL default '', + `Std` varbinary(255) default NULL, + `Optimal_fieldtype` varbinary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t2; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype @@ -78,16 +78,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` varchar(255) NOT NULL default '', - `Min_value` varchar(255) default NULL, - `Max_value` varchar(255) default NULL, + `Field_name` varbinary(255) NOT NULL default '', + `Min_value` varbinary(255) default NULL, + `Max_value` varbinary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` varchar(255) NOT NULL default '', - `Std` varchar(255) default NULL, - `Optimal_fieldtype` varchar(64) NOT NULL default '' + `Avg_value_or_avg_length` varbinary(255) NOT NULL default '', + `Std` varbinary(255) default NULL, + `Optimal_fieldtype` varbinary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t2; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 5679b1d6838..1f2d60fb79a 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -98,10 +98,10 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '', `c2` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '', - `c3` varchar(1) NOT NULL default '', - `c4` varchar(1) NOT NULL default '', - `c5` varchar(3) NOT NULL default '', - `c6` varchar(3) NOT NULL default '', + `c3` varbinary(1) NOT NULL default '', + `c4` varbinary(1) NOT NULL default '', + `c5` varbinary(3) NOT NULL default '', + `c6` varbinary(3) NOT NULL default '', `c7` double(3,1) NOT NULL default '0.0', `c8` double(3,1) NOT NULL default '0.0', `c9` double(3,1) default NULL @@ -149,8 +149,8 @@ t1 CREATE TABLE `t1` ( `COALESCE(1.0)` double(3,1) NOT NULL default '0.0', `COALESCE('a')` varchar(1) NOT NULL default '', `COALESCE(1,1.0)` double(3,1) NOT NULL default '0.0', - `COALESCE(1,'1')` varchar(1) NOT NULL default '', - `COALESCE(1.1,'1')` varchar(3) NOT NULL default '', + `COALESCE(1,'1')` varbinary(1) NOT NULL default '', + `COALESCE(1.1,'1')` varbinary(3) NOT NULL default '', `COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index f2e91c36f75..05d1ba026ba 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -204,7 +204,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 drop table t1; SET SESSION storage_engine="gemini"; ERROR 42000: Unknown table engine 'gemini' @@ -216,7 +216,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 SET SESSION storage_engine=default; drop table t1; create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2)); @@ -361,7 +361,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 drop table t1; SET SESSION storage_engine="gemini"; ERROR 42000: Unknown table engine 'gemini' @@ -373,7 +373,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 SET SESSION storage_engine=default; drop table t1; create table t1(a int,b int,c int unsigned,d date,e char,f datetime,g time,h blob); diff --git a/mysql-test/r/ctype_cp932.result b/mysql-test/r/ctype_cp932.result index c5e57d996fd..2661ff5e3c9 100755 --- a/mysql-test/r/ctype_cp932.result +++ b/mysql-test/r/ctype_cp932.result @@ -11315,3 +11315,23 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; +SET collation_connection='cp932_japanese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +cp932_japanese_ci 6109 +cp932_japanese_ci 61 +cp932_japanese_ci 6120 +drop table t1; +SET collation_connection='cp932_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +cp932_bin 6109 +cp932_bin 61 +cp932_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_eucjpms.result b/mysql-test/r/ctype_eucjpms.result index f3c22a55a54..a07ff9b28be 100755 --- a/mysql-test/r/ctype_eucjpms.result +++ b/mysql-test/r/ctype_eucjpms.result @@ -9785,3 +9785,23 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; +SET collation_connection='eucjpms_japanese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +eucjpms_japanese_ci 6109 +eucjpms_japanese_ci 61 +eucjpms_japanese_ci 6120 +drop table t1; +SET collation_connection='eucjpms_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +eucjpms_bin 6109 +eucjpms_bin 61 +eucjpms_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 175a02b63f1..a6ca59fc62b 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -528,7 +528,7 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 95 User var 1 135 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci master-bin.000001 135 Query 1 218 use `test`; insert into t2 values (@v) /*!40019 SET @@session.max_insert_delayed_threads=0*/; -SET @`v`:=_ucs2 0x006100620063 COLLATE ucs2_general_ci; +SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`; use test; SET TIMESTAMP=10000; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index f1edcdbdef5..faab013559a 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -413,7 +413,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 default NULL, UNIQUE KEY `a` USING HASH (`c`(1)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); ERROR 23000: Duplicate entry 'aa' for key 1 @@ -449,7 +449,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 default NULL, UNIQUE KEY `a` USING BTREE (`c`(1)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); ERROR 23000: Duplicate entry 'aa' for key 1 @@ -571,7 +571,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 collate utf8_bin default NULL, UNIQUE KEY `a` USING HASH (`c`(1)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); ERROR 23000: Duplicate entry 'aa' for key 1 @@ -607,7 +607,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 collate utf8_bin default NULL, UNIQUE KEY `a` USING BTREE (`c`(1)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); ERROR 23000: Duplicate entry 'aa' for key 1 @@ -849,3 +849,15 @@ utf8_bin 6109 utf8_bin 61 utf8_bin 6120 drop table t1; +CREATE TABLE t1 ( +user varchar(255) NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES ('one'),('two'); +SELECT CHARSET('a'); +CHARSET('a') +utf8 +SELECT user, CONCAT('<', user, '>') AS c FROM t1; +user c +one +two +DROP TABLE t1; diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index dfaf5758699..06c1759bf1d 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -457,6 +457,11 @@ group_concat(distinct b order by b) Warnings: Warning 1260 2 line(s) were cut by GROUP_CONCAT() drop table t1; +CREATE TABLE t1 (id int); +SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; +gc +NULL +DROP TABLE t1; create table t1 (a char(3), b char(20), primary key (a, b)); insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English'); select group_concat(a) from t1 group by b; diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index fa603fd16d5..f75fe0d1627 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -157,6 +157,14 @@ a bbbb цццц drop table t1; +create table t1 (a char(10) character set latin1 not null); +insert into t1 values ('a'),('b'),('c'); +select a from t1 where a IN ('a','b','c') order by a; +a +a +b +c +drop table t1; set names latin1; select '1.0' in (1,2); '1.0' in (1,2) diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index f80b0281dd8..6556d2be6ad 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -107,13 +107,16 @@ timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") --23:59:59.999999 +-24:00:00.000001 select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); timediff("1997-12-31 23:59:59.000001","23:59:59.000001") NULL select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001") -00:00:00.000001 +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); +timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50") +-00:00:00.000001 select maketime(10,11,12); maketime(10,11,12) 10:11:12 @@ -185,7 +188,7 @@ f8 date YES NULL f9 time YES NULL select * from t1; f1 f2 f3 f4 f5 f6 f7 f8 f9 -1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -23:59:59 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 +1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 create table test(t1 datetime, t2 time, t3 time, t4 datetime); insert into test values ('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'), diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 2399099b478..1f78e5098f8 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -466,7 +466,7 @@ collation(hex(130)) coercibility(hex(130)) latin1_swedish_ci 3 select collation(char(130)), coercibility(hex(130)); collation(char(130)) coercibility(hex(130)) -binary 3 +latin1_swedish_ci 3 select collation(format(130,10)), coercibility(format(130,10)); collation(format(130,10)) coercibility(format(130,10)) latin1_swedish_ci 3 diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index 4d5aabb8b3a..f79bcf3f1dd 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -266,7 +266,7 @@ t1 CREATE TABLE `t1` ( `v` varchar(10) default NULL, `c` char(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 create table t2 like t1; show create table t2; Table Create Table @@ -274,7 +274,7 @@ t2 CREATE TABLE `t2` ( `v` varchar(10) default NULL, `c` char(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 create table t3 select * from t1; show create table t3; Table Create Table @@ -282,7 +282,7 @@ t3 CREATE TABLE `t3` ( `v` varchar(10) default NULL, `c` char(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 alter table t1 modify c varchar(10); show create table t1; Table Create Table @@ -290,7 +290,7 @@ t1 CREATE TABLE `t1` ( `v` varchar(10) default NULL, `c` varchar(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 alter table t1 modify v char(10); show create table t1; Table Create Table @@ -298,7 +298,7 @@ t1 CREATE TABLE `t1` ( `v` char(10) default NULL, `c` varchar(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 alter table t1 modify t varchar(10); Warnings: Warning 1265 Data truncated for column 't' at row 2 @@ -308,7 +308,7 @@ t1 CREATE TABLE `t1` ( `v` char(10) default NULL, `c` varchar(10) default NULL, `t` varchar(10) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 select concat('*',v,'*',c,'*',t,'*') from t1; concat('*',v,'*',c,'*',t,'*') *+*+*+ * @@ -324,7 +324,7 @@ t1 CREATE TABLE `t1` ( KEY `v` (`v`), KEY `c` (`c`), KEY `t` (`t`(10)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 select count(*) from t1; count(*) 270 @@ -559,7 +559,7 @@ t1 CREATE TABLE `t1` ( KEY `v` USING BTREE (`v`), KEY `c` USING BTREE (`c`), KEY `t` USING BTREE (`t`(10)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 select count(*) from t1; count(*) 270 @@ -650,7 +650,7 @@ t1 CREATE TABLE `t1` ( KEY `v` (`v`(5)), KEY `c` (`c`(5)), KEY `t` (`t`(5)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 drop table t1; create table t1 (v varchar(65530), key(v(10))); show create table t1; @@ -658,7 +658,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `v` varchar(65530) default NULL, KEY `v` (`v`(10)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values(repeat('a',65530)); select length(v) from t1 where v=repeat('a',65530); length(v) diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index d1914844839..4c6be698749 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1,t2; create table t1 ( key1 int not null, diff --git a/mysql-test/r/index_merge_ror_cpk.result b/mysql-test/r/index_merge_ror_cpk.result index ba8efe42bd6..c344cef5db9 100644 --- a/mysql-test/r/index_merge_ror_cpk.result +++ b/mysql-test/r/index_merge_ror_cpk.result @@ -26,7 +26,7 @@ primary key (pk1, pk2) ) engine=innodb; explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref PRIMARY,key1 PRIMARY 4 const 1 Using where +1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 9 Using where select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2 1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2 diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index e6793843c93..9bf4ee28b3b 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -478,7 +478,7 @@ character_sets CREATE TEMPORARY TABLE `character_sets` ( `DEFAULT_COLLATE_NAME` varchar(64) NOT NULL default '', `DESCRIPTION` varchar(60) NOT NULL default '', `MAXLEN` bigint(3) NOT NULL default '0' -) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=1818 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 MAX_ROWS=1818 set names latin2; SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets; Table Create Table @@ -487,7 +487,7 @@ character_sets CREATE TEMPORARY TABLE `character_sets` ( `DEFAULT_COLLATE_NAME` varchar(64) NOT NULL default '', `DESCRIPTION` varchar(60) NOT NULL default '', `MAXLEN` bigint(3) NOT NULL default '0' -) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=1818 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 MAX_ROWS=1818 set names latin1; create table t1 select * from information_schema.CHARACTER_SETS where CHARACTER_SET_NAME like "latin1"; @@ -676,3 +676,6 @@ variable_name character_set_database collation_database skip_show_database +show global status like "Threads_running"; +Variable_name Value +Threads_running 1 diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index bdd5ac0bd63..8d1c4e3fc90 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1326,8 +1326,8 @@ truncate table t1; insert into t1 (a) values (NULL),(NULL); SELECT * from t1; a -3 -4 +1 +2 drop table t1; CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) ENGINE=INNODB; CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (`t1_id`) REFERENCES `t1`(`id 1`) ON DELETE CASCADE ) ENGINE=INNODB; @@ -1690,13 +1690,13 @@ Variable_name Value Innodb_page_size 16384 show status like "Innodb_rows_deleted"; Variable_name Value -Innodb_rows_deleted 2078 +Innodb_rows_deleted 2070 show status like "Innodb_rows_inserted"; Variable_name Value Innodb_rows_inserted 31706 show status like "Innodb_rows_read"; Variable_name Value -Innodb_rows_read 80161 +Innodb_rows_read 80153 show status like "Innodb_rows_updated"; Variable_name Value Innodb_rows_updated 29530 diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index b7343065c73..d2879e18726 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -784,32 +784,32 @@ t2.flag_value IS NULL; flag_name flag_value flag2 NULL DROP TABLE t1,t2; -CREATE TABLE invoice ( +CREATE TABLE t1 ( id int(11) unsigned NOT NULL auto_increment, text_id int(10) unsigned default NULL, PRIMARY KEY (id) ); -INSERT INTO invoice VALUES("1", "0"); -INSERT INTO invoice VALUES("2", "10"); -CREATE TABLE text_table ( +INSERT INTO t1 VALUES("1", "0"); +INSERT INTO t1 VALUES("2", "10"); +CREATE TABLE t2 ( text_id char(3) NOT NULL default '', language_id char(3) NOT NULL default '', text_data text, PRIMARY KEY (text_id,language_id) ); -INSERT INTO text_table VALUES("0", "EN", "0-EN"); -INSERT INTO text_table VALUES("0", "SV", "0-SV"); -INSERT INTO text_table VALUES("10", "EN", "10-EN"); -INSERT INTO text_table VALUES("10", "SV", "10-SV"); -SELECT invoice.id, invoice.text_id, text_table.text_data -FROM invoice LEFT JOIN text_table -ON invoice.text_id = text_table.text_id -AND text_table.language_id = 'SV' - WHERE (invoice.id LIKE '%' OR text_table.text_data LIKE '%'); +INSERT INTO t2 VALUES("0", "EN", "0-EN"); +INSERT INTO t2 VALUES("0", "SV", "0-SV"); +INSERT INTO t2 VALUES("10", "EN", "10-EN"); +INSERT INTO t2 VALUES("10", "SV", "10-SV"); +SELECT t1.id, t1.text_id, t2.text_data +FROM t1 LEFT JOIN t2 +ON t1.text_id = t2.text_id +AND t2.language_id = 'SV' + WHERE (t1.id LIKE '%' OR t2.text_data LIKE '%'); id text_id text_data 1 0 0-SV 2 10 10-SV -DROP TABLE invoice, text_table; +DROP TABLE t1, t2; CREATE TABLE t0 (a0 int PRIMARY KEY); CREATE TABLE t1 (a1 int PRIMARY KEY); CREATE TABLE t2 (a2 int); diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result index 307e918a37b..48c09f369b3 100644 --- a/mysql-test/r/metadata.result +++ b/mysql-test/r/metadata.result @@ -1,9 +1,9 @@ drop table if exists t1,t2; select 1, 1.0, -1, "hello", NULL; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def 1 8 1 1 N 32769 0 8 -def 1.0 5 3 3 N 32769 1 8 -def -1 8 2 2 N 32769 0 8 +def 1 8 1 1 N 32897 0 63 +def 1.0 5 3 3 N 32897 1 63 +def -1 8 2 2 N 32897 0 63 def hello 253 5 5 N 1 31 8 def NULL 6 0 0 Y 32896 0 63 1 1.0 -1 hello NULL diff --git a/mysql-test/r/ndb_autodiscover.result b/mysql-test/r/ndb_autodiscover.result index 35820512d39..b89b4ce1f21 100644 --- a/mysql-test/r/ndb_autodiscover.result +++ b/mysql-test/r/ndb_autodiscover.result @@ -353,12 +353,17 @@ drop table t1; use test2; drop table t2; drop database test2; -show databases; -Database -information_schema -mysql -test use test; +drop database if exists test_only_ndb_tables; +create database test_only_ndb_tables; +use test_only_ndb_tables; +create table t1 (a int primary key) engine=ndb; +select * from t1; +a +select * from t1; +ERROR HY000: Can't lock file (errno: 4009) +use test; +drop database test_only_ndb_tables; CREATE TABLE t9 ( a int NOT NULL PRIMARY KEY, b int diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 6744ffa889f..5674fbb9177 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -740,3 +740,41 @@ a b 1 2 1 1 drop table t1; +create table t1 ( +`sid` decimal(8,0) default null, +`wnid` varchar(11) not null default '', +key `wnid14` (`wnid`(4)), +key `wnid` (`wnid`) +) engine=myisam default charset=latin1; +insert into t1 (`sid`, `wnid`) values +('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), +('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), +('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), +('37994','01019090000'),('475','02070000000'),('25253','02071100000'), +('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), +('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), +('25262','02071290000'),('25263','02071300000'),('25264','02071310000'), +('25265','02071310000'),('25266','02071320000'),('25267','02071320000'), +('25269','02071330000'),('25270','02071340000'),('25271','02071350000'), +('25272','02071360000'),('25273','02071370000'),('25281','02071391000'), +('25282','02071391000'),('25283','02071399000'),('25284','02071400000'), +('25285','02071410000'),('25286','02071410000'),('25287','02071420000'), +('25288','02071420000'),('25291','02071430000'),('25290','02071440000'), +('25292','02071450000'),('25293','02071460000'),('25294','02071470000'), +('25295','02071491000'),('25296','02071491000'),('25297','02071499000'); +explain select * from t1 where wnid like '0101%' order by wnid; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range wnid14,wnid wnid 13 NULL 10 Using where +select * from t1 where wnid like '0101%' order by wnid; +sid wnid +10100 01019000000 +37986 01019000000 +37989 01019000000 +37987 01019010000 +37990 01019011000 +37991 01019011000 +37992 01019019000 +37993 01019030000 +39560 01019090000 +37994 01019090000 +drop table t1; diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 6df5f633b88..c65d11330ea 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -471,7 +471,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye prepare stmt1 from ' explain select a from t1 order by b '; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -479,7 +479,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 14 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort @@ -487,7 +487,7 @@ SET @arg00=1 ; prepare stmt1 from ' explain select a from t1 where a > ? order by b '; execute stmt1 using @arg00; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 5 N 1 31 8 @@ -495,7 +495,7 @@ def possible_keys 253 4096 7 Y 0 31 8 def key 253 64 7 Y 0 31 8 def key_len 253 4096 1 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 27 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 621a7ceeab8..50a74dfad63 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1145,7 +1145,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1153,7 +1153,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 4fc3ce54810..209a22e4a9e 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1145,7 +1145,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1153,7 +1153,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 5025e847f1a..f0be4d119bc 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1146,7 +1146,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1154,7 +1154,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 3dff34e374f..a62d00c71c0 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1188,7 +1188,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1196,7 +1196,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -4197,7 +4197,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -4205,7 +4205,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 6817c0000c5..9a922d75cdc 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -1145,7 +1145,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1153,7 +1153,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 230da5df00d..5047160bf75 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -1145,7 +1145,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1153,7 +1153,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index de74b4e6216..53882e6be69 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -315,57 +315,57 @@ insert into t2 values (1),(2); insert into t3 values (1,1),(2,2); show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL insert into t1 values (3),(4); insert into t2 values (3),(4); insert into t3 values (3,3),(4,4); show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL insert into t1 values (5); insert into t2 values (5); insert into t3 values (5,5); show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL delete from t1 where a=3; delete from t2 where b=3; delete from t3 where a=3; show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL delete from t1; delete from t2; delete from t3; show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL insert into t1 values (5); insert into t2 values (5); insert into t3 values (5,5); show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL delete from t1 where a=5; delete from t2 where b=5; delete from t3 where a=5; show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL drop table t1, t2, t3; create database mysqltest; show create database mysqltest; @@ -412,7 +412,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (i int, KEY USING HASH (i)) ENGINE=MEMORY; SHOW CREATE TABLE t1; @@ -420,7 +420,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` USING HASH (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MEMORY; SHOW CREATE TABLE t1; @@ -428,7 +428,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` USING BTREE (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; SHOW CREATE TABLE t1; @@ -459,7 +459,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; SHOW CREATE TABLE t1; @@ -474,5 +474,5 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` USING BTREE (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index e01355816c3..5492a7a65fc 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -18,7 +18,7 @@ t1 CREATE TABLE `t1` ( `email` varchar(60) character set latin2 NOT NULL default '', PRIMARY KEY (`a`), UNIQUE KEY `email` USING BTREE (`email`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC set @@sql_mode="ansi_quotes"; show variables like 'sql_mode'; Variable_name Value @@ -31,7 +31,7 @@ t1 CREATE TABLE "t1" ( "email" varchar(60) character set latin2 NOT NULL default '', PRIMARY KEY ("a"), UNIQUE KEY "email" USING BTREE ("email") -) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC set @@sql_mode="no_table_options"; show variables like 'sql_mode'; Variable_name Value @@ -57,7 +57,7 @@ t1 CREATE TABLE `t1` ( `email` varchar(60) character set latin2 NOT NULL default '', PRIMARY KEY (`a`), UNIQUE KEY `email` (`email`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC set @@sql_mode="no_field_options,mysql323,mysql40"; show variables like 'sql_mode'; Variable_name Value diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index fb228d37da3..f28317ce947 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -768,7 +768,7 @@ INSERT INTO t1 VALUES (-2.2E-307,0),(+1.7E+308,+1.7E+308); INSERT INTO t1 VALUES ('-2.2E-307',0),('+1.7E+308','+1.7E+308'); INSERT INTO t1 (col1) VALUES (-2.2E-330); INSERT INTO t1 (col1) VALUES (+1.7E+309); -ERROR 22007: Illegal double '1.7E+309' value found during parsing +Got one of the listed errors INSERT INTO t1 (col2) VALUES (-1.1E-3); ERROR 22003: Out of range value adjusted for column 'col2' at row 1 INSERT INTO t1 (col1) VALUES ('+1.8E+309'); diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1a1a9a256db..5fd2053a3ec 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -2160,3 +2160,11 @@ WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000); f1 NULL 1 +drop table t1,t2; +create table t1 (a1 int); +create table t2 (b1 int); +select * from t1 where a2 > any(select b1 from t2); +ERROR 42S22: Unknown column 'a2' in 'scalar IN/ALL/ANY subquery' +select * from t1 where a1 > any(select b1 from t2); +a1 +drop table t1,t2; diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 53d0f63aea2..8aa20a88177 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -45,6 +45,15 @@ alter table t9 rename t8, add column d int not null; alter table t8 rename t7; rename table t7 to t9; drop table t1; +SHOW CREATE TABLE t9; +Table Create Table +t9 CREATE TABLE `t9` ( + `a` int(11) NOT NULL auto_increment, + `b` char(16) NOT NULL, + `c` int(11) NOT NULL, + `d` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/' Got one of the listed errors Got one of the listed errors Got one of the listed errors diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 45f887461e7..88bb04fefba 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -368,3 +368,14 @@ a+0 44 57 drop table t1; +create table t1 (a bit(3), b bit(12)); +insert into t1 values (7,(1<<12)-2), (0x01,0x01ff); +select hex(a),hex(b) from t1; +hex(a) hex(b) +7 FFE +1 1FF +select hex(concat(a)),hex(concat(b)) from t1; +hex(concat(a)) hex(concat(b)) +07 0FFE +01 01FF +drop table t1; diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 449d9b0ea4b..c77b3ad7578 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1,t2; SELECT 10,10.0,10.,.1e+2,100.0e-1; 10 10.0 10. .1e+2 100.0e-1 10 10.0 10 10 10 @@ -8,6 +8,9 @@ SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000; SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1; 1e1 1.e1 1.0e1 1e+1 1.e+1 1.0e+1 1e-1 1.e-1 1.0e-1 10 10 10 10 10 10 0.1 0.1 0.1 +SELECT 0.001e+1,0.001e-1, -0.001e+01,-0.001e-01; +0.001e+1 0.001e-1 -0.001e+01 -0.001e-01 +0.01 0.0001 -0.01 -0.0001 create table t1 (f1 float(24),f2 float(52)); show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment @@ -143,6 +146,15 @@ drop table t1; create table t1 (f float(54)); ERROR 42000: Incorrect column specifier for column 'f' drop table if exists t1; +create table t1 (d1 double, d2 double unsigned); +insert into t1 set d1 = -1.0; +update t1 set d2 = d1; +Warnings: +Warning 1264 Out of range value adjusted for column 'd2' at row 1 +select * from t1; +d1 d2 +-1 0 +drop table t1; create table t1 (f float(4,3)); insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11"); Warnings: diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 61c167c6264..1e0b5deaf25 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -426,3 +426,13 @@ max(t) 2004-01-01 01:00:00 2004-02-01 00:00:00 drop table t1; +set sql_mode='maxdb'; +create table t1 (a timestamp, b timestamp(19)); +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" datetime default NULL, + "b" datetime default NULL +) +set sql_mode=''; +drop table t1; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 334a2531c7f..a63358ff2bc 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -554,7 +554,7 @@ aa show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` varchar(20) NOT NULL default '' + `a` varbinary(20) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 SELECT 12 as a UNION select 12.2 as a; @@ -872,6 +872,22 @@ count(*) show status like 'Slow_queries'; Variable_name Value Slow_queries 7 +flush status; +select a from t1 where b not in (1,2,3) union select a from t1 where b not in (4,5,6); +a +4 +5 +3 +6 +7 +8 +9 +10 +1 +2 +show status like 'Slow_queries'; +Variable_name Value +Slow_queries 1 drop table t1; create table t1 ( RID int(11) not null default '0', IID int(11) not null default '0', nada varchar(50) not null,NAME varchar(50) not null,PHONE varchar(50) not null) engine=MyISAM; insert into t1 ( RID,IID,nada,NAME,PHONE) values (1, 1, 'main', 'a', '111'), (2, 1, 'main', 'b', '222'), (3, 1, 'main', 'c', '333'), (4, 1, 'main', 'd', '444'), (5, 1, 'main', 'e', '555'), (6, 2, 'main', 'c', '333'), (7, 2, 'main', 'd', '454'), (8, 2, 'main', 'e', '555'), (9, 2, 'main', 'f', '666'), (10, 2, 'main', 'g', '777'); diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index d7d527dd720..69fcc5c45fe 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -172,23 +172,26 @@ SET TIMESTAMP=10000; SET @`a b`='hello'; INSERT INTO t1 VALUES(@`a b`); set @var1= "';aaa"; -insert into t1 values (@var1); +SET @var2=char(ascii('a')); +insert into t1 values (@var1),(@var2); show binlog events from 95; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 95 User var 1 136 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci master-bin.000001 136 Query 1 222 use `test`; INSERT INTO t1 VALUES(@`a b`) master-bin.000001 222 User var 1 264 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci -master-bin.000001 264 Query 1 350 use `test`; insert into t1 values (@var1) +master-bin.000001 264 User var 1 302 @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci +master-bin.000001 302 Query 1 396 use `test`; insert into t1 values (@var1),(@var2) /*!40019 SET @@session.max_insert_delayed_threads=0*/; -SET @`a b`:=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci; +SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`; use test; SET TIMESTAMP=10000; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.sql_mode=0; INSERT INTO t1 VALUES(@`a b`); -SET @`var1`:=_latin1 0x273B616161 COLLATE latin1_swedish_ci; +SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`; +SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`; SET TIMESTAMP=10000; -insert into t1 values (@var1); +insert into t1 values (@var1),(@var2); drop table t1; set @var= NULL ; select FIELD( @var,'1it','Hit') as my_column; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index c4391781e9c..239849ed8d1 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1724,3 +1724,9 @@ a b 301 0 drop view v3; drop tables t1,t2; +create table t1(f1 int); +create view v1 as select f1 from t1; +select * from v1 where F1 = 1; +f1 +drop view v1; +drop table t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 66a4adc90fe..c2277dc1755 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -336,3 +336,14 @@ select hex(a) from t1; alter table t1 convert to character set cp1251; select hex(a) from t1; drop table t1; + +# +# Test for bug #7884 "Able to add invalid unique index on TIMESTAMP prefix" +# MySQL should not think that packed field with non-zero decimals is +# geometry field and allow to create prefix index which is +# shorter than packed field length. +# +create table t1 ( a timestamp ); +--error 1089 +alter table t1 add unique ( a(1) ); +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 686bf5a97ad..26b467a398d 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -294,7 +294,7 @@ select * from t2; create table t3 like t1; --error 1050 create table t3 like mysqltest.t3; ---error 1044,1 +--error ER_DBACCESS_DENIED_ERROR,1 create table non_existing_database.t1 like t1; --error 1051 create table t3 like non_existing_table; diff --git a/mysql-test/t/ctype_cp932.test b/mysql-test/t/ctype_cp932.test index 504468b1e1d..24da8a76dcd 100755 --- a/mysql-test/t/ctype_cp932.test +++ b/mysql-test/t/ctype_cp932.test @@ -395,3 +395,9 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; + + +SET collation_connection='cp932_japanese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='cp932_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_eucjpms.test b/mysql-test/t/ctype_eucjpms.test index abc7105c12e..578d116fcb9 100755 --- a/mysql-test/t/ctype_eucjpms.test +++ b/mysql-test/t/ctype_eucjpms.test @@ -342,3 +342,9 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; + + +SET collation_connection='eucjpms_japanese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='eucjpms_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index a57db4455ab..8e3eb71c3e5 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -681,3 +681,15 @@ SET collation_connection='utf8_general_ci'; -- source include/ctype_filesort.inc SET collation_connection='utf8_bin'; -- source include/ctype_filesort.inc + +# +# Bug #7874 CONCAT() gives wrong results mixing +# latin1 field and utf8 string literals +# +CREATE TABLE t1 ( + user varchar(255) NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES ('one'),('two'); +SELECT CHARSET('a'); +SELECT user, CONCAT('<', user, '>') AS c FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index c5147dc381e..a1fac51371c 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -278,6 +278,13 @@ select group_concat(distinct b order by b) from t1 group by a; drop table t1; +# +# bug #7769: group_concat returning null is checked in having +# +CREATE TABLE t1 (id int); +SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; +DROP TABLE t1; + # # Bug #6475 # diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index 3cd8c064817..6e0883b821f 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -80,6 +80,11 @@ create table t1 (a char(10) character set utf8 not null); insert into t1 values ('bbbb'),(_koi8r''),(_latin1''); select a from t1 where a in ('bbbb',_koi8r'',_latin1'') order by a; drop table t1; +# Bug#7834 Illegal mix of collations in IN operator +create table t1 (a char(10) character set latin1 not null); +insert into t1 values ('a'),('b'),('c'); +select a from t1 where a IN ('a','b','c') order by a; +drop table t1; set names latin1; select '1.0' in (1,2); diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test index 3f547739679..cb3ab12b5fc 100644 --- a/mysql-test/t/func_sapdb.test +++ b/mysql-test/t/func_sapdb.test @@ -60,6 +60,7 @@ select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); --enable_ps_protocol select maketime(10,11,12); diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test index cc1a3169d0e..5e270c161a2 100644 --- a/mysql-test/t/index_merge_innodb.test +++ b/mysql-test/t/index_merge_innodb.test @@ -4,7 +4,7 @@ -- source include/have_innodb.inc --disable_warnings -drop table if exists t1; +drop table if exists t1,t2; --enable_warnings create table t1 diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index ac36bbd6014..a4886fd8245 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -354,3 +354,8 @@ show open tables where `table` like "user"; show status variable_name where variable_name like "%database%"; # test for 'show variables ... where' show variables variable_name where variable_name like "%database%"; + +# +# Bug #7981:SHOW GLOBAL STATUS crashes server +# +show global status like "Threads_running"; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index ce2ce577b46..66de5e5a4c9 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -554,34 +554,34 @@ SELECT t1.flag_name,t2.flag_value DROP TABLE t1,t2; -CREATE TABLE invoice ( +CREATE TABLE t1 ( id int(11) unsigned NOT NULL auto_increment, text_id int(10) unsigned default NULL, PRIMARY KEY (id) ); -INSERT INTO invoice VALUES("1", "0"); -INSERT INTO invoice VALUES("2", "10"); +INSERT INTO t1 VALUES("1", "0"); +INSERT INTO t1 VALUES("2", "10"); -CREATE TABLE text_table ( +CREATE TABLE t2 ( text_id char(3) NOT NULL default '', language_id char(3) NOT NULL default '', text_data text, PRIMARY KEY (text_id,language_id) ); -INSERT INTO text_table VALUES("0", "EN", "0-EN"); -INSERT INTO text_table VALUES("0", "SV", "0-SV"); -INSERT INTO text_table VALUES("10", "EN", "10-EN"); -INSERT INTO text_table VALUES("10", "SV", "10-SV"); +INSERT INTO t2 VALUES("0", "EN", "0-EN"); +INSERT INTO t2 VALUES("0", "SV", "0-SV"); +INSERT INTO t2 VALUES("10", "EN", "10-EN"); +INSERT INTO t2 VALUES("10", "SV", "10-SV"); -SELECT invoice.id, invoice.text_id, text_table.text_data - FROM invoice LEFT JOIN text_table - ON invoice.text_id = text_table.text_id - AND text_table.language_id = 'SV' - WHERE (invoice.id LIKE '%' OR text_table.text_data LIKE '%'); +SELECT t1.id, t1.text_id, t2.text_data + FROM t1 LEFT JOIN t2 + ON t1.text_id = t2.text_id + AND t2.language_id = 'SV' + WHERE (t1.id LIKE '%' OR t2.text_data LIKE '%'); -DROP TABLE invoice, text_table; +DROP TABLE t1, t2; # Test for bug #5896 diff --git a/mysql-test/t/ndb_autodiscover.test b/mysql-test/t/ndb_autodiscover.test index 6551732adba..2159e6b6e62 100644 --- a/mysql-test/t/ndb_autodiscover.test +++ b/mysql-test/t/ndb_autodiscover.test @@ -449,9 +449,28 @@ drop table t1; use test2; drop table t2; drop database test2; -show databases; use test; +######################################################### +# Bug#8035 +# mysqld would segfault on second select * before bug was fixed +# +--disable_warnings +drop database if exists test_only_ndb_tables; +--enable_warnings +create database test_only_ndb_tables; +use test_only_ndb_tables; +create table t1 (a int primary key) engine=ndb; +select * from t1; +--exec $NDB_MGM --no-defaults -e "all restart -n" > /dev/null +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults --not-started > /dev/null +--error 1015 +select * from t1; +--exec $NDB_MGM --no-defaults -e "all start" > /dev/null +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults > /dev/null +use test; +drop database test_only_ndb_tables; + ###################################################### # Note! This should always be the last step in this # file, the table t9 will be used and dropped diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index dd36cd95969..02e49f9750d 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -506,3 +506,36 @@ insert t1 values (1,1,1),(1,1,2),(1,2,1); select a, b from t1 group by a, b order by sum(c); drop table t1; +# +# Bug #7331 +# + +create table t1 ( + `sid` decimal(8,0) default null, + `wnid` varchar(11) not null default '', + key `wnid14` (`wnid`(4)), + key `wnid` (`wnid`) +) engine=myisam default charset=latin1; + +insert into t1 (`sid`, `wnid`) values +('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), +('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), +('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), +('37994','01019090000'),('475','02070000000'),('25253','02071100000'), +('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), +('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), +('25262','02071290000'),('25263','02071300000'),('25264','02071310000'), +('25265','02071310000'),('25266','02071320000'),('25267','02071320000'), +('25269','02071330000'),('25270','02071340000'),('25271','02071350000'), +('25272','02071360000'),('25273','02071370000'),('25281','02071391000'), +('25282','02071391000'),('25283','02071399000'),('25284','02071400000'), +('25285','02071410000'),('25286','02071410000'),('25287','02071420000'), +('25288','02071420000'),('25291','02071430000'),('25290','02071440000'), +('25292','02071450000'),('25293','02071460000'),('25294','02071470000'), +('25295','02071491000'),('25296','02071491000'),('25297','02071499000'); + +explain select * from t1 where wnid like '0101%' order by wnid; + +select * from t1 where wnid like '0101%' order by wnid; + +drop table t1; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 47b115cf030..a32b9d06ef9 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1761,9 +1761,9 @@ DO benchmark(100,1+1),1,1; # Bug #6449: do default; # ---error 1064 +--error ER_PARSE_ERROR do default; ---error 1054 +--error ER_BAD_FIELD_ERROR do foobar; # diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index a0cfc0c60f4..2ccc3e672c7 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -531,7 +531,7 @@ INSERT INTO t1 VALUES (-2.2E-307,0),(+1.7E+308,+1.7E+308); INSERT INTO t1 VALUES ('-2.2E-307',0),('+1.7E+308','+1.7E+308'); # We don't give warnings for underflow INSERT INTO t1 (col1) VALUES (-2.2E-330); ---error 1367 +--error 1367,1264 INSERT INTO t1 (col1) VALUES (+1.7E+309); --error 1264 INSERT INTO t1 (col2) VALUES (-1.1E-3); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index bedeecd5d12..244802d4d6e 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1417,3 +1417,14 @@ SELECT f1 FROM t1 SELECT f1 FROM t1 WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000); + +drop table t1,t2; +# Test for BUG#7885: Server crash when 'any' subselect compared to +# non-existant field. +create table t1 (a1 int); +create table t2 (b1 int); +--error 1054 +select * from t1 where a2 > any(select b1 from t2); +select * from t1 where a1 > any(select b1 from t2); +drop table t1,t2; + diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 78c9b68fde5..25c78129129 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -49,6 +49,7 @@ check table t9; optimize table t9; repair table t9; alter table t9 add column c int not null; + --replace_result $MYSQL_TEST_DIR TEST_DIR show create table t9; @@ -64,6 +65,9 @@ drop table t1; # Note that we are using the above table t9 here! # +--replace_result $MYSQL_TEST_DIR TEST_DIR +SHOW CREATE TABLE t9; + disable_query_log; --error 1103,1103 create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="tmp"; @@ -78,9 +82,11 @@ create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, p --error 1103,1103 create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path"; +# Should fail becasue the file t9.MYI already exist in 'run' --error 1,1 eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="$MYSQL_TEST_DIR/var/run"; +# Should fail becasue the file t9.MYD already exist in 'tmp' --error 1,1 eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="$MYSQL_TEST_DIR/var/tmp"; enable_query_log; diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 0c1c22099f9..fed15806765 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -106,3 +106,12 @@ create table t1 (a bit(7), key(a)); insert into t1 values (44), (57); select a+0 from t1; drop table t1; + +# +# Test conversion to and from strings +# +create table t1 (a bit(3), b bit(12)); +insert into t1 values (7,(1<<12)-2), (0x01,0x01ff); +select hex(a),hex(b) from t1; +select hex(concat(a)),hex(concat(b)) from t1; +drop table t1; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 69cdeaa32a9..80eff1f2859 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -3,7 +3,7 @@ # Numeric floating point. --disable_warnings -drop table if exists t1; +drop table if exists t1,t2; --enable_warnings --replace_result e-0 e- e+0 e+ @@ -11,6 +11,7 @@ SELECT 10,10.0,10.,.1e+2,100.0e-1; --replace_result e-00 e-0 SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000; SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1; +SELECT 0.001e+1,0.001e-1, -0.001e+01,-0.001e-01; create table t1 (f1 float(24),f2 float(52)); show full columns from t1; @@ -93,6 +94,13 @@ create table t1 (f float(54)); # Should give an error drop table if exists t1; --enable_warnings +# Don't allow 'double unsigned' to be set to a negative value (Bug #7700) +create table t1 (d1 double, d2 double unsigned); +insert into t1 set d1 = -1.0; +update t1 set d2 = d1; +select * from t1; +drop table t1; + # Ensure that maximum values as the result of number of decimals # being specified in table schema are enforced (Bug #7361) create table t1 (f float(4,3)); diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 0a92afeb57d..62e7510405d 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -288,3 +288,15 @@ insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00') ('b', '2004-02-01 00:00:00'); select max(t) from t1 group by a; drop table t1; + +# +# Test for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB +# mode". TIMESTAMP columns should be converted DATETIME columns in MAXDB +# mode regardless of whether a display width is given. +# +set sql_mode='maxdb'; +create table t1 (a timestamp, b timestamp(19)); +show create table t1; +# restore default mode +set sql_mode=''; +drop table t1; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 58e4c22e168..6045d8e3c30 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -499,6 +499,10 @@ select count(*) from t1 where b=13 union select count(*) from t1 where a=7; show status like 'Slow_queries'; select count(*) from t1 where a=7 union select count(*) from t1 where b=13; show status like 'Slow_queries'; +# additional test for examined rows +flush status; +select a from t1 where b not in (1,2,3) union select a from t1 where b not in (4,5,6); +show status like 'Slow_queries'; drop table t1; # diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index ae8e3ccf841..49cf981b966 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -108,7 +108,8 @@ SET TIMESTAMP=10000; SET @`a b`='hello'; INSERT INTO t1 VALUES(@`a b`); set @var1= "';aaa"; -insert into t1 values (@var1); +SET @var2=char(ascii('a')); +insert into t1 values (@var1),(@var2); show binlog events from 95; # more important than SHOW BINLOG EVENTS, mysqlbinlog (where we # absolutely need variables names to be quoted and strings to be diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 77f0f65323e..ed7401adaab 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1654,3 +1654,10 @@ select * from v3; drop view v3; drop tables t1,t2; + +# View field names should be case insensitive +create table t1(f1 int); +create view v1 as select f1 from t1; +select * from v1 where F1 = 1; +drop view v1; +drop table t1; diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index f109df912f1..b86e9daf92d 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -27,7 +27,7 @@ also info->read_pos is set to info->read_end. If called through open_cached_file(), then the temporary file will only be created if a write exeeds the file buffer or if one calls - flush_io_cache(). + my_b_flush_io_cache(). If one uses SEQ_READ_APPEND, then two buffers are allocated, one for reading and another for writing. Reads are first done from disk and @@ -43,7 +43,7 @@ TODO: each time the write buffer gets full and it's written to disk, we will always do a disk read to read a part of the buffer from disk to the read buffer. - This should be fixed so that when we do a flush_io_cache() and + This should be fixed so that when we do a my_b_flush_io_cache() and we have been reading the write buffer, we should transfer the rest of the write buffer to the read buffer before we start to reuse it. */ @@ -70,9 +70,40 @@ static void my_aiowait(my_aio_result *result); #define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1)) #define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1)) -static void -init_functions(IO_CACHE* info, enum cache_type type) + +/* + Setup internal pointers inside IO_CACHE + + SYNOPSIS + setup_io_cache() + info IO_CACHE handler + + NOTES + This is called on automaticly on init or reinit of IO_CACHE + It must be called externally if one moves or copies an IO_CACHE + object. +*/ + +void setup_io_cache(IO_CACHE* info) { + /* Ensure that my_b_tell() and my_b_bytes_in_cache works */ + if (info->type == WRITE_CACHE) + { + info->current_pos= &info->write_pos; + info->current_end= &info->write_end; + } + else + { + info->current_pos= &info->read_pos; + info->current_end= &info->read_end; + } +} + + +static void +init_functions(IO_CACHE* info) +{ + enum cache_type type= info->type; switch (type) { case READ_NET: /* @@ -96,17 +127,7 @@ init_functions(IO_CACHE* info, enum cache_type type) info->write_function = _my_b_write; } - /* Ensure that my_b_tell() and my_b_bytes_in_cache works */ - if (type == WRITE_CACHE) - { - info->current_pos= &info->write_pos; - info->current_end= &info->write_end; - } - else - { - info->current_pos= &info->read_pos; - info->current_end= &info->read_end; - } + setup_io_cache(info); } @@ -236,7 +257,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, info->end_of_file= end_of_file; info->error=0; info->type= type; - init_functions(info,type); + init_functions(info); #ifdef HAVE_AIOWAIT if (use_async_io && ! my_disable_async_io) { @@ -339,7 +360,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, if (info->type == WRITE_CACHE && type == READ_CACHE) info->end_of_file=my_b_tell(info); /* flush cache if we want to reuse it */ - if (!clear_cache && flush_io_cache(info)) + if (!clear_cache && my_b_flush_io_cache(info,1)) DBUG_RETURN(1); info->pos_in_file=seek_offset; /* Better to do always do a seek */ @@ -358,7 +379,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, } info->type=type; info->error=0; - init_functions(info,type); + init_functions(info); #ifdef HAVE_AIOWAIT if (use_async_io && ! my_disable_async_io && @@ -948,7 +969,7 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count) Buffer+=rest_length; Count-=rest_length; info->write_pos+=rest_length; - if (flush_io_cache(info)) + if (my_b_flush_io_cache(info,1)) return 1; if (Count >= IO_SIZE) { /* Fill first intern buffer */ @@ -1191,6 +1212,7 @@ int end_io_cache(IO_CACHE *info) int error=0; IO_CACHE_CALLBACK pre_close; DBUG_ENTER("end_io_cache"); + DBUG_PRINT("enter",("cache: 0x%lx", (ulong) info)); #ifdef THREAD /* @@ -1200,7 +1222,7 @@ int end_io_cache(IO_CACHE *info) */ if (info->share) { - pthread_cond_destroy (&info->share->cond); + pthread_cond_destroy(&info->share->cond); pthread_mutex_destroy(&info->share->mutex); info->share=0; } @@ -1215,7 +1237,7 @@ int end_io_cache(IO_CACHE *info) { info->alloced_buffer=0; if (info->file != -1) /* File doesn't exist */ - error=flush_io_cache(info); + error= my_b_flush_io_cache(info,1); my_free((gptr) info->buffer,MYF(MY_WME)); info->buffer=info->read_pos=(byte*) 0; } diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index d8c19d86e5c..c14b2899b4b 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -245,6 +245,19 @@ static inline void mark_blocks_free(MEM_ROOT* root) /* Deallocate everything used by alloc_root or just move used blocks to free list if called with MY_USED_TO_FREE + + SYNOPSIS + free_root() + root Memory root + MyFlags Flags for what should be freed: + + MY_MARK_BLOCKS_FREED Don't free blocks, just mark them free + MY_KEEP_PREALLOC If this is not set, then free also the + preallocated block + + NOTES + One can call this function either with root block initialised with + init_alloc_root() or with a bzero()-ed block. */ void free_root(MEM_ROOT *root, myf MyFlags) diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index 045802c5e61..7be3fcd36f0 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -26,9 +26,11 @@ /* Reads the content of a symbolic link If the file is not a symbolic link, return the original file name in to. - Returns: 0 if table was a symlink, - 1 if table was a normal file - -1 on error. + + RETURN + 0 If filename was a symlink, (to will be set to value of symlink) + 1 If filename was a normal file (to will be set to filename) + -1 on error. */ int my_readlink(char *to, const char *filename, myf MyFlags) @@ -58,6 +60,7 @@ int my_readlink(char *to, const char *filename, myf MyFlags) } else to[length]=0; + DBUG_PRINT("exit" ,("result: %d", result)); DBUG_RETURN(result); #endif /* HAVE_READLINK */ } diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index d47ca8de183..9ce058f90fc 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -523,8 +523,10 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type) data->prev=lock->write_wait.last; lock->write_wait.last= &data->next; data->cond=get_cond(); - if (lock->get_status) - (*lock->get_status)(data->status_param); + /* + We don't have to do get_status here as we will do it when we change + the delayed lock to a real write lock + */ statistic_increment(locks_immediate,&THR_LOCK_lock); goto end; } diff --git a/ndb/docs/Makefile.am b/ndb/docs/Makefile.am index cfcab70af9c..6d4cdc12cf6 100644 --- a/ndb/docs/Makefile.am +++ b/ndb/docs/Makefile.am @@ -43,7 +43,7 @@ ndbapidoc-pdf: ndbapi.pdf ndbapi.html: $(noinst_HEADERS) @set -x; \ - export NDB_RELEASE=$(NDB_RELEASE) \ + export NDB_RELEASE=$(NDB_RELEASE); \ @RM@ -f ndbapi.pdf ndbapi.html; \ @RM@ -rf $(DOXYTMP) $(DOXYOUT); \ mkdir -p $(DOXYTMP) $(DOXYOUT); \ @@ -70,7 +70,7 @@ mgmapidoc-pdf: mgmapi.pdf mgmapi.html: $(noinst_HEADERS) @set -x; \ - export NDB_RELEASE=$(NDB_RELEASE) \ + export NDB_RELEASE=$(NDB_RELEASE); \ @RM@ -f mgmapi.pdf mgmapi.html; \ @RM@ -rf $(DOXYTMP) $(DOXYOUT); \ mkdir -p $(DOXYTMP) $(DOXYOUT); \ diff --git a/ndb/docs/doxygen/Doxyfile.mgmapi b/ndb/docs/doxygen/Doxyfile.mgmapi index db0b31f11ab..1e743dcb60e 100644 --- a/ndb/docs/doxygen/Doxyfile.mgmapi +++ b/ndb/docs/doxygen/Doxyfile.mgmapi @@ -688,7 +688,8 @@ INCLUDE_FILE_PATTERNS = # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. -PREDEFINED = DOXYGEN_SHOULD_SKIP_DEPRECATED \ +PREDEFINED = DOXYGEN_FIX \ + DOXYGEN_SHOULD_SKIP_DEPRECATED \ DOXYGEN_SHOULD_SKIP_INTERNAL \ protected=private diff --git a/ndb/examples/mgmapi_logevent_example/Makefile b/ndb/examples/mgmapi_logevent_example/Makefile new file mode 100644 index 00000000000..c1ca32dfe17 --- /dev/null +++ b/ndb/examples/mgmapi_logevent_example/Makefile @@ -0,0 +1,23 @@ +TARGET = mgmapi_logevent +SRCS = $(TARGET).cpp +OBJS = $(TARGET).o +CXX = g++ +CFLAGS = -c -Wall -fno-rtti -fno-exceptions +CXXFLAGS = +DEBUG = +LFLAGS = -Wall +TOP_SRCDIR = ../../.. +INCLUDE_DIR = $(TOP_SRCDIR) +LIB_DIR = -L$(TOP_SRCDIR)/ndb/src/.libs \ + -L$(TOP_SRCDIR)/libmysql_r/.libs \ + -L$(TOP_SRCDIR)/mysys +SYS_LIB = + +$(TARGET): $(OBJS) + $(CXX) $(CXXFLAGS) $(LFLAGS) $(LIB_DIR) $(OBJS) -lndbclient -lmysqlclient_r -lmysys -lz $(SYS_LIB) -o $(TARGET) + +$(TARGET).o: $(SRCS) + $(CXX) $(CFLAGS) -I$(INCLUDE_DIR)/include -I$(INCLUDE_DIR)/ndb/include -I$(INCLUDE_DIR)/ndb/include/mgmapi -I$(INCLUDE_DIR)/ndb/include/ndbapi $(SRCS) + +clean: + rm -f *.o $(TARGET) diff --git a/ndb/examples/mgmapi_logevent_example/mgmapi_logevent.cpp b/ndb/examples/mgmapi_logevent_example/mgmapi_logevent.cpp new file mode 100644 index 00000000000..abd8089a286 --- /dev/null +++ b/ndb/examples/mgmapi_logevent_example/mgmapi_logevent.cpp @@ -0,0 +1,104 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include +#include +#include + +/* + * export LD_LIBRARY_PATH=../../../libmysql_r/.libs:../../../ndb/src/.libs + */ + +#define MGMERROR(h) \ +{ \ + fprintf(stderr, "code: %d msg: %s\n", \ + ndb_mgm_get_latest_error(h), \ + ndb_mgm_get_latest_error_msg(h)); \ + exit(-1); \ +} + +#define LOGEVENTERROR(h) \ +{ \ + fprintf(stderr, "code: %d msg: %s\n", \ + ndb_logevent_get_latest_error(h), \ + ndb_logevent_get_latest_error_msg(h)); \ + exit(-1); \ +} + +int main() +{ + NdbMgmHandle h; + NdbLogEventHandle l; + int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; + struct ndb_logevent event; + + ndb_init(); + + h= ndb_mgm_create_handle(); + if ( h == 0) + { + printf("Unable to create handle\n"); + exit(-1); + } + if (ndb_mgm_connect(h,0,0,0)) MGMERROR(h); + + l= ndb_mgm_create_logevent_handle(h, filter); + if ( l == 0 ) MGMERROR(h); + + while (1) + { + int timeout= 5000; + int r= ndb_logevent_get_next(l,&event,timeout); + if (r == 0) + printf("No event within %d milliseconds\n", timeout); + else if (r < 0) + LOGEVENTERROR(l) + else + { + printf("Event %d from node ID %d\n", + event.type, + event.source_nodeid); + printf("Category %d, severity %d, level %d\n", + event.category, + event.severity, + event.level); + switch (event.type) { + case NDB_LE_BackupStarted: + printf("BackupStartded\n"); + printf("Starting node ID: %d\n", event.BackupStarted.starting_node); + printf("Backup ID: %d\n", event.BackupStarted.backup_id); + break; + case NDB_LE_BackupCompleted: + printf("BackupCompleted\n"); + printf("Backup ID: %d\n", event.BackupStarted.backup_id); + break; + case NDB_LE_BackupAborted: + break; + case NDB_LE_BackupFailedToStart: + break; + default: + printf("Unexpected event\n"); + break; + } + } + } + + ndb_mgm_destroy_logevent_handle(&l); + ndb_mgm_destroy_handle(&h); + ndb_end(0); + return 0; +} diff --git a/ndb/include/debugger/EventLogger.hpp b/ndb/include/debugger/EventLogger.hpp index 7c45dbd353d..6308cf25465 100644 --- a/ndb/include/debugger/EventLogger.hpp +++ b/ndb/include/debugger/EventLogger.hpp @@ -17,12 +17,12 @@ #ifndef EVENTLOGGER_H #define EVENTLOGGER_H -#include -#include -#include -#include +#include +#include +#include "GrepError.hpp" +#include #include -#include +#include class EventLoggerBase { public: @@ -39,11 +39,14 @@ public: * threshold - is in range [0-15] * severity - DEBUG to ALERT (Type of log message) */ + typedef void (* EventTextFunction)(char *,size_t,const Uint32*); + struct EventRepLogLevelMatrix { - Ndb_logevent_type eventType; - LogLevel::EventCategory eventCategory; - Uint32 threshold; - Logger::LoggerLevel severity; + Ndb_logevent_type eventType; + LogLevel::EventCategory eventCategory; + Uint32 threshold; + Logger::LoggerLevel severity; + EventTextFunction textF; }; static const EventRepLogLevelMatrix matrix[]; @@ -51,7 +54,8 @@ public: static int event_lookup(int eventType, LogLevel::EventCategory &cat, Uint32 &threshold, - Logger::LoggerLevel &severity); + Logger::LoggerLevel &severity, + EventTextFunction &textF); }; /** @@ -130,17 +134,18 @@ public: * @param nodeId the node id of event origin. */ virtual void log(int, const Uint32*, NodeId = 0,const class LogLevel * = 0); + /** * Returns the event text for the specified event report type. * - * @param type the event type. + * @param textF print function for the event * @param theData the event data. * @param nodeId a node id. * @return the event report text. */ static const char* getText(char * dst, size_t dst_len, - int type, + EventTextFunction textF, const Uint32* theData, NodeId nodeId = 0); /** diff --git a/ndb/include/kernel/AttributeHeader.hpp b/ndb/include/kernel/AttributeHeader.hpp index 3af5d01f007..3cb432067eb 100644 --- a/ndb/include/kernel/AttributeHeader.hpp +++ b/ndb/include/kernel/AttributeHeader.hpp @@ -17,7 +17,6 @@ #ifndef ATTRIBUTE_HEADER #define ATTRIBUTE_HEADER -#include /** * @class AttributeHeader * @brief Header passed in front of every attribute value in AttrInfo signal diff --git a/ndb/include/kernel/LogLevel.hpp b/ndb/include/kernel/LogLevel.hpp index 382016ee761..60dcd36ab56 100644 --- a/ndb/include/kernel/LogLevel.hpp +++ b/ndb/include/kernel/LogLevel.hpp @@ -147,7 +147,7 @@ LogLevel::set_max(const LogLevel & org){ return * this; } -#include +#include "signaldata/EventSubscribeReq.hpp" inline LogLevel& diff --git a/ndb/include/kernel/signaldata/SignalData.hpp b/ndb/include/kernel/signaldata/SignalData.hpp index 2b29ca06ba0..f825b0feb7b 100644 --- a/ndb/include/kernel/signaldata/SignalData.hpp +++ b/ndb/include/kernel/signaldata/SignalData.hpp @@ -18,8 +18,8 @@ #define SIGNAL_DATA_H #include -#include -#include +#include +#include #include #define ASSERT_BOOL(flag, message) assert(flag<=1) diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index 3f8d29e13c1..de4286bdbfd 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -86,6 +86,53 @@ * int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; * int fd = ndb_mgm_listen_event(handle, filter); * @endcode + * + * + * @section secSLogEvents Structured Log Events + * + * The following steps are involved: + * - Create a NdbEventLogHandle using ndb_mgm_create_logevent_handle() + * - Wait and store log events using ndb_logevent_get_next() + * - The log event data is available in the struct ndb_logevent. The + * data which is specific to a particular event is stored in a union + * between structs so use ndb_logevent::type to decide which struct + * is valid. + * + * Sample code for listening to Backup related events. The availaable log + * events are listed in @ref ndb_logevent.h + * + * @code + * int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; + * NdbEventLogHandle le_handle= ndb_mgm_create_logevent_handle(handle, filter); + * struct ndb_logevent le; + * int r= ndb_logevent_get_next(le_handle,&le,0); + * if (r < 0) error + * else if (r == 0) no event + * + * switch (le.type) + * { + * case NDB_LE_BackupStarted: + * ... le.BackupStarted.starting_node; + * ... le.BackupStarted.backup_id; + * break; + * case NDB_LE_BackupFailedToStart: + * ... le.BackupFailedToStart.error; + * break; + * case NDB_LE_BackupCompleted: + * ... le.BackupCompleted.stop_gci; + * break; + * case NDB_LE_BackupAborted: + * ... le.BackupStarted.backup_id; + * break; + * default: + * break; + * } + * @endcode + */ + +/* + * @page ndb_logevent.h ndb_logevent.h + * @include ndb_logevent.h */ /** @addtogroup MGM_C_API @@ -93,6 +140,7 @@ */ #include +#include "ndb_logevent.h" #include "mgmapi_config_parameters.h" #ifdef __cplusplus @@ -348,97 +396,6 @@ extern "C" { }; #endif - /** - * Log event severities (used to filter the cluster log, - * ndb_mgm_set_clusterlog_severity_filter(), and filter listening to events - * ndb_mgm_listen_event()) - */ - enum ndb_mgm_event_severity { - NDB_MGM_ILLEGAL_EVENT_SEVERITY = -1, - /* Must be a nonnegative integer (used for array indexing) */ - /** Cluster log on */ - NDB_MGM_EVENT_SEVERITY_ON = 0, - /** Used in NDB Cluster developement */ - NDB_MGM_EVENT_SEVERITY_DEBUG = 1, - /** Informational messages*/ - NDB_MGM_EVENT_SEVERITY_INFO = 2, - /** Conditions that are not error condition, but might require handling. - */ - NDB_MGM_EVENT_SEVERITY_WARNING = 3, - /** Conditions that, while not fatal, should be corrected. */ - NDB_MGM_EVENT_SEVERITY_ERROR = 4, - /** Critical conditions, like device errors or out of resources */ - NDB_MGM_EVENT_SEVERITY_CRITICAL = 5, - /** A condition that should be corrected immediately, - * such as a corrupted system - */ - NDB_MGM_EVENT_SEVERITY_ALERT = 6, - /* must be next number, works as bound in loop */ - /** All severities */ - NDB_MGM_EVENT_SEVERITY_ALL = 7 - }; - - /** - * Log event categories, used to set filter level on the log events using - * ndb_mgm_set_clusterlog_loglevel() and ndb_mgm_listen_event() - */ - enum ndb_mgm_event_category { - /** - * Invalid log event category - */ - NDB_MGM_ILLEGAL_EVENT_CATEGORY = -1, - /** - * Log events during all kinds of startups - */ - NDB_MGM_EVENT_CATEGORY_STARTUP = CFG_LOGLEVEL_STARTUP, - /** - * Log events during shutdown - */ - NDB_MGM_EVENT_CATEGORY_SHUTDOWN = CFG_LOGLEVEL_SHUTDOWN, - /** - * Statistics log events - */ - NDB_MGM_EVENT_CATEGORY_STATISTIC = CFG_LOGLEVEL_STATISTICS, - /** - * Log events related to checkpoints - */ - NDB_MGM_EVENT_CATEGORY_CHECKPOINT = CFG_LOGLEVEL_CHECKPOINT, - /** - * Log events during node restart - */ - NDB_MGM_EVENT_CATEGORY_NODE_RESTART = CFG_LOGLEVEL_NODERESTART, - /** - * Log events related to connections between cluster nodes - */ - NDB_MGM_EVENT_CATEGORY_CONNECTION = CFG_LOGLEVEL_CONNECTION, - /** - * Backup related log events - */ - NDB_MGM_EVENT_CATEGORY_BACKUP = CFG_LOGLEVEL_BACKUP, - /** - * Congestion related log events - */ - NDB_MGM_EVENT_CATEGORY_CONGESTION = CFG_LOGLEVEL_CONGESTION, -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - /** - * Loglevel debug - */ - NDB_MGM_EVENT_CATEGORY_DEBUG = CFG_LOGLEVEL_DEBUG, -#endif - /** - * Uncategorized log events (severity info) - */ - NDB_MGM_EVENT_CATEGORY_INFO = CFG_LOGLEVEL_INFO, - /** - * Uncategorized log events (severity warning or higher) - */ - NDB_MGM_EVENT_CATEGORY_ERROR = CFG_LOGLEVEL_ERROR, -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - NDB_MGM_MIN_EVENT_CATEGORY = CFG_MIN_LOGLEVEL, - NDB_MGM_MAX_EVENT_CATEGORY = CFG_MAX_LOGLEVEL -#endif - }; - /***************************************************************************/ /** * @name Functions: Error Handling @@ -871,6 +828,64 @@ extern "C" { struct ndb_mgm_reply* reply); #endif + /** + * The NdbLogEventHandle + */ + typedef struct ndb_logevent_handle * NdbLogEventHandle; + + /** + * Listen to log events. + * + * @param handle NDB management handle. + * @param filter pairs of { level, ndb_mgm_event_category } that will be + * pushed to fd, level=0 ends list. + * + * @return NdbLogEventHandle + */ + NdbLogEventHandle ndb_mgm_create_logevent_handle(NdbMgmHandle, + const int filter[]); + void ndb_mgm_destroy_logevent_handle(NdbLogEventHandle*); + + /** + * Retrieve filedescriptor from NdbLogEventHandle. May be used in + * e.g. an application select() statement. + * + * @note Do not attemt to read from it, it will corrupt the parsing. + * + * @return filedescriptor, -1 on failure. + */ + int ndb_logevent_get_fd(const NdbLogEventHandle); + + /** + * Attempt to retrieve next log event and will fill in the supplied + * struct dst + * + * @param dst Pointer to struct to fill in event information + * @param timeout_in_milliseconds Timeout for waiting for event + * + * @return >0 if event exists, 0 no event (timed out), or -1 on error. + * + * @note Return value <=0 will leave dst untouched + */ + int ndb_logevent_get_next(const NdbLogEventHandle, + struct ndb_logevent *dst, + unsigned timeout_in_milliseconds); + + /** + * Retrieve laterst error code + * + * @return error code + */ + int ndb_logevent_get_latest_error(const NdbLogEventHandle); + + /** + * Retrieve laterst error message + * + * @return error message + */ + const char *ndb_logevent_get_latest_error_msg(const NdbLogEventHandle); + + /** @} *********************************************************************/ /** * @name Functions: Backup diff --git a/ndb/include/mgmapi/ndb_logevent.h b/ndb/include/mgmapi/ndb_logevent.h index ca6f848206f..3ca744bcc2e 100644 --- a/ndb/include/mgmapi/ndb_logevent.h +++ b/ndb/include/mgmapi/ndb_logevent.h @@ -17,90 +17,542 @@ #ifndef NDB_LOGEVENT_H #define NDB_LOGEVENT_H +/** @addtogroup MGM_C_API + * @{ + */ + +#include "mgmapi_config_parameters.h" + #ifdef __cplusplus extern "C" { #endif + /** + * Available log events grouped by @ref ndb_mgm_event_category + */ + enum Ndb_logevent_type { - /* CONNECTION */ + + NDB_LE_ILLEGAL_TYPE = -1, + + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_Connected = 0, + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_Disconnected = 1, + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_CommunicationClosed = 2, + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_CommunicationOpened = 3, + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_ConnectedApiVersion = 51, - /* CHECKPOINT */ + + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_GlobalCheckpointStarted = 4, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_GlobalCheckpointCompleted = 5, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_LocalCheckpointStarted = 6, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_LocalCheckpointCompleted = 7, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_LCPStoppedInCalcKeepGci = 8, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_LCPFragmentCompleted = 9, - /* STARTUP */ + + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_NDBStartStarted = 10, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_NDBStartCompleted = 11, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_STTORRYRecieved = 12, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_StartPhaseCompleted = 13, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_CM_REGCONF = 14, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_CM_REGREF = 15, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_FIND_NEIGHBOURS = 16, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_NDBStopStarted = 17, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_NDBStopAborted = 18, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_StartREDOLog = 19, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_StartLog = 20, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_UNDORecordsExecuted = 21, - /* NODERESTART */ + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyDict = 22, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyDistr = 23, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyFragsStarted = 24, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyFragDone = 25, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyFragsCompleted = 26, /* NODEFAIL */ + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NodeFailCompleted = 27, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NODE_FAILREP = 28, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_ArbitState = 29, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_ArbitResult = 30, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_GCP_TakeoverStarted = 31, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_GCP_TakeoverCompleted = 32, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_LCP_TakeoverStarted = 33, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_LCP_TakeoverCompleted = 34, - /* STATISTIC */ + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_TransReportCounters = 35, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_OperationReportCounters = 36, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_TableCreated = 37, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_UndoLogBlocked = 38, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_JobStatistic = 39, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_SendBytesStatistic = 40, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_ReceiveBytesStatistic = 41, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_MemoryUsage = 50, - /* ERROR */ + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_TransporterError = 42, + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_TransporterWarning = 43, + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_MissedHeartbeat = 44, + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_DeadDueToHeartbeat = 45, + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_WarningEvent = 46, - /* INFO */ + /** NDB_MGM_EVENT_CATEGORY_INFO */ NDB_LE_SentHeartbeat = 47, + /** NDB_MGM_EVENT_CATEGORY_INFO */ NDB_LE_CreateLogBytes = 48, + /** NDB_MGM_EVENT_CATEGORY_INFO */ NDB_LE_InfoEvent = 49, /* GREP */ NDB_LE_GrepSubscriptionInfo = 52, NDB_LE_GrepSubscriptionAlert = 53, - /* BACKUP */ + /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupStarted = 54, + /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupFailedToStart = 55, + /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupCompleted = 56, + /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupAborted = 57 }; + /** + * Log event severities (used to filter the cluster log, + * ndb_mgm_set_clusterlog_severity_filter(), and filter listening to events + * ndb_mgm_listen_event()) + */ + enum ndb_mgm_event_severity { + NDB_MGM_ILLEGAL_EVENT_SEVERITY = -1, + /* Must be a nonnegative integer (used for array indexing) */ + /** Cluster log on */ + NDB_MGM_EVENT_SEVERITY_ON = 0, + /** Used in NDB Cluster developement */ + NDB_MGM_EVENT_SEVERITY_DEBUG = 1, + /** Informational messages*/ + NDB_MGM_EVENT_SEVERITY_INFO = 2, + /** Conditions that are not error condition, but might require handling. + */ + NDB_MGM_EVENT_SEVERITY_WARNING = 3, + /** Conditions that, while not fatal, should be corrected. */ + NDB_MGM_EVENT_SEVERITY_ERROR = 4, + /** Critical conditions, like device errors or out of resources */ + NDB_MGM_EVENT_SEVERITY_CRITICAL = 5, + /** A condition that should be corrected immediately, + * such as a corrupted system + */ + NDB_MGM_EVENT_SEVERITY_ALERT = 6, + /* must be next number, works as bound in loop */ + /** All severities */ + NDB_MGM_EVENT_SEVERITY_ALL = 7 + }; + + /** + * Log event categories, used to set filter level on the log events using + * ndb_mgm_set_clusterlog_loglevel() and ndb_mgm_listen_event() + */ + enum ndb_mgm_event_category { + /** + * Invalid log event category + */ + NDB_MGM_ILLEGAL_EVENT_CATEGORY = -1, + /** + * Log events during all kinds of startups + */ + NDB_MGM_EVENT_CATEGORY_STARTUP = CFG_LOGLEVEL_STARTUP, + /** + * Log events during shutdown + */ + NDB_MGM_EVENT_CATEGORY_SHUTDOWN = CFG_LOGLEVEL_SHUTDOWN, + /** + * Statistics log events + */ + NDB_MGM_EVENT_CATEGORY_STATISTIC = CFG_LOGLEVEL_STATISTICS, + /** + * Log events related to checkpoints + */ + NDB_MGM_EVENT_CATEGORY_CHECKPOINT = CFG_LOGLEVEL_CHECKPOINT, + /** + * Log events during node restart + */ + NDB_MGM_EVENT_CATEGORY_NODE_RESTART = CFG_LOGLEVEL_NODERESTART, + /** + * Log events related to connections between cluster nodes + */ + NDB_MGM_EVENT_CATEGORY_CONNECTION = CFG_LOGLEVEL_CONNECTION, + /** + * Backup related log events + */ + NDB_MGM_EVENT_CATEGORY_BACKUP = CFG_LOGLEVEL_BACKUP, + /** + * Congestion related log events + */ + NDB_MGM_EVENT_CATEGORY_CONGESTION = CFG_LOGLEVEL_CONGESTION, +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + /** + * Loglevel debug + */ + NDB_MGM_EVENT_CATEGORY_DEBUG = CFG_LOGLEVEL_DEBUG, +#endif + /** + * Uncategorized log events (severity info) + */ + NDB_MGM_EVENT_CATEGORY_INFO = CFG_LOGLEVEL_INFO, + /** + * Uncategorized log events (severity warning or higher) + */ + NDB_MGM_EVENT_CATEGORY_ERROR = CFG_LOGLEVEL_ERROR, +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + NDB_MGM_MIN_EVENT_CATEGORY = CFG_MIN_LOGLEVEL, + NDB_MGM_MAX_EVENT_CATEGORY = CFG_MAX_LOGLEVEL +#endif + }; + + /** + * Structure to store and retrieve log event information. + * @see @ref secSLogEvents + */ + struct ndb_logevent { + /** NdbLogEventHandle (to be used for comparing only) + * set in ndb_logevent_get_next() + */ + void *handle; + + /** Which event */ + enum Ndb_logevent_type type; + + /** Time when log event was registred at the management server */ + unsigned time; + + /** Category of log event */ + enum ndb_mgm_event_category category; + + /** Severity of log event */ + enum ndb_mgm_event_severity severity; + + /** Level (0-15) of log event */ + unsigned level; + + /** Node ID of the node that reported the log event */ + unsigned source_nodeid; + + /** Union of log event specific data. Use @ref type to decide + * which struct to use + */ + union { + /* CONNECT */ + struct { + unsigned node; + } Connected; + + struct { + unsigned node; + } Disconnected; + + struct { + unsigned node; + } CommunicationClosed; + + struct { + unsigned node; + } CommunicationOpened; + + struct { + unsigned node; + unsigned version; + } ConnectedApiVersion; + + /* CHECKPOINT */ + struct { + unsigned gci; + } GlobalCheckpointStarted; + struct { + unsigned gci; + } GlobalCheckpointCompleted; + struct { + unsigned lci; + unsigned keep_gci; + unsigned restore_gci; + } LocalCheckpointStarted; + struct { + unsigned lci; + } LocalCheckpointCompleted; + struct { + unsigned data; + } LCPStoppedInCalcKeepGci; + struct { + unsigned node; + unsigned table_id; + unsigned fragment_id; + } LCPFragmentCompleted; + struct { + unsigned acc_count; + unsigned tup_count; + } UndoLogBlocked; + + /* STARTUP */ + struct { + unsigned version; + } NDBStartStarted; + struct { + unsigned version; + } NDBStartCompleted; + struct { + } STTORRYRecieved; + struct { + unsigned phase; + unsigned starttype; + } StartPhaseCompleted; + struct { + unsigned own_id; + unsigned president_id; + unsigned dynamic_id; + } CM_REGCONF; + struct { + unsigned own_id; + unsigned other_id; + unsigned cause; + } CM_REGREF; + struct { + unsigned own_id; + unsigned left_id; + unsigned right_id; + unsigned dynamic_id; + } FIND_NEIGHBOURS; + struct { + unsigned stoptype; + } NDBStopStarted; + struct { + } NDBStopAborted; + struct { + unsigned node; + unsigned keep_gci; + unsigned completed_gci; + unsigned restorable_gci; + } StartREDOLog; + struct { + unsigned log_part; + unsigned start_mb; + unsigned stop_mb; + unsigned gci; + } StartLog; + struct { + unsigned block; + unsigned data1; + unsigned data2; + unsigned data3; + unsigned data4; + unsigned data5; + unsigned data6; + unsigned data7; + unsigned data8; + unsigned data9; + unsigned data10; + } UNDORecordsExecuted; + + /* NODERESTART */ + struct { + } NR_CopyDict; + struct { + } NR_CopyDistr; + struct { + unsigned dest_node; + } NR_CopyFragsStarted; + struct { + unsigned dest_node; + unsigned table_id; + unsigned fragment_id; + } NR_CopyFragDone; + struct { + unsigned dest_node; + } NR_CopyFragsCompleted; + + struct { + unsigned block; /* 0 = all */ + unsigned failed_node; + unsigned completing_node; /* 0 = all */ + } NodeFailCompleted; + struct { + unsigned failed_node; + unsigned failure_state; + } NODE_FAILREP; + struct { + /* TODO */ + } ArbitState; + struct { + /* TODO */ + } ArbitResult; + struct { + } GCP_TakeoverStarted; + struct { + } GCP_TakeoverCompleted; + struct { + } LCP_TakeoverStarted; + struct { + unsigned state; + } LCP_TakeoverCompleted; + + /* STATISTIC */ + struct { + unsigned trans_count; + unsigned commit_count; + unsigned read_count; + unsigned simple_read_count; + unsigned write_count; + unsigned attrinfo_count; + unsigned conc_op_count; + unsigned abort_count; + unsigned scan_count; + unsigned range_scan_count; + } TransReportCounters; + struct { + unsigned ops; + } OperationReportCounters; + struct { + unsigned table_id; + } TableCreated; + struct { + unsigned mean_loop_count; + } JobStatistic; + struct { + unsigned to_node; + unsigned mean_sent_bytes; + } SendBytesStatistic; + struct { + unsigned from_node; + unsigned mean_received_bytes; + } ReceiveBytesStatistic; + struct { + int gth; + unsigned page_size_kb; + unsigned pages_used; + unsigned pages_total; + unsigned block; + } MemoryUsage; + + /* ERROR */ + struct { + unsigned to_node; + unsigned code; + } TransporterError; + struct { + unsigned to_node; + unsigned code; + } TransporterWarning; + struct { + unsigned node; + unsigned count; + } MissedHeartbeat; + struct { + unsigned node; + } DeadDueToHeartbeat; + struct { + /* TODO */ + } WarningEvent; + + /* INFO */ + struct { + unsigned node; + } SentHeartbeat; + struct { + unsigned node; + } CreateLogBytes; + struct { + /* TODO */ + } InfoEvent; + + /** Log event data for @ref NDB_LE_BackupStarted */ + struct { + unsigned starting_node; + unsigned backup_id; + } BackupStarted; + /** Log event data @ref NDB_LE_BackupFailedToStart */ + struct { + unsigned starting_node; + unsigned error; + } BackupFailedToStart; + /** Log event data @ref NDB_LE_BackupCompleted */ + struct { + unsigned starting_node; + unsigned backup_id; + unsigned start_gci; + unsigned stop_gci; + unsigned n_records; + unsigned n_log_records; + unsigned n_bytes; + unsigned n_log_bytes; + } BackupCompleted; + /** Log event data @ref NDB_LE_BackupAborted */ + struct { + unsigned starting_node; + unsigned backup_id; + unsigned error; + } BackupAborted; +#ifndef DOXYGEN_FIX + }; +#else + } ; +#endif + }; + +enum ndb_logevent_handle_error { + NDB_LEH_NO_ERROR, + NDB_LEH_READ_ERROR, + NDB_LEH_MISSING_EVENT_SPECIFIER, + NDB_LEH_UNKNOWN_EVENT_TYPE, + NDB_LEH_UNKNOWN_EVENT_VARIABLE, + NDB_LEH_INTERNAL_ERROR +}; + #ifdef __cplusplus } #endif +/** @} */ + #endif diff --git a/ndb/include/ndb_constants.h b/ndb/include/ndb_constants.h index 491d0719a69..a04afe1bd72 100644 --- a/ndb/include/ndb_constants.h +++ b/ndb/include/ndb_constants.h @@ -48,7 +48,7 @@ #define NDB_TYPE_BIGUNSIGNED 10 #define NDB_TYPE_FLOAT 11 #define NDB_TYPE_DOUBLE 12 -#define NDB_TYPE_DECIMAL 13 // not used +#define NDB_TYPE_DECIMAL 13 /* not used */ #define NDB_TYPE_CHAR 14 #define NDB_TYPE_VARCHAR 15 #define NDB_TYPE_BINARY 16 diff --git a/ndb/include/ndb_global.h.in b/ndb/include/ndb_global.h.in index dd1d1c05db8..43f90e1f8b5 100644 --- a/ndb/include/ndb_global.h.in +++ b/ndb/include/ndb_global.h.in @@ -115,10 +115,8 @@ static const char table_name_separator = '/'; #endif #ifdef __cplusplus -#include -#endif - -#ifdef __cplusplus +inline void* operator new(size_t, void* __p) { return __p; } +inline void* operator new[](size_t, void* __p) { return __p; } extern "C" { #endif diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h index dc95149f706..9151aee6cf2 100644 --- a/ndb/include/util/ndb_opts.h +++ b/ndb/include/util/ndb_opts.h @@ -34,7 +34,7 @@ OPT_NDB_OPTIMIZED_NODE_SELECTION #define OPT_NDB_CONNECTSTRING 'c' -#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 +#if defined(NOT_ENOUGH_TESTED) && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 #define OPT_NDB_SHM_DEFAULT 1 #else #define OPT_NDB_SHM_DEFAULT 0 diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp index 7ffcde88ce2..32a170d27a4 100644 --- a/ndb/src/common/debugger/EventLogger.cpp +++ b/ndb/src/common/debugger/EventLogger.cpp @@ -33,1276 +33,697 @@ EventLoggerBase::~EventLoggerBase() } + +#define QQQQ char *m_text, size_t m_text_len, const Uint32* theData + +void getTextConnected(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node %u Connected", + theData[1]); +} +void getTextConnectedApiVersion(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node %u: API version %d.%d.%d", + theData[1], + getMajor(theData[2]), + getMinor(theData[2]), + getBuild(theData[2])); +} +void getTextDisconnected(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node %u Disconnected", + theData[1]); +} +void getTextCommunicationClosed(QQQQ) { + //----------------------------------------------------------------------- + // REPORT communication to node closed. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Communication to Node %u closed", + theData[1]); +} +void getTextCommunicationOpened(QQQQ) { + //----------------------------------------------------------------------- + // REPORT communication to node opened. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Communication to Node %u opened", + theData[1]); +} +void getTextNDBStartStarted(QQQQ) { + //----------------------------------------------------------------------- + // Start of NDB has been initiated. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Start initiated (version %d.%d.%d)", + getMajor(theData[1]), + getMinor(theData[1]), + getBuild(theData[1])); +} +void getTextNDBStopStarted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "%s shutdown initiated", + (theData[1] == 1 ? "Cluster" : "Node")); +} +void getTextNDBStopAborted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node shutdown aborted"); +} +void getTextNDBStartCompleted(QQQQ) { + //----------------------------------------------------------------------- + // Start of NDB has been completed. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Started (version %d.%d.%d)", + getMajor(theData[1]), + getMinor(theData[1]), + getBuild(theData[1])); +} +void getTextSTTORRYRecieved(QQQQ) { + //----------------------------------------------------------------------- + // STTORRY recevied after restart finished. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "STTORRY received after restart finished"); +} +void getTextStartPhaseCompleted(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Start phase completed. + //----------------------------------------------------------------------- + const char *type = ""; + switch((NodeState::StartType)theData[2]){ + case NodeState::ST_INITIAL_START: + type = "(initial start)"; + break; + case NodeState::ST_SYSTEM_RESTART: + type = "(system restart)"; + break; + case NodeState::ST_NODE_RESTART: + type = "(node restart)"; + break; + case NodeState::ST_INITIAL_NODE_RESTART: + type = "(initial node restart)"; + break; + case NodeState::ST_ILLEGAL_TYPE: + type = ""; + break; + default: + BaseString::snprintf(m_text, m_text_len, + "Start phase %u completed (unknown = %d)", + theData[1], + theData[2]); + return; + } + BaseString::snprintf(m_text, m_text_len, + "Start phase %u completed %s", + theData[1], + type); +} +void getTextCM_REGCONF(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "CM_REGCONF president = %u, own Node = %u, our dynamic id = %u", + theData[2], + theData[1], + theData[3]); +} +void getTextCM_REGREF(QQQQ) { + const char* line = ""; + switch (theData[3]) { + case 0: + line = "Busy"; + break; + case 1: + line = "Election with wait = false"; + break; + case 2: + line = "Election with wait = false"; + break; + case 3: + line = "Not president"; + break; + case 4: + line = "Election without selecting new candidate"; + break; + default: + line = "No such cause"; + break; + }//switch + + BaseString::snprintf(m_text, m_text_len, + "CM_REGREF from Node %u to our Node %u. Cause = %s", + theData[2], + theData[1], + line); +} +void getTextFIND_NEIGHBOURS(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart copied a fragment. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "We are Node %u with dynamic ID %u, our left neighbour " + "is Node %u, our right is Node %u", + theData[1], + theData[4], + theData[2], + theData[3]); +} +void getTextNodeFailCompleted(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node failure phase completed. + //----------------------------------------------------------------------- + if (theData[1] == 0) + { + if (theData[3] != 0) { + BaseString::snprintf(m_text, m_text_len, + "Node %u completed failure of Node %u", + theData[3], + theData[2]); + } else { + BaseString::snprintf(m_text, m_text_len, + "All nodes completed failure of Node %u", + theData[2]); + }//if + } else { + const char* line = ""; + if (theData[1] == DBTC){ + line = "DBTC"; + }else if (theData[1] == DBDICT){ + line = "DBDICT"; + }else if (theData[1] == DBDIH){ + line = "DBDIH"; + }else if (theData[1] == DBLQH){ + line = "DBLQH"; + } + BaseString::snprintf(m_text, m_text_len, + "Node failure of %u %s completed", + theData[2], + line); + } +} +void getTextNODE_FAILREP(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node %u has failed. The Node state at failure " + "was %u", + theData[1], + theData[2]); +} +void getTextArbitState(QQQQ) { + //----------------------------------------------------------------------- + // REPORT arbitrator found or lost. + //----------------------------------------------------------------------- + { + const ArbitSignalData* sd = (ArbitSignalData*)theData; + char ticketText[ArbitTicket::TextLength + 1]; + char errText[ArbitCode::ErrTextLength + 1]; + const unsigned code = sd->code & 0xFFFF; + const unsigned state = sd->code >> 16; + switch (code) { + case ArbitCode::ThreadStart: + BaseString::snprintf(m_text, m_text_len, + "President restarts arbitration thread [state=%u]", + state); + break; + case ArbitCode::PrepPart2: + sd->ticket.getText(ticketText, sizeof(ticketText)); + BaseString::snprintf(m_text, m_text_len, + "Prepare arbitrator node %u [ticket=%s]", + sd->node, ticketText); + break; + case ArbitCode::PrepAtrun: + sd->ticket.getText(ticketText, sizeof(ticketText)); + BaseString::snprintf(m_text, m_text_len, + "Receive arbitrator node %u [ticket=%s]", + sd->node, ticketText); + break; + case ArbitCode::ApiStart: + sd->ticket.getText(ticketText, sizeof(ticketText)); + BaseString::snprintf(m_text, m_text_len, + "Started arbitrator node %u [ticket=%s]", + sd->node, ticketText); + break; + case ArbitCode::ApiFail: + BaseString::snprintf(m_text, m_text_len, + "Lost arbitrator node %u - process failure [state=%u]", + sd->node, state); + break; + case ArbitCode::ApiExit: + BaseString::snprintf(m_text, m_text_len, + "Lost arbitrator node %u - process exit [state=%u]", + sd->node, state); + break; + default: + ArbitCode::getErrText(code, errText, sizeof(errText)); + BaseString::snprintf(m_text, m_text_len, + "Lost arbitrator node %u - %s [state=%u]", + sd->node, errText, state); + break; + } + } +} + +void getTextArbitResult(QQQQ) { + //----------------------------------------------------------------------- + // REPORT arbitration result (the failures may not reach us). + //----------------------------------------------------------------------- + { + const ArbitSignalData* sd = (ArbitSignalData*)theData; + char errText[ArbitCode::ErrTextLength + 1]; + const unsigned code = sd->code & 0xFFFF; + const unsigned state = sd->code >> 16; + switch (code) { + case ArbitCode::LoseNodes: + BaseString::snprintf(m_text, m_text_len, + "Arbitration check lost - less than 1/2 nodes left"); + break; + case ArbitCode::WinNodes: + BaseString::snprintf(m_text, m_text_len, + "Arbitration check won - all node groups and more than 1/2 nodes left"); + break; + case ArbitCode::WinGroups: + BaseString::snprintf(m_text, m_text_len, + "Arbitration check won - node group majority"); + break; + case ArbitCode::LoseGroups: + BaseString::snprintf(m_text, m_text_len, + "Arbitration check lost - missing node group"); + break; + case ArbitCode::Partitioning: + BaseString::snprintf(m_text, m_text_len, + "Network partitioning - arbitration required"); + break; + case ArbitCode::WinChoose: + BaseString::snprintf(m_text, m_text_len, + "Arbitration won - positive reply from node %u", + sd->node); + break; + case ArbitCode::LoseChoose: + BaseString::snprintf(m_text, m_text_len, + "Arbitration lost - negative reply from node %u", + sd->node); + break; + case ArbitCode::LoseNorun: + BaseString::snprintf(m_text, m_text_len, + "Network partitioning - no arbitrator available"); + break; + case ArbitCode::LoseNocfg: + BaseString::snprintf(m_text, m_text_len, + "Network partitioning - no arbitrator configured"); + break; + default: + ArbitCode::getErrText(code, errText, sizeof(errText)); + BaseString::snprintf(m_text, m_text_len, + "Arbitration failure - %s [state=%u]", + errText, state); + break; + } + } +} +void getTextGlobalCheckpointStarted(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a global checkpoint has been started and this + // node is the master of this global checkpoint. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Global checkpoint %u started", + theData[1]); +} +void getTextGlobalCheckpointCompleted(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a global checkpoint has been completed on this + // node and the node is the master of this global checkpoint. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Global checkpoint %u completed", + theData[1]); +} +void getTextLocalCheckpointStarted(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a local checkpoint has been started and this + // node is the master of this local checkpoint. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Local checkpoint %u started. " + "Keep GCI = %u oldest restorable GCI = %u", + theData[1], + theData[2], + theData[3]); +} +void getTextLocalCheckpointCompleted(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a local checkpoint has been completed on this + // node and the node is the master of this local checkpoint. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Local checkpoint %u completed", + theData[1]); +} +void getTextTableCreated(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a table has been created. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Table with ID = %u created", + theData[1]); +} +/* STRANGE */ +void getTextLCPStoppedInCalcKeepGci(QQQQ) { + if (theData[1] == 0) + BaseString::snprintf(m_text, m_text_len, + "Local Checkpoint stopped in CALCULATED_KEEP_GCI"); +} +void getTextNR_CopyDict(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart completed copy of dictionary information. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node restart completed copy of dictionary information"); +} +void getTextNR_CopyDistr(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart completed copy of distribution information. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node restart completed copy of distribution information"); +} +void getTextNR_CopyFragsStarted(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart is starting to copy the fragments. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node restart starting to copy the fragments " + "to Node %u", + theData[1]); +} +void getTextNR_CopyFragDone(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart copied a fragment. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Table ID = %u, fragment ID = %u have been copied " + "to Node %u", + theData[2], + theData[3], + theData[1]); +} +void getTextNR_CopyFragsCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node restart completed copying the fragments " + "to Node %u", + theData[1]); +} +void getTextLCPFragmentCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Table ID = %u, fragment ID = %u has completed LCP " + "on Node %u", + theData[2], + theData[3], + theData[1]); +} +void getTextTransReportCounters(QQQQ) { + // ------------------------------------------------------------------- + // Report information about transaction activity once per 10 seconds. + // ------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Trans. Count = %u, Commit Count = %u, " + "Read Count = %u, Simple Read Count = %u,\n" + "Write Count = %u, AttrInfo Count = %u, " + "Concurrent Operations = %u, Abort Count = %u\n" + " Scans: %u Range scans: %u", + theData[1], + theData[2], + theData[3], + theData[4], + theData[5], + theData[6], + theData[7], + theData[8], + theData[9], + theData[10]); +} +void getTextOperationReportCounters(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Operations=%u", + theData[1]); +} +void getTextUndoLogBlocked(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Undo Logging blocked due to buffer near to overflow. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "ACC Blocked %u and TUP Blocked %u times last second", + theData[1], + theData[2]); +} +void getTextTransporterError(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Transporter to node %d reported error 0x%x", + theData[1], + theData[2]); +} +void getTextTransporterWarning(QQQQ) { + getTextTransporterError(m_text, m_text_len, theData); +} +void getTextMissedHeartbeat(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Undo Logging blocked due to buffer near to overflow. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node %d missed heartbeat %d", + theData[1], + theData[2]); +} +void getTextDeadDueToHeartbeat(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Undo Logging blocked due to buffer near to overflow. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node %d declared dead due to missed heartbeat", + theData[1]); +} +void getTextJobStatistic(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Mean loop Counter in doJob last 8192 times = %u", + theData[1]); +} +void getTextSendBytesStatistic(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Mean send size to Node = %d last 4096 sends = %u bytes", + theData[1], + theData[2]); +} +void getTextReceiveBytesStatistic(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Mean receive size to Node = %d last 4096 sends = %u bytes", + theData[1], + theData[2]); +} +void getTextSentHeartbeat(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node Sent Heartbeat to node = %d", + theData[1]); +} +void getTextCreateLogBytes(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Log part %u, log file %u, MB %u", + theData[1], + theData[2], + theData[3]); +} +void getTextStartLog(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Log part %u, start MB %u, stop MB %u, last GCI, log exec %u", + theData[1], + theData[2], + theData[3], + theData[4]); +} +void getTextStartREDOLog(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node: %d StartLog: [GCI Keep: %d LastCompleted: %d NewestRestorable: %d]", + theData[1], + theData[2], + theData[3], + theData[4]); +} +void getTextUNDORecordsExecuted(QQQQ) { + const char* line = ""; + if (theData[1] == DBTUP){ + line = "DBTUP"; + }else if (theData[1] == DBACC){ + line = "DBACC"; + } + + BaseString::snprintf(m_text, m_text_len, + " UNDO %s %d [%d %d %d %d %d %d %d %d %d]", + line, + theData[2], + theData[3], + theData[4], + theData[5], + theData[6], + theData[7], + theData[8], + theData[9], + theData[10], + theData[11]); +} +void getTextInfoEvent(QQQQ) { + BaseString::snprintf(m_text, m_text_len, (char *)&theData[1]); +} +void getTextWarningEvent(QQQQ) { + BaseString::snprintf(m_text, m_text_len, (char *)&theData[1]); +} +void getTextGCP_TakeoverStarted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, "GCP Take over started"); +} +void getTextGCP_TakeoverCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, "GCP Take over completed"); +} +void getTextLCP_TakeoverStarted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, "LCP Take over started"); +} +void getTextLCP_TakeoverCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "LCP Take over completed (state = %d)", + theData[1]); +} +void getTextMemoryUsage(QQQQ) { + const int gth = theData[1]; + const int size = theData[2]; + const int used = theData[3]; + const int total = theData[4]; + const int block = theData[5]; + const int percent = (used*100)/total; + + BaseString::snprintf(m_text, m_text_len, + "%s usage %s %d%s(%d %dK pages of total %d)", + (block==DBACC ? "Index" : (block == DBTUP ?"Data":"")), + (gth == 0 ? "is" : (gth > 0 ? "increased to" : "decreased to")), + percent, "%", + used, size/1024, total + ); +} + +void getTextBackupStarted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Backup %d started from node %d", + theData[2], refToNode(theData[1])); +} +void getTextBackupFailedToStart(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Backup request from %d failed to start. Error: %d", + refToNode(theData[1]), theData[2]); +} +void getTextBackupCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Backup %u started from node %u completed\n" + " StartGCP: %u StopGCP: %u\n" + " #Records: %u #LogRecords: %u\n" + " Data: %u bytes Log: %u bytes", + theData[2], refToNode(theData[1]), + theData[3], theData[4], theData[6], theData[8], + theData[5], theData[7]); +} +void getTextBackupAborted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Backup %d started from %d has been aborted. Error: %d", + theData[2], + refToNode(theData[1]), + theData[3]); +} + +#if 0 +BaseString::snprintf(m_text, + m_text_len, + "Unknown event: %d", + theData[0]); +#endif + /** * This matrix defines which event should be printed when * * threshold - is in range [0-15] * severity - DEBUG to ALERT (Type of log message) */ + +#define ROW(a,b,c,d) \ +{ NDB_LE_ ## a, b, c, d, getText ## a} + const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = { // CONNECTION - { NDB_LE_Connected, LogLevel::llConnection, 8, Logger::LL_INFO }, - { NDB_LE_Disconnected, LogLevel::llConnection, 8, Logger::LL_ALERT }, - { NDB_LE_CommunicationClosed, LogLevel::llConnection, 8, Logger::LL_INFO }, - { NDB_LE_CommunicationOpened, LogLevel::llConnection, 8, Logger::LL_INFO }, - { NDB_LE_ConnectedApiVersion, LogLevel::llConnection, 8, Logger::LL_INFO }, + ROW(Connected, LogLevel::llConnection, 8, Logger::LL_INFO ), + ROW(Disconnected, LogLevel::llConnection, 8, Logger::LL_ALERT ), + ROW(CommunicationClosed, LogLevel::llConnection, 8, Logger::LL_INFO ), + ROW(CommunicationOpened, LogLevel::llConnection, 8, Logger::LL_INFO ), + ROW(ConnectedApiVersion, LogLevel::llConnection, 8, Logger::LL_INFO ), // CHECKPOINT - { NDB_LE_GlobalCheckpointStarted, LogLevel::llCheckpoint, 9, Logger::LL_INFO }, - { NDB_LE_GlobalCheckpointCompleted,LogLevel::llCheckpoint,10, Logger::LL_INFO }, - { NDB_LE_LocalCheckpointStarted, LogLevel::llCheckpoint, 7, Logger::LL_INFO }, - { NDB_LE_LocalCheckpointCompleted,LogLevel::llCheckpoint, 8, Logger::LL_INFO }, - { NDB_LE_LCPStoppedInCalcKeepGci, LogLevel::llCheckpoint, 0, Logger::LL_ALERT }, - { NDB_LE_LCPFragmentCompleted, LogLevel::llCheckpoint, 11, Logger::LL_INFO }, - { NDB_LE_UndoLogBlocked, LogLevel::llCheckpoint, 7, Logger::LL_INFO }, + ROW(GlobalCheckpointStarted, LogLevel::llCheckpoint, 9, Logger::LL_INFO ), + ROW(GlobalCheckpointCompleted,LogLevel::llCheckpoint,10, Logger::LL_INFO ), + ROW(LocalCheckpointStarted, LogLevel::llCheckpoint, 7, Logger::LL_INFO ), + ROW(LocalCheckpointCompleted,LogLevel::llCheckpoint, 8, Logger::LL_INFO ), + ROW(LCPStoppedInCalcKeepGci, LogLevel::llCheckpoint, 0, Logger::LL_ALERT ), + ROW(LCPFragmentCompleted, LogLevel::llCheckpoint, 11, Logger::LL_INFO ), + ROW(UndoLogBlocked, LogLevel::llCheckpoint, 7, Logger::LL_INFO ), // STARTUP - { NDB_LE_NDBStartStarted, LogLevel::llStartUp, 1, Logger::LL_INFO }, - { NDB_LE_NDBStartCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO }, - { NDB_LE_STTORRYRecieved, LogLevel::llStartUp,15, Logger::LL_INFO }, - { NDB_LE_StartPhaseCompleted, LogLevel::llStartUp, 4, Logger::LL_INFO }, - { NDB_LE_CM_REGCONF, LogLevel::llStartUp, 3, Logger::LL_INFO }, - { NDB_LE_CM_REGREF, LogLevel::llStartUp, 8, Logger::LL_INFO }, - { NDB_LE_FIND_NEIGHBOURS, LogLevel::llStartUp, 8, Logger::LL_INFO }, - { NDB_LE_NDBStopStarted, LogLevel::llStartUp, 1, Logger::LL_INFO }, - { NDB_LE_NDBStopAborted, LogLevel::llStartUp, 1, Logger::LL_INFO }, - { NDB_LE_StartREDOLog, LogLevel::llStartUp, 10, Logger::LL_INFO }, - { NDB_LE_StartLog, LogLevel::llStartUp, 10, Logger::LL_INFO }, - { NDB_LE_UNDORecordsExecuted, LogLevel::llStartUp, 15, Logger::LL_INFO }, + ROW(NDBStartStarted, LogLevel::llStartUp, 1, Logger::LL_INFO ), + ROW(NDBStartCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO ), + ROW(STTORRYRecieved, LogLevel::llStartUp, 15, Logger::LL_INFO ), + ROW(StartPhaseCompleted, LogLevel::llStartUp, 4, Logger::LL_INFO ), + ROW(CM_REGCONF, LogLevel::llStartUp, 3, Logger::LL_INFO ), + ROW(CM_REGREF, LogLevel::llStartUp, 8, Logger::LL_INFO ), + ROW(FIND_NEIGHBOURS, LogLevel::llStartUp, 8, Logger::LL_INFO ), + ROW(NDBStopStarted, LogLevel::llStartUp, 1, Logger::LL_INFO ), + ROW(NDBStopAborted, LogLevel::llStartUp, 1, Logger::LL_INFO ), + ROW(StartREDOLog, LogLevel::llStartUp, 10, Logger::LL_INFO ), + ROW(StartLog, LogLevel::llStartUp, 10, Logger::LL_INFO ), + ROW(UNDORecordsExecuted, LogLevel::llStartUp, 15, Logger::LL_INFO ), // NODERESTART - { NDB_LE_NR_CopyDict, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, - { NDB_LE_NR_CopyDistr, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, - { NDB_LE_NR_CopyFragsStarted, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, - { NDB_LE_NR_CopyFragDone, LogLevel::llNodeRestart, 10, Logger::LL_INFO }, - { NDB_LE_NR_CopyFragsCompleted, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, + ROW(NR_CopyDict, LogLevel::llNodeRestart, 8, Logger::LL_INFO ), + ROW(NR_CopyDistr, LogLevel::llNodeRestart, 8, Logger::LL_INFO ), + ROW(NR_CopyFragsStarted, LogLevel::llNodeRestart, 8, Logger::LL_INFO ), + ROW(NR_CopyFragDone, LogLevel::llNodeRestart,10, Logger::LL_INFO ), + ROW(NR_CopyFragsCompleted, LogLevel::llNodeRestart, 8, Logger::LL_INFO ), - { NDB_LE_NodeFailCompleted, LogLevel::llNodeRestart, 8, Logger::LL_ALERT}, - { NDB_LE_NODE_FAILREP, LogLevel::llNodeRestart, 8, Logger::LL_ALERT}, - { NDB_LE_ArbitState, LogLevel::llNodeRestart, 6, Logger::LL_INFO }, - { NDB_LE_ArbitResult, LogLevel::llNodeRestart, 2, Logger::LL_ALERT}, - { NDB_LE_GCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, - { NDB_LE_GCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, - { NDB_LE_LCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, - { NDB_LE_LCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, + ROW(NodeFailCompleted, LogLevel::llNodeRestart, 8, Logger::LL_ALERT), + ROW(NODE_FAILREP, LogLevel::llNodeRestart, 8, Logger::LL_ALERT), + ROW(ArbitState, LogLevel::llNodeRestart, 6, Logger::LL_INFO ), + ROW(ArbitResult, LogLevel::llNodeRestart, 2, Logger::LL_ALERT), + ROW(GCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ), + ROW(GCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ), + ROW(LCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ), + ROW(LCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ), // STATISTIC - { NDB_LE_TransReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO }, - { NDB_LE_OperationReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO }, - { NDB_LE_TableCreated, LogLevel::llStatistic, 7, Logger::LL_INFO }, - { NDB_LE_JobStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, - { NDB_LE_SendBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, - { NDB_LE_ReceiveBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, - { NDB_LE_MemoryUsage, LogLevel::llStatistic, 5, Logger::LL_INFO }, + ROW(TransReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO ), + ROW(OperationReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO ), + ROW(TableCreated, LogLevel::llStatistic, 7, Logger::LL_INFO ), + ROW(JobStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ), + ROW(SendBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ), + ROW(ReceiveBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ), + ROW(MemoryUsage, LogLevel::llStatistic, 5, Logger::LL_INFO ), // ERROR - { NDB_LE_TransporterError, LogLevel::llError, 2, Logger::LL_ERROR }, - { NDB_LE_TransporterWarning, LogLevel::llError, 8, Logger::LL_WARNING }, - { NDB_LE_MissedHeartbeat, LogLevel::llError, 8, Logger::LL_WARNING }, - { NDB_LE_DeadDueToHeartbeat, LogLevel::llError, 8, Logger::LL_ALERT }, - { NDB_LE_WarningEvent, LogLevel::llError, 2, Logger::LL_WARNING }, + ROW(TransporterError, LogLevel::llError, 2, Logger::LL_ERROR ), + ROW(TransporterWarning, LogLevel::llError, 8, Logger::LL_WARNING ), + ROW(MissedHeartbeat, LogLevel::llError, 8, Logger::LL_WARNING ), + ROW(DeadDueToHeartbeat, LogLevel::llError, 8, Logger::LL_ALERT ), + ROW(WarningEvent, LogLevel::llError, 2, Logger::LL_WARNING ), // INFO - { NDB_LE_SentHeartbeat, LogLevel::llInfo, 12, Logger::LL_INFO }, - { NDB_LE_CreateLogBytes, LogLevel::llInfo, 11, Logger::LL_INFO }, - { NDB_LE_InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO }, + ROW(SentHeartbeat, LogLevel::llInfo, 12, Logger::LL_INFO ), + ROW(CreateLogBytes, LogLevel::llInfo, 11, Logger::LL_INFO ), + ROW(InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO ), // Backup - { NDB_LE_BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO }, - { NDB_LE_BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO }, - { NDB_LE_BackupFailedToStart, LogLevel::llBackup, 7, Logger::LL_ALERT}, - { NDB_LE_BackupAborted, LogLevel::llBackup, 7, Logger::LL_ALERT } + ROW(BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO ), + ROW(BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO ), + ROW(BackupFailedToStart, LogLevel::llBackup, 7, Logger::LL_ALERT), + ROW(BackupAborted, LogLevel::llBackup, 7, Logger::LL_ALERT ) }; -const Uint32 EventLoggerBase::matrixSize = sizeof(EventLoggerBase::matrix)/ - sizeof(EventRepLogLevelMatrix); - -const char* -EventLogger::getText(char * m_text, size_t m_text_len, - int type, - const Uint32* theData, NodeId nodeId) -{ - // TODO: Change the switch implementation... - char theNodeId[32]; - if (nodeId != 0){ - BaseString::snprintf(theNodeId, 32, "Node %u: ", nodeId); - } else { - theNodeId[0] = 0; - } - - Ndb_logevent_type eventType = (Ndb_logevent_type)type; - switch (eventType){ - case NDB_LE_Connected: - BaseString::snprintf(m_text, m_text_len, - "%sNode %u Connected", - theNodeId, - theData[1]); - break; - case NDB_LE_ConnectedApiVersion: - BaseString::snprintf(m_text, m_text_len, - "%sNode %u: API version %d.%d.%d", - theNodeId, - theData[1], - getMajor(theData[2]), - getMinor(theData[2]), - getBuild(theData[2])); - break; - case NDB_LE_Disconnected: - BaseString::snprintf(m_text, m_text_len, - "%sNode %u Disconnected", - theNodeId, - theData[1]); - break; - case NDB_LE_CommunicationClosed: - //----------------------------------------------------------------------- - // REPORT communication to node closed. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sCommunication to Node %u closed", - theNodeId, - theData[1]); - break; - case NDB_LE_CommunicationOpened: - //----------------------------------------------------------------------- - // REPORT communication to node opened. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sCommunication to Node %u opened", - theNodeId, - theData[1]); - break; - case NDB_LE_NDBStartStarted: - //----------------------------------------------------------------------- - // Start of NDB has been initiated. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sStart initiated (version %d.%d.%d)", - theNodeId , - getMajor(theData[1]), - getMinor(theData[1]), - getBuild(theData[1])); - break; - case NDB_LE_NDBStopStarted: - BaseString::snprintf(m_text, m_text_len, - "%s%s shutdown initiated", - theNodeId, - (theData[1] == 1 ? "Cluster" : "Node")); - break; - case NDB_LE_NDBStopAborted: - BaseString::snprintf(m_text, m_text_len, - "%sNode shutdown aborted", - theNodeId); - break; - case NDB_LE_NDBStartCompleted: - //----------------------------------------------------------------------- - // Start of NDB has been completed. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sStarted (version %d.%d.%d)", - theNodeId , - getMajor(theData[1]), - getMinor(theData[1]), - getBuild(theData[1])); - - break; - case NDB_LE_STTORRYRecieved: - //----------------------------------------------------------------------- - // STTORRY recevied after restart finished. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sSTTORRY received after restart finished", - theNodeId); - break; - case NDB_LE_StartPhaseCompleted:{ - //----------------------------------------------------------------------- - // REPORT Start phase completed. - //----------------------------------------------------------------------- - const char * type = ""; - switch((NodeState::StartType)theData[2]){ - case NodeState::ST_INITIAL_START: - type = "(initial start)"; - break; - case NodeState::ST_SYSTEM_RESTART: - type = "(system restart)"; - break; - case NodeState::ST_NODE_RESTART: - type = "(node restart)"; - break; - case NodeState::ST_INITIAL_NODE_RESTART: - type = "(initial node restart)"; - break; - case NodeState::ST_ILLEGAL_TYPE: - type = ""; - break; - default:{ - BaseString::snprintf(m_text, m_text_len, - "%sStart phase %u completed (unknown = %d)", - theNodeId, - theData[1], - theData[2]); - return m_text; - } - } - BaseString::snprintf(m_text, m_text_len, - "%sStart phase %u completed %s", - theNodeId, - theData[1], - type); - return m_text; - break; - } - case NDB_LE_CM_REGCONF: - BaseString::snprintf(m_text, m_text_len, - "%sCM_REGCONF president = %u, own Node = %u, our dynamic id = %u" - , - theNodeId, - theData[2], - theData[1], - theData[3]); - break; - case NDB_LE_CM_REGREF: - { - const char* line = ""; - switch (theData[3]) { - case 0: - line = "Busy"; - break; - case 1: - line = "Election with wait = false"; - break; - case 2: - line = "Election with wait = false"; - break; - case 3: - line = "Not president"; - break; - case 4: - line = "Election without selecting new candidate"; - break; - default: - line = "No such cause"; - break; - }//switch - - BaseString::snprintf(m_text, m_text_len, - "%sCM_REGREF from Node %u to our Node %u. Cause = %s", - theNodeId, - theData[2], - theData[1], - line); - } - break; - case NDB_LE_FIND_NEIGHBOURS: - //----------------------------------------------------------------------- - // REPORT Node Restart copied a fragment. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sWe are Node %u with dynamic ID %u, our left neighbour " - "is Node %u, our right is Node %u", - theNodeId, - theData[1], - theData[4], - theData[2], - theData[3]); - break; - case NDB_LE_NodeFailCompleted: - //----------------------------------------------------------------------- - // REPORT Node failure phase completed. - //----------------------------------------------------------------------- - if (theData[1] == 0) - { - if (theData[3] != 0) { - BaseString::snprintf(m_text, m_text_len, - "%sNode %u completed failure of Node %u", - theNodeId, - theData[3], - theData[2]); - } else { - BaseString::snprintf(m_text, m_text_len, - "%sAll nodes completed failure of Node %u", - theNodeId, - theData[2]); - }//if - } else { - const char* line = ""; - if (theData[1] == DBTC){ - line = "DBTC"; - }else if (theData[1] == DBDICT){ - line = "DBDICT"; - }else if (theData[1] == DBDIH){ - line = "DBDIH"; - }else if (theData[1] == DBLQH){ - line = "DBLQH"; - } - - BaseString::snprintf(m_text, m_text_len, - "%sNode failure of %u %s completed", - theNodeId, - theData[2], - line); - } - break; - case NDB_LE_NODE_FAILREP: - BaseString::snprintf(m_text, - m_text_len, - "%sNode %u has failed. The Node state at failure " - "was %u", - theNodeId, - theData[1], - theData[2]); - - break; - case NDB_LE_ArbitState: - //----------------------------------------------------------------------- - // REPORT arbitrator found or lost. - //----------------------------------------------------------------------- - { const ArbitSignalData* sd = (ArbitSignalData*)theData; - char ticketText[ArbitTicket::TextLength + 1]; - char errText[ArbitCode::ErrTextLength + 1]; - const unsigned code = sd->code & 0xFFFF; - const unsigned state = sd->code >> 16; - switch (code) { - case ArbitCode::ThreadStart: - BaseString::snprintf(m_text, m_text_len, - "%sPresident restarts arbitration thread [state=%u]", - theNodeId, state); - break; - case ArbitCode::PrepPart2: - sd->ticket.getText(ticketText, sizeof(ticketText)); - BaseString::snprintf(m_text, m_text_len, - "%sPrepare arbitrator node %u [ticket=%s]", - theNodeId, sd->node, ticketText); - break; - case ArbitCode::PrepAtrun: - sd->ticket.getText(ticketText, sizeof(ticketText)); - BaseString::snprintf(m_text, m_text_len, - "%sReceive arbitrator node %u [ticket=%s]", - theNodeId, sd->node, ticketText); - break; - case ArbitCode::ApiStart: - sd->ticket.getText(ticketText, sizeof(ticketText)); - BaseString::snprintf(m_text, m_text_len, - "%sStarted arbitrator node %u [ticket=%s]", - theNodeId, sd->node, ticketText); - break; - case ArbitCode::ApiFail: - BaseString::snprintf(m_text, m_text_len, - "%sLost arbitrator node %u - process failure [state=%u]", - theNodeId, sd->node, state); - break; - case ArbitCode::ApiExit: - BaseString::snprintf(m_text, m_text_len, - "%sLost arbitrator node %u - process exit [state=%u]", - theNodeId, sd->node, state); - break; - default: - ArbitCode::getErrText(code, errText, sizeof(errText)); - BaseString::snprintf(m_text, m_text_len, - "%sLost arbitrator node %u - %s [state=%u]", - theNodeId, sd->node, errText, state); - break; - } - } - break; - case NDB_LE_ArbitResult: - //----------------------------------------------------------------------- - // REPORT arbitration result (the failures may not reach us). - //----------------------------------------------------------------------- - { const ArbitSignalData* sd = (ArbitSignalData*)theData; - char errText[ArbitCode::ErrTextLength + 1]; - const unsigned code = sd->code & 0xFFFF; - const unsigned state = sd->code >> 16; - switch (code) { - case ArbitCode::LoseNodes: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration check lost - less than 1/2 nodes left", - theNodeId); - break; - case ArbitCode::WinNodes: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration check won - all node groups and more than 1/2 nodes left", - theNodeId); - break; - case ArbitCode::WinGroups: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration check won - node group majority", - theNodeId); - break; - case ArbitCode::LoseGroups: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration check lost - missing node group", - theNodeId); - break; - case ArbitCode::Partitioning: - BaseString::snprintf(m_text, m_text_len, - "%sNetwork partitioning - arbitration required", - theNodeId); - break; - case ArbitCode::WinChoose: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration won - positive reply from node %u", - theNodeId, sd->node); - break; - case ArbitCode::LoseChoose: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration lost - negative reply from node %u", - theNodeId, sd->node); - break; - case ArbitCode::LoseNorun: - BaseString::snprintf(m_text, m_text_len, - "%sNetwork partitioning - no arbitrator available", - theNodeId); - break; - case ArbitCode::LoseNocfg: - BaseString::snprintf(m_text, m_text_len, - "%sNetwork partitioning - no arbitrator configured", - theNodeId); - break; - default: - ArbitCode::getErrText(code, errText, sizeof(errText)); - BaseString::snprintf(m_text, m_text_len, - "%sArbitration failure - %s [state=%u]", - theNodeId, errText, state); - break; - } - } - break; - case NDB_LE_GlobalCheckpointStarted: - //----------------------------------------------------------------------- - // This event reports that a global checkpoint has been started and this - // node is the master of this global checkpoint. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sGlobal checkpoint %u started", - theNodeId, - theData[1]); - break; - case NDB_LE_GlobalCheckpointCompleted: - //----------------------------------------------------------------------- - // This event reports that a global checkpoint has been completed on this - // node and the node is the master of this global checkpoint. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sGlobal checkpoint %u completed", - theNodeId, - theData[1]); - break; - case NDB_LE_LocalCheckpointStarted: - //----------------------------------------------------------------------- - // This event reports that a local checkpoint has been started and this - // node is the master of this local checkpoint. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sLocal checkpoint %u started. " - "Keep GCI = %u oldest restorable GCI = %u", - theNodeId, - theData[1], - theData[2], - theData[3]); - break; - case NDB_LE_LocalCheckpointCompleted: - //----------------------------------------------------------------------- - // This event reports that a local checkpoint has been completed on this - // node and the node is the master of this local checkpoint. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sLocal checkpoint %u completed", - theNodeId, - theData[1]); - break; - case NDB_LE_TableCreated: - //----------------------------------------------------------------------- - // This event reports that a table has been created. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sTable with ID = %u created", - theNodeId, - theData[1]); - break; - case NDB_LE_LCPStoppedInCalcKeepGci: - if (theData[1] == 0) - BaseString::snprintf(m_text, m_text_len, - "%sLocal Checkpoint stopped in CALCULATED_KEEP_GCI", - theNodeId); - break; - case NDB_LE_NR_CopyDict: - //----------------------------------------------------------------------- - // REPORT Node Restart completed copy of dictionary information. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode restart completed copy of dictionary information", - theNodeId); - break; - case NDB_LE_NR_CopyDistr: - //----------------------------------------------------------------------- - // REPORT Node Restart completed copy of distribution information. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode restart completed copy of distribution information", - theNodeId); - break; - case NDB_LE_NR_CopyFragsStarted: - //----------------------------------------------------------------------- - // REPORT Node Restart is starting to copy the fragments. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode restart starting to copy the fragments " - "to Node %u", - theNodeId, - theData[1]); - break; - case NDB_LE_NR_CopyFragDone: - //----------------------------------------------------------------------- - // REPORT Node Restart copied a fragment. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sTable ID = %u, fragment ID = %u have been copied " - "to Node %u", - theNodeId, - theData[2], - theData[3], - theData[1]); - break; - case NDB_LE_NR_CopyFragsCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sNode restart completed copying the fragments " - "to Node %u", - theNodeId, - theData[1]); - break; - case NDB_LE_LCPFragmentCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sTable ID = %u, fragment ID = %u has completed LCP " - "on Node %u", - theNodeId, - theData[2], - theData[3], - theData[1]); - break; - case NDB_LE_TransReportCounters: - // ------------------------------------------------------------------- - // Report information about transaction activity once per 10 seconds. - // ------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sTrans. Count = %u, Commit Count = %u, " - "Read Count = %u, Simple Read Count = %u,\n" - "Write Count = %u, AttrInfo Count = %u, " - "Concurrent Operations = %u, Abort Count = %u\n" - " Scans: %u Range scans: %u", - theNodeId, - theData[1], - theData[2], - theData[3], - theData[4], - theData[5], - theData[6], - theData[7], - theData[8], - theData[9], - theData[10]); - break; - case NDB_LE_OperationReportCounters: - BaseString::snprintf(m_text, m_text_len, - "%sOperations=%u", - theNodeId, - theData[1]); - break; - case NDB_LE_UndoLogBlocked: - //----------------------------------------------------------------------- - // REPORT Undo Logging blocked due to buffer near to overflow. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sACC Blocked %u and TUP Blocked %u times last second", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_TransporterError: - case NDB_LE_TransporterWarning: - BaseString::snprintf(m_text, - m_text_len, - "%sTransporter to node %d reported error 0x%x", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_MissedHeartbeat: - //----------------------------------------------------------------------- - // REPORT Undo Logging blocked due to buffer near to overflow. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode %d missed heartbeat %d", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_DeadDueToHeartbeat: - //----------------------------------------------------------------------- - // REPORT Undo Logging blocked due to buffer near to overflow. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode %d declared dead due to missed heartbeat", - theNodeId, - theData[1]); - break; - case NDB_LE_JobStatistic: - BaseString::snprintf(m_text, - m_text_len, - "%sMean loop Counter in doJob last 8192 times = %u", - theNodeId, - theData[1]); - break; - case NDB_LE_SendBytesStatistic: - BaseString::snprintf(m_text, - m_text_len, - "%sMean send size to Node = %d last 4096 sends = %u bytes", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_ReceiveBytesStatistic: - BaseString::snprintf(m_text, - m_text_len, - "%sMean receive size to Node = %d last 4096 sends = %u bytes", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_SentHeartbeat: - BaseString::snprintf(m_text, - m_text_len, - "%sNode Sent Heartbeat to node = %d", - theNodeId, - theData[1]); - break; - case NDB_LE_CreateLogBytes: - BaseString::snprintf(m_text, - m_text_len, - "%sLog part %u, log file %u, MB %u", - theNodeId, - theData[1], - theData[2], - theData[3]); - break; - case NDB_LE_StartLog: - BaseString::snprintf(m_text, - m_text_len, - "%sLog part %u, start MB %u, stop MB %u, last GCI, log exec %u", - theNodeId, - theData[1], - theData[2], - theData[3], - theData[4]); - break; - case NDB_LE_StartREDOLog: - BaseString::snprintf(m_text, - m_text_len, - "%sNode: %d StartLog: [GCI Keep: %d LastCompleted: %d NewestRestorable: %d]", - theNodeId, - theData[1], - theData[2], - theData[3], - theData[4]); - break; - case NDB_LE_UNDORecordsExecuted:{ - const char* line = ""; - if (theData[1] == DBTUP){ - line = "DBTUP"; - }else if (theData[1] == DBACC){ - line = "DBACC"; - } - - BaseString::snprintf(m_text, - m_text_len, - "%s UNDO %s %d [%d %d %d %d %d %d %d %d %d]", - theNodeId, - line, - theData[2], - theData[3], - theData[4], - theData[5], - theData[6], - theData[7], - theData[8], - theData[9], - theData[10], - theData[11]); - } - break; - case NDB_LE_InfoEvent: - BaseString::snprintf(m_text, - m_text_len, - "%s%s", - theNodeId, - (char *)&theData[1]); - break; - case NDB_LE_WarningEvent: - BaseString::snprintf(m_text, - m_text_len, - "%s%s", - theNodeId, - (char *)&theData[1]); - break; - case NDB_LE_GCP_TakeoverStarted: - BaseString::snprintf(m_text, - m_text_len, - "%sGCP Take over started", theNodeId); - break; - case NDB_LE_GCP_TakeoverCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sGCP Take over completed", theNodeId); - break; - case NDB_LE_LCP_TakeoverStarted: - BaseString::snprintf(m_text, - m_text_len, - "%sLCP Take over started", theNodeId); - break; - case NDB_LE_LCP_TakeoverCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sLCP Take over completed (state = %d)", - theNodeId, theData[1]); - break; - case NDB_LE_MemoryUsage:{ - const int gth = theData[1]; - const int size = theData[2]; - const int used = theData[3]; - const int total = theData[4]; - const int block = theData[5]; - const int percent = (used*100)/total; - - BaseString::snprintf(m_text, m_text_len, - "%s%s usage %s %d%s(%d %dK pages of total %d)", - theNodeId, - (block==DBACC ? "Index" : (block == DBTUP ?"Data":"")), - (gth == 0 ? "is" : (gth > 0 ? "increased to" : "decreased to")), - percent, "%", - used, size/1024, total - ); - break; - } - case NDB_LE_GrepSubscriptionInfo : - { - GrepEvent::Subscription event = (GrepEvent::Subscription)theData[1]; - switch(event) { - case GrepEvent::GrepSS_CreateSubIdConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Created subscription id" - " (subId=%d,SubKey=%d)" - " Return code: %d.", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_CreateSubIdConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Created subscription id" - " (subId=%d,SubKey=%d)" - " Return code: %d.", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubCreateConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int nodegrp = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Created subscription using" - " (subId=%d,SubKey=%d)" - " in primary system. Primary system has %d nodegroup(s)." - " Return code: %d", - subId, - subKey, - nodegrp, - err); - break; - } - case GrepEvent::GrepPS_SubCreateConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have created " - "subscriptions" - " using (subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubStartMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Logging started on meta data changes." - " using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubStartMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have started " - "logging meta data" - " changes on the subscription subId=%d,SubKey=%d) " - "(N.I yet)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubStartDataConf: { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Logging started on table data changes " - " using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubStartDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have started logging " - "table data changes on the subscription " - "subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubSyncMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have started " - " synchronization on meta data (META SCAN) using " - "(subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubSyncMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Synchronization started (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubSyncDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have started " - "synchronization " - " on table data (DATA SCAN) using (subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubSyncDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Synchronization started (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d" - " Return code: %d", - subId, - subKey, - gci, - err); - break; - } - case GrepEvent::GrepPS_SubRemoveConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have removed " - "subscription (subId=%d,SubKey=%d). I have cleaned " - "up resources I've used." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubRemoveConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Removed subscription " - "(subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - default: - BaseString::snprintf(m_text, - m_text_len, - "%sUnknown GrepSubscriptonInfo event: %d", - theNodeId, - theData[1]); - } - break; - } - - case NDB_LE_GrepSubscriptionAlert : - { - GrepEvent::Subscription event = (GrepEvent::Subscription)theData[1]; - switch(event) - { - case GrepEvent::GrepSS_CreateSubIdRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord:Error code: %d Error message: %s" - " (subId=%d,SubKey=%d)", - err, - GrepError::getErrorDesc((GrepError::GE_Code)err), - subId, - subKey); - break; - } - case GrepEvent::GrepSS_SubCreateRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: FAILED to Created subscription using" - " (subId=%d,SubKey=%d)in primary system." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubStartMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Logging failed to start on meta " - "data changes." - " using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubStartDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Logging FAILED to start on table data " - " changes using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubSyncMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Synchronization FAILED (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubSyncDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Synchronization FAILED (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d" - " Error code: %d Error Message: %s", - subId, - subKey, - gci, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubRemoveRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Failed to remove subscription " - "(subId=%d,SubKey=%d). " - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err) - ); - break; - } - - case GrepEvent::GrepPS_CreateSubIdRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Error code: %d Error Message: %s" - " (subId=%d,SubKey=%d)", - err, - GrepError::getErrorDesc((GrepError::GE_Code)err), - subId, - subKey); - break; - } - case GrepEvent::GrepPS_SubCreateRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: FAILED to Created subscription using" - " (subId=%d,SubKey=%d)in primary system." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepPS_SubStartMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Logging failed to start on meta " - "data changes." - " using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepPS_SubStartDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Logging FAILED to start on table data " - " changes using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepPS_SubSyncMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Synchronization FAILED (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepPS_SubSyncDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Synchronization FAILED (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d. " - " Error code: %d Error Message: %s", - subId, - subKey, - gci, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepPS_SubRemoveRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Failed to remove subscription " - "(subId=%d,SubKey=%d)." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::Rep_Disconnect: - { - const int err = theData[4]; - const int nodeId = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Rep: Node %d." - " Error code: %d Error Message: %s", - nodeId, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - - - default: - BaseString::snprintf(m_text, - m_text_len, - "%sUnknown GrepSubscriptionAlert event: %d", - theNodeId, - theData[1]); - break; - } - break; - } - - case NDB_LE_BackupStarted: - BaseString::snprintf(m_text, - m_text_len, - "%sBackup %d started from node %d", - theNodeId, theData[2], refToNode(theData[1])); - break; - case NDB_LE_BackupFailedToStart: - BaseString::snprintf(m_text, - m_text_len, - "%sBackup request from %d failed to start. Error: %d", - theNodeId, refToNode(theData[1]), theData[2]); - break; - case NDB_LE_BackupCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sBackup %u started from node %u completed\n" - " StartGCP: %u StopGCP: %u\n" - " #Records: %u #LogRecords: %u\n" - " Data: %u bytes Log: %u bytes", - theNodeId, theData[2], refToNode(theData[1]), - theData[3], theData[4], theData[6], theData[8], - theData[5], theData[7]); - break; - case NDB_LE_BackupAborted: - BaseString::snprintf(m_text, - m_text_len, - "%sBackup %d started from %d has been aborted. Error: %d", - theNodeId, - theData[2], - refToNode(theData[1]), - theData[3]); - break; - default: - BaseString::snprintf(m_text, - m_text_len, - "%sUnknown event: %d", - theNodeId, - theData[0]); - - } - return m_text; -} +const Uint32 EventLoggerBase::matrixSize= +sizeof(EventLoggerBase::matrix)/sizeof(EventRepLogLevelMatrix); EventLogger::EventLogger() : m_filterLevel(15) { @@ -1342,19 +763,36 @@ int EventLoggerBase::event_lookup(int eventType, LogLevel::EventCategory &cat, Uint32 &threshold, - Logger::LoggerLevel &severity) + Logger::LoggerLevel &severity, + EventTextFunction &textF) { for(unsigned i = 0; igetLogLevel(cat) : m_logLevel.getLogLevel(cat); DBUG_PRINT("info",("threshold=%d, set=%d", threshold, set)); if (ll) DBUG_PRINT("info",("m_logLevel.getLogLevel=%d", m_logLevel.getLogLevel(cat))); + if (threshold <= set){ + getText(m_text,sizeof(m_text),textF,theData,nodeId); + switch (severity){ case Logger::LL_ALERT: - alert(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + alert(m_text); break; - case Logger::LL_CRITICAL: - critical(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + critical(m_text); break; - case Logger::LL_WARNING: - warning(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + warning(m_text); break; - case Logger::LL_ERROR: - error(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + error(m_text); break; - case Logger::LL_INFO: - info(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + info(m_text); break; - case Logger::LL_DEBUG: - debug(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + debug(m_text); break; - default: - info(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + info(m_text); break; } } // if (.. diff --git a/ndb/src/common/portlib/NdbThread.c b/ndb/src/common/portlib/NdbThread.c index d4f6617d2f5..8cd6c306514 100644 --- a/ndb/src/common/portlib/NdbThread.c +++ b/ndb/src/common/portlib/NdbThread.c @@ -28,8 +28,24 @@ struct NdbThread { pthread_t thread; char thread_name[MAX_THREAD_NAME]; + NDB_THREAD_FUNC * func; + void * object; }; +static +void* +ndb_thread_wrapper(void* _ss){ + void * ret; + struct NdbThread * ss = (struct NdbThread *)_ss; +#ifdef NDB_SHM_TRANSPORTER + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + pthread_sigmask(SIG_BLOCK, &mask, 0); +#endif + ret= (* ss->func)(ss->object); + return ret; +} struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func, @@ -67,10 +83,12 @@ struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func, #ifdef PTHREAD_CREATE_JOINABLE /* needed on SCO */ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); #endif + tmpThread->func= p_thread_func; + tmpThread->object= p_thread_arg; result = pthread_create(&tmpThread->thread, &thread_attr, - p_thread_func, - p_thread_arg); + ndb_thread_wrapper, + tmpThread); assert(result==0); pthread_attr_destroy(&thread_attr); diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp index fcc7a62d9e9..215b2a05f63 100644 --- a/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/ndb/src/common/transporter/TransporterRegistry.cpp @@ -157,8 +157,17 @@ TransporterRegistry::init(NodeId nodeId) { DEBUG("TransporterRegistry started node: " << localNodeId); - // return allocateLongSignalMemoryPool(nLargeSegments); - return true; +#ifdef NDB_SHM_TRANSPORTER + /** + * Make sure to block SIGUSR1 + * TransporterRegistry::init is run from "main" thread + */ + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + pthread_sigmask(SIG_BLOCK, &mask, 0); +#endif +return true; } bool @@ -1347,6 +1356,9 @@ TransporterRegistry::startReceiving() #ifdef NDB_SHM_TRANSPORTER m_shm_own_pid = getpid(); struct sigaction sa; + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGUSR1); + pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, 0); sa.sa_handler = shm_sig_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; diff --git a/ndb/src/common/util/Bitmask.cpp b/ndb/src/common/util/Bitmask.cpp index 4169434483f..0aa39a37204 100644 --- a/ndb/src/common/util/Bitmask.cpp +++ b/ndb/src/common/util/Bitmask.cpp @@ -5,7 +5,7 @@ static void print(const Uint32 src[], Uint32 len, Uint32 pos = 0) { printf("b'"); - for(int i = 0; i> 5, src, i+pos)) printf("1"); diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp index e0171c61eca..08fa089a9c0 100644 --- a/ndb/src/kernel/blocks/backup/BackupInit.cpp +++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp @@ -22,7 +22,6 @@ //=========================================================================== #include "Backup.hpp" -#include #include #include diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index ba7a77fa4a9..9001491dd64 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -39,7 +39,6 @@ #include #include -#include #include #include @@ -198,7 +197,8 @@ void Cmvmi::execEVENT_REP(Signal* signal) Uint32 threshold; LogLevel::EventCategory eventCategory; Logger::LoggerLevel severity; - if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity)) + EventLoggerBase::EventTextFunction textF; + if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity,textF)) return; SubscriberPtr ptr; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index f4db8c8de7c..30b3e88bd82 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -4350,7 +4350,7 @@ Dbdict::execTAB_COMMITCONF(Signal* signal){ } tAttr = aRec->nextAttrInTable; } - ndbrequire(sz == 2 * tabPtr.p->noOfPrimkey); + ndbrequire((int)sz == 2 * tabPtr.p->noOfPrimkey); LinearSectionPtr lsPtr[3]; lsPtr[0].p = buf; diff --git a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp index b823dbcd952..9a5efebc56e 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp @@ -18,7 +18,6 @@ #define DBDIH_C #include "Dbdih.hpp" #include -#include #define DEBUG(x) { ndbout << "DIH::" << x << endl; } diff --git a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp index 2b62e907e7b..e39d0ca68a6 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp @@ -19,7 +19,6 @@ #define DBLQH_C #include "Dblqh.hpp" #include -#include #define DEBUG(x) { ndbout << "LQH::" << x << endl; } diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp index 5c66ba776b0..59c8237f20a 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #define DEBUG(x) { ndbout << "TC::" << x << endl; } diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index ce38c355c91..51fd50c8c46 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -1312,7 +1312,10 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) if (tapiBlockref == apiConnectptr.p->ndbapiBlockref) { if (apiConnectptr.p->apiConnectstate == CS_CONNECTED || (apiConnectptr.p->apiConnectstate == CS_ABORTING && - apiConnectptr.p->abortState == AS_IDLE)){ + apiConnectptr.p->abortState == AS_IDLE) || + (apiConnectptr.p->apiConnectstate == CS_STARTED && + apiConnectptr.p->firstTcConnect == RNIL)) + { jam(); /* JUST REPLY OK */ releaseApiCon(signal, apiConnectptr.i); signal->theData[0] = tuserpointer; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 0f0e6d61f41..0d7430e662d 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -31,7 +31,6 @@ #include #include -#include #define DEBUG(x) { ndbout << "TUP::" << x << endl; } diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index 79da3af5de4..5c12472a0f7 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -17,7 +17,6 @@ #ifndef DBTUX_H #define DBTUX_H -#include #include #include #include diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index e9c3027dfc0..f50d3a49df6 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -262,7 +262,7 @@ Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData) debugOut << endl; totalSize += 1 + dataSize; } - ndbassert(totalSize == ret); + ndbassert((int)totalSize == ret); } #endif } diff --git a/ndb/src/kernel/blocks/grep/GrepInit.cpp b/ndb/src/kernel/blocks/grep/GrepInit.cpp index 36855f86568..d764fb1f473 100644 --- a/ndb/src/kernel/blocks/grep/GrepInit.cpp +++ b/ndb/src/kernel/blocks/grep/GrepInit.cpp @@ -15,7 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Grep.hpp" -#include #include #include diff --git a/ndb/src/kernel/blocks/suma/SumaInit.cpp b/ndb/src/kernel/blocks/suma/SumaInit.cpp index 36217c313af..b5945db3811 100644 --- a/ndb/src/kernel/blocks/suma/SumaInit.cpp +++ b/ndb/src/kernel/blocks/suma/SumaInit.cpp @@ -16,7 +16,6 @@ #include "Suma.hpp" -#include #include #include diff --git a/ndb/src/kernel/vm/Emulator.cpp b/ndb/src/kernel/vm/Emulator.cpp index adf3c438945..068610b6778 100644 --- a/ndb/src/kernel/vm/Emulator.cpp +++ b/ndb/src/kernel/vm/Emulator.cpp @@ -33,7 +33,6 @@ #include #include #include -#include extern "C" { extern void (* ndb_new_handler)(); diff --git a/ndb/src/kernel/vm/SimulatedBlock.hpp b/ndb/src/kernel/vm/SimulatedBlock.hpp index cff19734368..787d14ca5cb 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -36,7 +36,6 @@ #include #include -#include #include "DLList.hpp" #include "ArrayPool.hpp" #include "DLHashTable.hpp" diff --git a/ndb/src/mgmapi/Makefile.am b/ndb/src/mgmapi/Makefile.am index 2f2fb407e46..db730bf8c89 100644 --- a/ndb/src/mgmapi/Makefile.am +++ b/ndb/src/mgmapi/Makefile.am @@ -1,7 +1,7 @@ noinst_LTLIBRARIES = libmgmapi.la -libmgmapi_la_SOURCES = mgmapi.cpp mgmapi_configuration.cpp LocalConfig.cpp +libmgmapi_la_SOURCES = mgmapi.cpp ndb_logevent.cpp mgmapi_configuration.cpp LocalConfig.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/include/mgmapi diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 9825185f88b..2872960f90a 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -22,8 +22,8 @@ #include #include -#include "mgmapi.h" -#include "mgmapi_debug.h" +#include +#include #include "mgmapi_configuration.hpp" #include @@ -314,7 +314,7 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow *command_reply, */ ndbout << "Error in mgm protocol parser. " << "cmd: '" << cmd - << "' status=" << ctx.m_status + << "' status=" << (Uint32)ctx.m_status << ", curr=" << ctx.m_currentToken << endl; DBUG_PRINT("info",("parser.parse returned NULL")); @@ -1156,9 +1156,9 @@ ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId, return 0; } -extern "C" int -ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[]) +ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[], + int structured) { SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_listen_event"); const ParserRow stat_reply[] = { @@ -1180,6 +1180,8 @@ ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[]) } Properties args; + + args.put("structured", structured); { BaseString tmp; for(int i = 0; filter[i] != 0; i += 2){ @@ -1203,6 +1205,13 @@ ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[]) return sockfd; } +extern "C" +int +ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[]) +{ + return ndb_mgm_listen_event_internal(handle,filter,0); +} + extern "C" int ndb_mgm_get_stat_port(NdbMgmHandle handle, struct ndb_mgm_reply* /*reply*/) @@ -2138,5 +2147,4 @@ ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle, DBUG_RETURN(res); } - template class Vector*>; diff --git a/ndb/src/mgmapi/mgmapi_configuration.cpp b/ndb/src/mgmapi/mgmapi_configuration.cpp index 7bac2d10b92..80ab428c05a 100644 --- a/ndb/src/mgmapi/mgmapi_configuration.cpp +++ b/ndb/src/mgmapi/mgmapi_configuration.cpp @@ -1,7 +1,6 @@ #include #include #include "mgmapi_configuration.hpp" -#include ndb_mgm_configuration_iterator::ndb_mgm_configuration_iterator (const ndb_mgm_configuration & conf, unsigned type_of_section) diff --git a/ndb/src/mgmapi/mgmapi_configuration.hpp b/ndb/src/mgmapi/mgmapi_configuration.hpp index 9e94b3311bf..7d60a4842a1 100644 --- a/ndb/src/mgmapi/mgmapi_configuration.hpp +++ b/ndb/src/mgmapi/mgmapi_configuration.hpp @@ -1,3 +1,19 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef MGMAPI_CONFIGURATION_HPP #define MGMAPI_CONFIGURATION_HPP diff --git a/ndb/src/mgmapi/ndb_logevent.cpp b/ndb/src/mgmapi/ndb_logevent.cpp new file mode 100644 index 00000000000..89ca9a50883 --- /dev/null +++ b/ndb/src/mgmapi/ndb_logevent.cpp @@ -0,0 +1,477 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "ndb_logevent.hpp" + +extern +int ndb_mgm_listen_event_internal(NdbMgmHandle, const int filter[], int); + +struct ndb_logevent_error_msg { + enum ndb_logevent_handle_error code; + const char *msg; +}; + +struct ndb_logevent_error_msg ndb_logevent_error_messages[]= { + { NDB_LEH_READ_ERROR, "Read error" }, + { NDB_LEH_MISSING_EVENT_SPECIFIER, "Missing event specifier" }, + { NDB_LEH_UNKNOWN_EVENT_VARIABLE, "Unknown event variable" }, + { NDB_LEH_UNKNOWN_EVENT_TYPE, "Unknown event type" }, + { NDB_LEH_INTERNAL_ERROR, "Unknown internal error" }, + { NDB_LEH_NO_ERROR,0} +}; + +struct ndb_logevent_handle { + NDB_SOCKET_TYPE socket; + enum ndb_logevent_handle_error m_error; +}; + +extern "C" +NdbLogEventHandle +ndb_mgm_create_logevent_handle(NdbMgmHandle mh, + const int filter[]) +{ + int fd= ndb_mgm_listen_event_internal(mh, filter, 1); + + if (fd == -1) + return 0; + + NdbLogEventHandle h= + (NdbLogEventHandle)my_malloc(sizeof(ndb_logevent_handle),MYF(MY_WME)); + + h->socket= fd; + + return h; +} + +extern "C" +void ndb_mgm_destroy_logevent_handle(NdbLogEventHandle * h) +{ + if( !h ) + return; + + if ( *h ) + close((*h)->socket); + + my_free((char*)* h,MYF(MY_ALLOW_ZERO_PTR)); + * h = 0; +} + +#define ROW(a,b,c,d) \ +{ NDB_LE_ ## a, b, c, 0, offsetof(struct ndb_logevent, a.d), \ + sizeof(((struct ndb_logevent *)0)->a.d) } + +#define ROW_FN(a,b,c,d,e) \ +{ NDB_LE_ ## a, b, c, e, offsetof(struct ndb_logevent, a.d), \ + sizeof(((struct ndb_logevent *)0)->a.d) } + +static int ref_to_node(int ref){ + return ref & 0xFFFF; +} + +struct Ndb_logevent_body_row ndb_logevent_body[]= { + + // Connection + ROW( Connected, "node", 1, node), + + ROW( Disconnected, "node", 1, node), + + ROW( CommunicationClosed, "node", 1, node), + + ROW( CommunicationOpened, "node", 1, node), + + ROW( ConnectedApiVersion, "node", 1, node), + ROW( ConnectedApiVersion, "version", 2, version), + + /* CHECKPOINT */ + + ROW( GlobalCheckpointStarted, "gci", 1, gci), + + ROW( GlobalCheckpointCompleted, "gci", 1, gci), + + ROW( LocalCheckpointStarted, "lci", 1, lci), + ROW( LocalCheckpointStarted, "keep_gci", 2, keep_gci), + ROW( LocalCheckpointStarted, "restore_gci", 3, restore_gci), + + ROW( LocalCheckpointCompleted, "lci", 1, lci), + + ROW( LCPStoppedInCalcKeepGci, "data", 1, data), + + ROW( LCPFragmentCompleted, "node", 1, node), + ROW( LCPFragmentCompleted, "table_id", 2, table_id), + ROW( LCPFragmentCompleted, "fragment_id", 3, fragment_id), + + ROW( UndoLogBlocked, "acc_count", 1, acc_count), + ROW( UndoLogBlocked, "tup_count", 2, tup_count), + + /* STARTUP */ + ROW( NDBStartStarted, "version", 1, version), + + ROW( NDBStartCompleted, "version", 1, version), + +// ROW( STTORRYRecieved), + + ROW( StartPhaseCompleted, "phase", 1, phase), + ROW( StartPhaseCompleted, "starttype", 2, starttype), + + ROW( CM_REGCONF, "own_id", 1, own_id), + ROW( CM_REGCONF, "president_id", 2, president_id), + ROW( CM_REGCONF, "dynamic_id", 3, dynamic_id), + + ROW( CM_REGREF, "own_id", 1, own_id), + ROW( CM_REGREF, "other_id", 2, other_id), + ROW( CM_REGREF, "cause", 3, cause), + + ROW( FIND_NEIGHBOURS, "own_id", 1, own_id), + ROW( FIND_NEIGHBOURS, "left_id", 3, left_id), + ROW( FIND_NEIGHBOURS, "right_id", 3, right_id), + ROW( FIND_NEIGHBOURS, "dynamic_id", 4, dynamic_id), + + ROW( NDBStopStarted, "stoptype", 1, stoptype), + +// ROW( NDBStopAborted), + + ROW( StartREDOLog, "node", 1, node), + ROW( StartREDOLog, "keep_gci", 2, keep_gci), + ROW( StartREDOLog, "completed_gci", 3, completed_gci), + ROW( StartREDOLog, "restorable_gci", 4, restorable_gci), + + ROW( StartLog, "log_part", 1, log_part), + ROW( StartLog, "start_mb", 2, start_mb), + ROW( StartLog, "stop_mb", 3, stop_mb), + ROW( StartLog, "gci", 4, gci), + + ROW( UNDORecordsExecuted, "block", 1, block), + ROW( UNDORecordsExecuted, "data1", 2, data1), + ROW( UNDORecordsExecuted, "data2", 3, data2), + ROW( UNDORecordsExecuted, "data3", 4, data3), + ROW( UNDORecordsExecuted, "data4", 5, data4), + ROW( UNDORecordsExecuted, "data5", 6, data5), + ROW( UNDORecordsExecuted, "data6", 7, data6), + ROW( UNDORecordsExecuted, "data7", 8, data7), + ROW( UNDORecordsExecuted, "data8", 9, data8), + ROW( UNDORecordsExecuted, "data9", 10, data9), + ROW( UNDORecordsExecuted, "data10", 11, data10), + + /* NODERESTART */ +// ROW( NR_CopyDict), + +// ROW( NR_CopyDistr), + + ROW( NR_CopyFragsStarted, "dest_node", 1, dest_node), + + ROW( NR_CopyFragDone, "dest_node", 1, dest_node), + ROW( NR_CopyFragDone, "table_id", 2, table_id), + ROW( NR_CopyFragDone, "fragment_id", 3, fragment_id), + + ROW( NR_CopyFragsCompleted, "dest_node", 1, dest_node), + + ROW( NodeFailCompleted, "block", 1, block), /* 0 = all */ + ROW( NodeFailCompleted, "failed_node", 2, failed_node), + ROW( NodeFailCompleted, "completing_node", 3, completing_node), /* 0 = all */ + + ROW( NODE_FAILREP, "failed_node", 1, failed_node), + ROW( NODE_FAILREP, "failure_state", 2, failure_state), + + /* TODO */ +// ROW( ArbitState), + + /* TODO */ +// ROW( ArbitResult), + +// ROW( GCP_TakeoverStarted), + +// ROW( GCP_TakeoverCompleted), + +// ROW( LCP_TakeoverStarted), + + ROW( LCP_TakeoverCompleted, "state", 1, state), + + /* STATISTIC */ + ROW( TransReportCounters, "trans_count", 1, trans_count), + ROW( TransReportCounters, "commit_count", 2, commit_count), + ROW( TransReportCounters, "read_count", 3, read_count), + ROW( TransReportCounters, "simple_read_count", 4, simple_read_count), + ROW( TransReportCounters, "write_count", 5, write_count), + ROW( TransReportCounters, "attrinfo_count", 6, attrinfo_count), + ROW( TransReportCounters, "conc_op_count", 7, conc_op_count), + ROW( TransReportCounters, "abort_count", 8, abort_count), + ROW( TransReportCounters, "scan_count", 9, scan_count), + ROW( TransReportCounters, "range_scan_count", 10, range_scan_count), + + ROW( OperationReportCounters, "ops", 1, ops), + + ROW( TableCreated, "table_id", 1, table_id), + + ROW( JobStatistic, "mean_loop_count", 1, mean_loop_count), + + ROW( SendBytesStatistic, "to_node", 1, to_node), + ROW( SendBytesStatistic, "mean_sent_bytes", 2, mean_sent_bytes), + + ROW( ReceiveBytesStatistic, "from_node", 1, from_node), + ROW( ReceiveBytesStatistic, "mean_received_bytes", 2, mean_received_bytes), + + ROW( MemoryUsage, "gth", 1, gth), + ROW( MemoryUsage, "page_size_kb", 2, page_size_kb), + ROW( MemoryUsage, "pages_used", 3, pages_used), + ROW( MemoryUsage, "pages_total", 4, pages_total), + ROW( MemoryUsage, "block", 5, block), + + /* ERROR */ + ROW( TransporterError, "to_node", 1, to_node), + ROW( TransporterError, "code", 2, code), + + ROW( TransporterWarning, "to_node", 1, to_node), + ROW( TransporterWarning, "code", 2, code), + + ROW( MissedHeartbeat, "node", 1, node), + ROW( MissedHeartbeat, "count", 2, count), + + ROW( DeadDueToHeartbeat, "node", 1, node), + + /* TODO */ +// ROW( WarningEvent), + + /* INFO */ + ROW( SentHeartbeat, "node", 1, node), + + ROW( CreateLogBytes, "node", 1, node), + + /* TODO */ +// ROW( InfoEvent), + + // Backup + ROW_FN( BackupStarted, "starting_node", 1, starting_node, ref_to_node), + ROW( BackupStarted, "backup_id", 2, backup_id), + + ROW_FN(BackupFailedToStart,"starting_node",1, starting_node, ref_to_node), + ROW( BackupFailedToStart, "error", 2, error), + + ROW_FN( BackupCompleted, "starting_node", 1, starting_node, ref_to_node), + ROW( BackupCompleted, "backup_id", 2, backup_id), + ROW( BackupCompleted, "start_gci", 3, start_gci), + ROW( BackupCompleted, "stop_gci", 4, stop_gci), + ROW( BackupCompleted, "n_bytes", 5, n_bytes), + ROW( BackupCompleted, "n_records", 6, n_records), + ROW( BackupCompleted, "n_log_bytes", 7, n_log_bytes), + ROW( BackupCompleted, "n_log_records", 8, n_log_records), + + ROW_FN( BackupAborted, "starting_node", 1, starting_node, ref_to_node), + ROW( BackupAborted, "backup_id", 2, backup_id), + ROW( BackupAborted, "error", 3, error), + + { NDB_LE_ILLEGAL_TYPE, 0, 0, 0, 0, 0} +}; + +struct Ndb_logevent_header_row { + const char *token; // token to use for text transfer + int offset; // offset into struct ndb_logevent + int size; +}; + +#define ROW2(a,b) \ +{ a, offsetof(struct ndb_logevent, b), \ + sizeof(((struct ndb_logevent *)0)->b) } + +struct Ndb_logevent_header_row ndb_logevent_header[]= { + ROW2( "type", type), + ROW2( "time", time), + ROW2( "source_nodeid", source_nodeid), + { 0, 0, 0 } +}; + +static int +insert_row(const char * pair, Properties & p){ + BaseString tmp(pair); + + tmp.trim(" \t\n\r"); + Vector split; + tmp.split(split, ":=", 2); + if(split.size() != 2) + return -1; + p.put(split[0].trim().c_str(), split[1].trim().c_str()); + + return 0; +} + +static +int memcpy_atoi(void *dst, const char *str, int sz) +{ + switch (sz) + { + case 1: + { + Int8 val= atoi(str); + memcpy(dst,&val,sz); + return 0; + } + case 2: + { + Int16 val= atoi(str); + memcpy(dst,&val,sz); + return 0; + } + case 4: + { + Int32 val= atoi(str); + memcpy(dst,&val,sz); + return 0; + } + case 8: + { + Int64 val= atoi(str); + memcpy(dst,&val,sz); + return 0; + } + default: + { + return -1; + } + } +} + +extern "C" +int ndb_logevent_get_next(const NdbLogEventHandle h, + struct ndb_logevent *dst, + unsigned timeout_in_milliseconds) +{ + SocketInputStream in(h->socket, timeout_in_milliseconds); + + Properties p; + char buf[256]; + + /* header */ + while (1) { + if (in.gets(buf,sizeof(buf)) == 0) + { + h->m_error= NDB_LEH_READ_ERROR; + return -1; + } + if ( buf[0] == 0 ) + { + // timed out + return 0; + } + if ( strcmp("log event reply\n", buf) == 0 ) + break; + ndbout_c("skipped: %s", buf); + } + + /* read name-value pairs into properties object */ + while (1) + { + if (in.gets(buf,sizeof(buf)) == 0) + { + h->m_error= NDB_LEH_READ_ERROR; + return -1; + } + if ( buf[0] == 0 ) + { + // timed out + return 0; + } + if ( buf[0] == '\n' ) + { + break; + } + if (insert_row(buf,p)) + { + h->m_error= NDB_LEH_READ_ERROR; + return -1; + } + } + + int i; + const char *val; + + dst->type= (enum Ndb_logevent_type)-1; + /* fill in header info from p*/ + for (i= 0; ndb_logevent_header[i].token; i++) + { + if ( p.get(ndb_logevent_header[i].token, &val) == 0 ) + { + ndbout_c("missing: %s\n", ndb_logevent_header[i].token); + h->m_error= NDB_LEH_MISSING_EVENT_SPECIFIER; + return -1; + } + if ( memcpy_atoi((char *)dst+ndb_logevent_header[i].offset, val, + ndb_logevent_header[i].size) ) + { + h->m_error= NDB_LEH_INTERNAL_ERROR; + return -1; + } + } + + Uint32 level; + LogLevel::EventCategory category; + Logger::LoggerLevel severity; + EventLoggerBase::EventTextFunction text_fn; + + /* fill in rest of header info event_lookup */ + if (EventLoggerBase::event_lookup(dst->type,category,level,severity,text_fn)) + { + ndbout_c("unknown type: %d\n", dst->type); + h->m_error= NDB_LEH_UNKNOWN_EVENT_TYPE; + return -1; + } + dst->category= (enum ndb_mgm_event_category)category; + dst->severity= (enum ndb_mgm_event_severity)severity; + dst->level= level; + + /* fill in header info from p */ + for (i= 0; ndb_logevent_body[i].token; i++) + { + if ( ndb_logevent_body[i].type != dst->type ) + continue; + if ( p.get(ndb_logevent_body[i].token, &val) == 0 ) + { + h->m_error= NDB_LEH_UNKNOWN_EVENT_VARIABLE; + return -1; + } + if ( memcpy_atoi((char *)dst+ndb_logevent_body[i].offset, val, + ndb_logevent_body[i].size) ) + { + h->m_error= NDB_LEH_INTERNAL_ERROR; + return -1; + } + } + return 1; +} + +extern "C" +int ndb_logevent_get_latest_error(const NdbLogEventHandle h) +{ + return h->m_error; +} + +extern "C" +const char *ndb_logevent_get_latest_error_msg(const NdbLogEventHandle h) +{ + for (int i= 0; ndb_logevent_error_messages[i].msg; i++) + if (ndb_logevent_error_messages[i].code == h->m_error) + return ndb_logevent_error_messages[i].msg; + return ""; +} diff --git a/ndb/src/mgmapi/ndb_logevent.hpp b/ndb/src/mgmapi/ndb_logevent.hpp new file mode 100644 index 00000000000..cb1a0e388e5 --- /dev/null +++ b/ndb/src/mgmapi/ndb_logevent.hpp @@ -0,0 +1,34 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef NDB_LOGEVENT_HPP +#define NDB_LOGEVENT_HPP + +#include + +struct Ndb_logevent_body_row { + enum Ndb_logevent_type type; // type + const char *token; // token to use for text transfer + int index; // index into theData array + int (*index_fn)(int); // conversion function on the data array[index] + int offset; // offset into struct ndb_logevent + int size; // offset into struct ndb_logevent +}; + +extern +struct Ndb_logevent_body_row ndb_logevent_body[]; + +#endif diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 25d7a7ad07e..6c52747e222 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -2809,7 +2809,7 @@ MgmtSrvr::setConnectionDbParameter(int node1, ConfigValues::Iterator i2(_config->m_configValues->m_config, iter.m_config); - if(i2.set(param, (unsigned)value) < 0) { + if(i2.set(param, (unsigned)value) == false) { msg.assign("Unable to set new value of parameter"); return -1; } diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index 4742d5f6426..03e99fb0770 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -49,6 +49,7 @@ class Ndb_mgmd_event_service : public EventLoggerBase public: struct Event_listener : public EventLoggerBase { NDB_SOCKET_TYPE m_socket; + Uint32 m_parsable; }; private: diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 447bc8bdc2b..9826a93020a 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -31,6 +31,7 @@ #include #include #include "Services.hpp" +#include "../mgmapi/ndb_logevent.hpp" extern bool g_StopServer; @@ -256,6 +257,7 @@ ParserRow commands[] = { MGM_CMD("listen event", &MgmApiSession::listen_event, ""), MGM_ARG("node", Int, Optional, "Node"), + MGM_ARG("parsable", Int, Optional, "Parsable"), MGM_ARG("filter", String, Mandatory, "Event category"), MGM_CMD("purge stale sessions", &MgmApiSession::purge_stale_sessions, ""), @@ -1249,25 +1251,49 @@ Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId) Uint32 threshold; LogLevel::EventCategory cat; Logger::LoggerLevel severity; + EventLoggerBase::EventTextFunction textF; int i; DBUG_ENTER("Ndb_mgmd_event_service::log"); DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId)); - if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity)) + if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF)) DBUG_VOID_RETURN; char m_text[256]; - EventLogger::getText(m_text, sizeof(m_text), eventType, theData, nodeId); + EventLogger::getText(m_text, sizeof(m_text), + textF, theData, nodeId); - Vector copy; + BaseString str("log event reply\n"); + str.appfmt("type=%d\n", eventType); + str.appfmt("time=%d\n", 0); + str.appfmt("source_nodeid=%d\n", nodeId); + for (i= 0; ndb_logevent_body[i].token; i++) + { + if ( ndb_logevent_body[i].type != eventType) + continue; + int val= theData[ndb_logevent_body[i].index]; + if (ndb_logevent_body[i].index_fn) + val= (*(ndb_logevent_body[i].index_fn))(val); + str.appfmt("%s=%d\n",ndb_logevent_body[i].token, val); + } + + Vector copy; m_clients.lock(); for(i = m_clients.size() - 1; i >= 0; i--){ if(threshold <= m_clients[i].m_logLevel.getLogLevel(cat)){ - if(m_clients[i].m_socket != NDB_INVALID_SOCKET && - println_socket(m_clients[i].m_socket, - MAX_WRITE_TIMEOUT, m_text) == -1){ - copy.push_back(m_clients[i].m_socket); - m_clients.erase(i, false); + if(m_clients[i].m_socket != NDB_INVALID_SOCKET) + { + int r; + if (m_clients[i].m_parsable) + r= println_socket(m_clients[i].m_socket, + MAX_WRITE_TIMEOUT, str.c_str()); + else + r= println_socket(m_clients[i].m_socket, + MAX_WRITE_TIMEOUT, m_text); + if (r == -1) { + copy.push_back(m_clients[i].m_socket); + m_clients.erase(i, false); + } } } } @@ -1395,15 +1421,17 @@ MgmApiSession::getConnectionParameter(Parser_t::Context &ctx, void MgmApiSession::listen_event(Parser::Context & ctx, Properties const & args) { - + Uint32 parsable= 0; BaseString node, param, value; args.get("node", node); args.get("filter", param); + args.get("parsable", &parsable); int result = 0; BaseString msg; Ndb_mgmd_event_service::Event_listener le; + le.m_parsable = parsable; le.m_socket = m_socket; Vector list; @@ -1512,4 +1540,3 @@ MgmApiSession::check_connection(Parser_t::Context &ctx, template class MutexVector; template class Vector const*>; -template class Vector; diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index ba878ac4336..e7b36d6ee02 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -47,7 +47,7 @@ NdbTransaction* Ndb::doConnect(Uint32 tConNode) { Uint32 tNode; Uint32 tAnyAlive = 0; - int TretCode; + int TretCode= 0; if (tConNode != 0) { TretCode = NDB_connect(tConNode); @@ -892,7 +892,7 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) DBUG_PRINT("enter", ("table=%u value=%llu op=%u", aTableId, opValue, op)); NdbTransaction* tConnection; - NdbOperation* tOperation; + NdbOperation* tOperation= 0; // Compiler warning if not initialized Uint64 tValue; NdbRecAttr* tRecAttrResult; int result; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 2a9f9be5a30..498c5716c73 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -631,7 +631,7 @@ NdbEventImpl::addTableEvent(const NdbDictionary::Event::TableEvent t = NdbDicti } void -NdbEventImpl::setDurability(const NdbDictionary::Event::EventDurability d) +NdbEventImpl::setDurability(NdbDictionary::Event::EventDurability d) { m_dur = d; } @@ -1370,9 +1370,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, } Uint32 topBit = (1 << 31); - for(int i = 31; i>=0; i--){ - if((fragCount & topBit) != 0) - break; + for(; topBit && !(fragCount & topBit); ){ topBit >>= 1; } impl->m_hashValueMask = topBit - 1; @@ -1593,6 +1591,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, abort(); } + int distKeys= impl.m_noOfDistributionKeys; for(i = 0; im_distributionKey && col->m_cs != NULL) { + if (distKeys && col->m_distributionKey && col->m_cs != NULL) { m_error.code= 745; DBUG_RETURN(-1); } diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 68cdce17b0d..9cd78ec721b 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -230,17 +230,17 @@ NdbScanOperation::fix_receivers(Uint32 parallel){ if(parallel > m_allocated_receivers){ const Uint32 sz = parallel * (4*sizeof(char*)+sizeof(Uint32)); - Uint32 * tmp = new Uint32[(sz+3)/4]; + Uint64 * tmp = new Uint64[(sz+7)/8]; // Save old receivers - memcpy(tmp+parallel, m_receivers, m_allocated_receivers*sizeof(char*)); + memcpy(tmp, m_receivers, m_allocated_receivers*sizeof(char*)); delete[] m_array; - m_array = tmp; + m_array = (Uint32*)tmp; - m_prepared_receivers = tmp; - m_receivers = (NdbReceiver**)(tmp + parallel); + m_receivers = (NdbReceiver**)tmp; m_api_receivers = m_receivers + parallel; m_conf_receivers = m_api_receivers + parallel; m_sent_receivers = m_conf_receivers + parallel; + m_prepared_receivers = (Uint32*)(m_sent_receivers + parallel); // Only get/init "new" receivers NdbReceiver* tScanRec; diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index b179c1fe6b9..20d98c63a67 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -473,12 +473,12 @@ void TransporterFacade::threadMainReceive(void) } TransporterFacade::TransporterFacade(NdbMgmHandle mgm_handle) : + m_mgm_handle(mgm_handle), theTransporterRegistry(0), theStopReceive(0), theSendThread(NULL), theReceiveThread(NULL), - m_fragmented_signal_id(0), - m_mgm_handle(mgm_handle) + m_fragmented_signal_id(0) { theOwnId = 0; diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index aefcb0d97d0..56c007350e6 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -497,7 +497,9 @@ int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, m_impl.m_transporter_facade->start_instance(nodeId, props); m_impl.init_nodes_vector(nodeId, *props); - for(int i=0;iget_registry()->m_transporter_interface.size();i++) + for(unsigned i=0; + iget_registry()->m_transporter_interface.size(); + i++) ndb_mgm_set_connection_int_parameter(m_impl.m_config_retriever->get_mgmHandle(), nodeId, m_impl.m_transporter_facade->get_registry() diff --git a/ndb/test/src/HugoCalculator.cpp b/ndb/test/src/HugoCalculator.cpp index aef81501ea0..2fee787bbed 100644 --- a/ndb/test/src/HugoCalculator.cpp +++ b/ndb/test/src/HugoCalculator.cpp @@ -18,6 +18,22 @@ #include #include +static +Uint32 +myRand(Uint64 * seed) +{ + const Uint64 mul= 0x5deece66dull; + const Uint64 add= 0xb; + Uint64 loc_result = *seed * mul + add; + + * seed= loc_result; + return loc_result >> 1; +} + +static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + /* ************************************************************* * HugoCalculator * @@ -72,60 +88,49 @@ HugoCalculator::Int64 calcValue(int record, int attrib, int updates) const; HugoCalculator::float calcValue(int record, int attrib, int updates) const; HugoCalculator::double calcValue(int record, int attrib, int updates) const; #endif + const char* HugoCalculator::calcValue(int record, int attrib, int updates, char* buf, int len) const { - + Uint64 seed; const NdbDictionary::Column* attr = m_tab.getColumn(attrib); Uint32 val; do { if (attrib == m_idCol) { - *((Uint32*)buf)= record; + val= record; + memcpy(buf, &val, 4); return buf; } // If this is the update column if (attrib == m_updatesCol) { - *((Uint32*)buf)= updates; + val= updates; + memcpy(buf, &val, 4); return buf; } if (attr->getPrimaryKey()) { - srand(record + attrib); - val = (record + attrib); + seed = record + attrib; } else { - srand(record + attrib + updates); - val = rand(); + seed = record + attrib + updates; } } while (0); + val = myRand(&seed); + if(attr->getNullable() && (((val >> 16) & 255) > 220)) return NULL; - - memcpy(buf, &val, (len > 4 ? 4 : len)); - int pos= 4; - while(pos + 4 < len) - { - val= rand(); - memcpy(buf+pos, &val, 4); - pos++; - } - - if(pos < len) - { - val= rand(); - memcpy(buf+pos, &val, (len - pos)); - } + int pos= 0; switch(attr->getType()){ case NdbDictionary::Column::Tinyint: case NdbDictionary::Column::Tinyunsigned: @@ -144,15 +149,24 @@ HugoCalculator::calcValue(int record, case NdbDictionary::Column::Datetime: case NdbDictionary::Column::Time: case NdbDictionary::Column::Date: - break; case NdbDictionary::Column::Bit: - { - Uint32 bits= attr->getLength(); - Uint32 tmp = bits >> 5; - Uint32 size = bits & 31; - ((Uint32*)buf)[tmp] &= ((1 << size) - 1); + while (len > 4) + { + memcpy(buf+pos, &val, 4); + pos += 4; + len -= 4; + val= myRand(&seed); + } + + memcpy(buf+pos, &val, len); + if(attr->getType() == NdbDictionary::Column::Bit) + { + Uint32 bits= attr->getLength(); + Uint32 tmp = bits >> 5; + Uint32 size = bits & 31; + ((Uint32*)buf)[tmp] &= ((1 << size) - 1); + } break; - } case NdbDictionary::Column::Varbinary: case NdbDictionary::Column::Varchar: case NdbDictionary::Column::Text: @@ -160,9 +174,21 @@ HugoCalculator::calcValue(int record, case NdbDictionary::Column::Longvarchar: case NdbDictionary::Column::Longvarbinary: { - BaseString tmp; - base64_encode(buf, len, tmp); - memcpy(buf, tmp.c_str(), len); + char* ptr= (char*)&val; + while(len >= 4) + { + len -= 4; + buf[pos++] = base64_table[ptr[0] & 0x3f]; + buf[pos++] = base64_table[ptr[1] & 0x3f]; + buf[pos++] = base64_table[ptr[2] & 0x3f]; + buf[pos++] = base64_table[ptr[3] & 0x3f]; + val= myRand(&seed); + } + + for(; len; len--, pos++) + buf[pos] = base64_table[ptr[len] & 0x3f]; + + pos--; break; } case NdbDictionary::Column::Blob: diff --git a/ndb/tools/restore/Restore.hpp b/ndb/tools/restore/Restore.hpp index e0b06c1774c..d7f6e3b7799 100644 --- a/ndb/tools/restore/Restore.hpp +++ b/ndb/tools/restore/Restore.hpp @@ -187,28 +187,33 @@ public: }; void update_max_auto_val(const char *data, int size) { - Uint64 val= 0; + union { + Uint8 u8; + Uint16 u16; + Uint32 u32; + } val; + Uint64 v; switch(size){ - case 8: - val= *(Uint8*)data; - break; - case 16: - val= *(Uint16*)data; - break; - case 24: - val= (0xffffff)&*(Uint32*)data; + case 64: + memcpy(&v,data,8); break; case 32: - val= *(Uint32*)data; + memcpy(&val.u32,data,4); + v= val.u32; break; - case 64: - val= *(Uint64*)data; + case 16: + memcpy(&val.u16,data,2); + v= val.u16; + break; + case 8: + memcpy(&val.u8,data,1); + v= val.u8; break; default: return; }; - if(val > m_max_auto_val) - m_max_auto_val= val; + if(v > m_max_auto_val) + m_max_auto_val= v; }; /** * Get attribute descriptor diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp index 4b86de36514..dfdb11524e3 100644 --- a/ndb/tools/waiter.cpp +++ b/ndb/tools/waiter.cpp @@ -31,11 +31,13 @@ waitClusterStatus(const char* _addr, ndb_mgm_node_status _status, unsigned int _timeout); enum ndb_waiter_options { - NDB_STD_OPTS_OPTIONS + NDB_STD_OPTS_OPTIONS, + OPT_WAIT_STATUS_NOT_STARTED }; NDB_STD_OPTS_VARS; static int _no_contact = 0; +static int _not_started = 0; static int _timeout = 120; static struct my_option my_long_options[] = { @@ -43,6 +45,9 @@ static struct my_option my_long_options[] = { "no-contact", 'n', "Wait for cluster no contact", (gptr*) &_no_contact, (gptr*) &_no_contact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "not-started", OPT_WAIT_STATUS_NOT_STARTED, "Wait for cluster not started", + (gptr*) &_not_started, (gptr*) &_not_started, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { "timeout", 't', "Timeout to wait", (gptr*) &_timeout, (gptr*) &_timeout, 0, GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 }, @@ -91,12 +96,22 @@ int main(int argc, char** argv){ if (_hostName == 0) _hostName= opt_connect_str; - if (_no_contact) { - if (waitClusterStatus(_hostName, NDB_MGM_NODE_STATUS_NO_CONTACT, _timeout) != 0) - return NDBT_ProgramExit(NDBT_FAILED); - } else if (waitClusterStatus(_hostName, NDB_MGM_NODE_STATUS_STARTED, _timeout) != 0) - return NDBT_ProgramExit(NDBT_FAILED); + enum ndb_mgm_node_status wait_status; + if (_no_contact) + { + wait_status= NDB_MGM_NODE_STATUS_NO_CONTACT; + } + else if (_not_started) + { + wait_status= NDB_MGM_NODE_STATUS_NOT_STARTED; + } + else + { + wait_status= NDB_MGM_NODE_STATUS_STARTED; + } + if (waitClusterStatus(_hostName, wait_status, _timeout) != 0) + return NDBT_ProgramExit(NDBT_FAILED); return NDBT_ProgramExit(NDBT_OK); } diff --git a/regex/Makefile.am b/regex/Makefile.am index 2e23efcbf2a..ee7fc5463b7 100644 --- a/regex/Makefile.am +++ b/regex/Makefile.am @@ -17,12 +17,11 @@ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include noinst_LIBRARIES = libregex.a -LDADD = libregex.a ../strings/libmystrings.a +LDADD= libregex.a $(top_builddir)/strings/libmystrings.a noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c regex.h libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c noinst_PROGRAMS = re re_SOURCES = split.c debug.c main.c -re_DEPENDENCIES= $(LIBRARIES) re_LDFLAGS= @NOINST_LDFLAGS@ EXTRA_DIST = tests CHANGES COPYRIGHT WHATSNEW regexp.c \ debug.ih engine.ih main.ih regcomp.ih regerror.ih \ diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 0851edd56ce..69f9092f1fd 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -210,8 +210,10 @@ do done $CP mysql-test/include/*.inc $BASE/mysql-test/include -$CP mysql-test/std_data/*.dat mysql-test/std_data/*.*001 $BASE/mysql-test/std_data -$CP mysql-test/std_data/des_key_file $BASE/mysql-test/std_data +$CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \ + mysql-test/std_data/*.pem mysql-test/std_data/Moscow_leap \ + mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \ + $BASE/mysql-test/std_data $CP mysql-test/t/*test mysql-test/t/*.opt mysql-test/t/*.slave-mi mysql-test/t/*.sh $BASE/mysql-test/t $CP mysql-test/r/*result mysql-test/r/*.require $BASE/mysql-test/r diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 7fd0fdef978..e1e2d4ce148 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -98,9 +98,9 @@ else if test -x "$basedir/libexec/mysqld" then execdir="$basedir/libexec" - elif test -x "@libexecdir@/mysqld" + elif test -x "$basedir/sbin/mysqld" then - execdir="@libexecdir@" + execdir="$basedir/sbin" else execdir="$basedir/bin" fi diff --git a/sql-common/client.c b/sql-common/client.c index 8259849cdbe..9dcf6b3e32c 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1424,6 +1424,7 @@ mysql_init(MYSQL *mysql) bzero((char*) (mysql),sizeof(*(mysql))); mysql->options.connect_timeout= CONNECT_TIMEOUT; mysql->last_used_con= mysql->next_slave= mysql->master = mysql; + mysql->charset=default_charset_info; strmov(mysql->net.sqlstate, not_error_sqlstate); /* By default, we are a replication pivot. The caller must reset it diff --git a/sql/field.cc b/sql/field.cc index 400ebf65273..a1dc02eba4a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1035,7 +1035,9 @@ int Field_decimal::store(longlong nr) double Field_decimal::val_real(void) { int not_used; - return my_strntod(&my_charset_bin, ptr, field_length, NULL, ¬_used); + char *end_not_used; + return my_strntod(&my_charset_bin, ptr, field_length, &end_not_used, + ¬_used); } longlong Field_decimal::val_int(void) @@ -4432,16 +4434,18 @@ int Field_string::store(longlong nr) double Field_string::val_real(void) { int not_used; - CHARSET_INFO *cs=charset(); - return my_strntod(cs,ptr,field_length,(char**)0,¬_used); + char *end_not_used; + CHARSET_INFO *cs= charset(); + return my_strntod(cs,ptr,field_length,&end_not_used,¬_used); } longlong Field_string::val_int(void) { int not_used; + char *end_not_used; CHARSET_INFO *cs=charset(); - return my_strntoll(cs,ptr,field_length,10,NULL,¬_used); + return my_strntoll(cs,ptr,field_length,10,&end_not_used,¬_used); } @@ -4740,8 +4744,9 @@ int Field_varstring::store(longlong nr) double Field_varstring::val_real(void) { int not_used; + char *end_not_used; uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); - return my_strntod(field_charset, ptr+length_bytes, length, (char**) 0, + return my_strntod(field_charset, ptr+length_bytes, length, &end_not_used, ¬_used); } @@ -4749,9 +4754,10 @@ double Field_varstring::val_real(void) longlong Field_varstring::val_int(void) { int not_used; + char *end_not_used; uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); - return my_strntoll(field_charset, ptr+length_bytes, length, 10, NULL, - ¬_used); + return my_strntoll(field_charset, ptr+length_bytes, length, 10, + &end_not_used, ¬_used); } @@ -5343,13 +5349,16 @@ int Field_blob::store(longlong nr) double Field_blob::val_real(void) { int not_used; - char *blob; + char *end_not_used, *blob; + uint32 length; + CHARSET_INFO *cs; + memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) return 0.0; - uint32 length=get_length(ptr); - CHARSET_INFO *cs=charset(); - return my_strntod(cs,blob,length,(char**)0, ¬_used); + length= get_length(ptr); + cs= charset(); + return my_strntod(cs, blob, length, &end_not_used, ¬_used); } @@ -6353,11 +6362,13 @@ longlong Field_bit::val_int(void) String *Field_bit::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { + char buff[sizeof(longlong)]; uint length= min(pack_length(), sizeof(longlong)); ulonglong bits= val_int(); + mi_int8store(buff,bits); val_buffer->alloc(length); - memcpy_fixed((char*) val_buffer->ptr(), (char*) &bits, length); + memcpy_fixed((char*) val_buffer->ptr(), buff+8-length, length); val_buffer->length(length); val_buffer->set_charset(&my_charset_bin); return val_buffer; diff --git a/sql/field.h b/sql/field.h index ab911822c2c..fd1ef09d14f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -123,6 +123,7 @@ public: } virtual bool eq_def(Field *field); virtual uint32 pack_length() const { return (uint32) field_length; } + virtual uint32 pack_length_in_rec() const { return pack_length(); } virtual void reset(void) { bzero(ptr,pack_length()); } virtual void reset_fields() {} virtual void set_default() @@ -1237,6 +1238,7 @@ public: { get_key_image(buff, length, itRAW); } uint32 pack_length() const { return (uint32) field_length + (bit_len > 0); } + uint32 pack_length_in_rec() const { return field_length; } void sql_type(String &str) const; field_cast_enum field_cast_type() { return FIELD_CAST_BIT; } char *pack(char *to, const char *from, uint max_length=~(uint) 0); @@ -1339,10 +1341,10 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions); #define FIELDFLAG_NUMBER 2 #define FIELDFLAG_ZEROFILL 4 #define FIELDFLAG_PACK 120 // Bits used for packing -#define FIELDFLAG_INTERVAL 256 -#define FIELDFLAG_BITFIELD 512 // mangled with dec! -#define FIELDFLAG_BLOB 1024 // mangled with dec! -#define FIELDFLAG_GEOM 2048 +#define FIELDFLAG_INTERVAL 256 // mangled with decimals! +#define FIELDFLAG_BITFIELD 512 // mangled with decimals! +#define FIELDFLAG_BLOB 1024 // mangled with decimals! +#define FIELDFLAG_GEOM 2048 // mangled with decimals! #define FIELDFLAG_LEFT_FULLSCREEN 8192 #define FIELDFLAG_RIGHT_FULLSCREEN 16384 @@ -1366,10 +1368,10 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions); #define f_decimals(x) ((uint8) (((x) >> FIELDFLAG_DEC_SHIFT) & FIELDFLAG_MAX_DEC)) #define f_is_alpha(x) (!f_is_num(x)) #define f_is_binary(x) ((x) & FIELDFLAG_BINARY) // 4.0- compatibility -#define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL) -#define f_is_bitfield(x) ((x) & FIELDFLAG_BITFIELD) +#define f_is_enum(x) (((x) & (FIELDFLAG_INTERVAL | FIELDFLAG_NUMBER)) == FIELDFLAG_INTERVAL) +#define f_is_bitfield(x) (((x) & (FIELDFLAG_BITFIELD | FIELDFLAG_NUMBER)) == FIELDFLAG_BITFIELD) #define f_is_blob(x) (((x) & (FIELDFLAG_BLOB | FIELDFLAG_NUMBER)) == FIELDFLAG_BLOB) -#define f_is_geom(x) ((x) & FIELDFLAG_GEOM) +#define f_is_geom(x) (((x) & (FIELDFLAG_GEOM | FIELDFLAG_NUMBER)) == FIELDFLAG_GEOM) #define f_is_equ(x) ((x) & (1+2+FIELDFLAG_PACK+31*256)) #define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT) #define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL) diff --git a/sql/field_conv.cc b/sql/field_conv.cc index b337ccd6306..07cc90283b7 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -584,6 +584,7 @@ void field_conv(Field *to,Field *from) if (to->real_type() == from->real_type()) { if (to->pack_length() == from->pack_length() && + !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && to->real_type() != FIELD_TYPE_ENUM && to->real_type() != FIELD_TYPE_SET && from->charset() == to->charset() && diff --git a/sql/filesort.cc b/sql/filesort.cc index 486215e51a1..21f75fa5ea0 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -564,10 +564,10 @@ write_keys(SORTPARAM *param, register uchar **sort_keys, uint count, if (!my_b_inited(tempfile) && open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME))) - goto err; /* purecov: inspected */ + goto err; /* purecov: inspected */ buffpek.file_pos= my_b_tell(tempfile); if ((ha_rows) count > param->max_rows) - count=(uint) param->max_rows; /* purecov: inspected */ + count=(uint) param->max_rows; /* purecov: inspected */ buffpek.count=(ha_rows) count; for (end=sort_keys+count ; sort_keys != end ; sort_keys++) if (my_b_write(tempfile, (byte*) *sort_keys, (uint) rec_length)) @@ -838,11 +838,16 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer, if (flush_io_cache(to_file)) break; /* purecov: inspected */ temp=from_file; from_file=to_file; to_file=temp; + setup_io_cache(from_file); + setup_io_cache(to_file); *maxbuffer= (uint) (lastbuff-buffpek)-1; } close_cached_file(to_file); // This holds old result if (to_file == t_file) + { *t_file=t_file2; // Copy result file + setup_io_cache(t_file); + } DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */ } /* merge_many_buff */ @@ -1170,7 +1175,12 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset) else { sortorder->length=sortorder->field->pack_length(); - if (use_strnxfrm((cs=sortorder->field->charset()))) + /* + We must test cmp_type() to ensure that ENUM and SET are sorted + as numbers + */ + if (use_strnxfrm((cs=sortorder->field->charset())) && + sortorder->field->cmp_type() == STRING_RESULT) { sortorder->need_strxnfrm= 1; *multi_byte_charset= 1; diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index abd33f2eaef..ea8633febe6 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -973,6 +973,7 @@ inline uint field_in_record_is_null ( int ha_federated::write_row(byte * buf) { int x= 0, num_fields= 0; + Field **field; ulong current_query_id= 1; ulong tmp_query_id; int all_fields_have_same_query_id= 1; @@ -1021,7 +1022,7 @@ int ha_federated::write_row(byte * buf) 0 if it remains 0, then that means no fields were specified in the query such as in the case of INSERT INTO table VALUES (val1, val2, valN) */ - for (Field **field= table->field; *field ; field++, x++) + for (field= table->field; *field ; field++, x++) { if (x > 0 && tmp_query_id != (*field)->query_id) all_fields_have_same_query_id= 0; @@ -1032,7 +1033,7 @@ int ha_federated::write_row(byte * buf) loop through the field pointer array, add any fields to both the values list and the fields list that match the current query id */ - for (Field **field= table->field; *field ; field++, x++) + for (field= table->field; *field ; field++, x++) { DBUG_PRINT("ha_federated::write_row", ("field type %d", (*field)->type())); // if there is a query id and if it's equal to the current query id diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index b5742699d7e..02d81882e7a 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -471,12 +471,24 @@ int ha_heap::create(const char *name, TABLE *table_arg, KEY_PART_INFO *key_part= pos->key_part; KEY_PART_INFO *key_part_end= key_part + pos->key_parts; - mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); - keydef[key].keysegs= (uint) pos->key_parts; keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); keydef[key].seg= seg; - keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? + + switch (pos->algorithm) { + case HA_KEY_ALG_UNDEF: + case HA_KEY_ALG_HASH: + keydef[key].algorithm= HA_KEY_ALG_HASH; + mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO) + break; + case HA_KEY_ALG_BTREE: + keydef[key].algorithm= HA_KEY_ALG_BTREE; + mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*); + break; + default: + DBUG_ASSERT(0); // cannot happen + } + keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? HA_KEY_ALG_HASH : pos->algorithm); for (; key_part != key_part_end; key_part++, seg++) @@ -525,8 +537,10 @@ int ha_heap::create(const char *name, TABLE *table_arg, hp_create_info.auto_key_type= auto_key_type; hp_create_info.auto_increment= (create_info->auto_increment_value ? create_info->auto_increment_value - 1 : 0); + hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; + max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); error= heap_create(fn_format(buff,name,"","",4+2), - keys,keydef, share->reclength, + keys, keydef, share->reclength, (ulong) ((share->max_rows < max_rows && share->max_rows) ? share->max_rows : max_rows), diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 8b44695df07..fb526888b01 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -32,7 +32,11 @@ class ha_heap: public handler public: ha_heap(TABLE *table): handler(table), file(0), records_changed(0) {} ~ha_heap() {} - const char *table_type() const { return "HEAP"; } + const char *table_type() const + { + return (table->in_use->variables.sql_mode & MODE_MYSQL323) ? + "HEAP" : "MEMORY"; + } const char *index_type(uint inx) { return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? "BTREE" : diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index d49f1c1ad46..18ab6f42d28 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2425,6 +2425,8 @@ build_template( templ->mysql_col_len = (ulint) field->pack_length(); templ->type = get_innobase_type_from_mysql_type(field); + templ->charset = dtype_get_charset_coll_noninline( + index->table->cols[i].type.prtype); templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG); if (templ->type == DATA_BLOB) { @@ -4091,6 +4093,48 @@ ha_innobase::discard_or_import_tablespace( DBUG_RETURN(err); } +/********************************************************************* +Deletes all rows of an InnoDB table. */ + +int +ha_innobase::delete_all_rows(void) +/*==============================*/ + /* out: error number */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + int error; + trx_t* trx; + THD* thd = current_thd; + + DBUG_ENTER("ha_innobase::delete_all_rows"); + + if (thd->lex->sql_command != SQLCOM_TRUNCATE) { + fallback: + /* We only handle TRUNCATE TABLE t as a special case. + DELETE FROM t will have to use ha_innobase::delete_row(). */ + DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND); + } + + /* Get the transaction associated with the current thd, or create one + if not yet created */ + + trx = check_trx_exists(thd); + + /* Truncate the table in InnoDB */ + + error = row_truncate_table_for_mysql(prebuilt->table, trx); + if (error == DB_ERROR) { + /* Cannot truncate; resort to ha_innobase::delete_row() */ + goto fallback; + } + + innobase_commit_low(trx); + + error = convert_error_code_to_mysql(error, NULL); + + DBUG_RETURN(error); +} + /********************************************************************* Drops a table from an InnoDB database. Before calling this function, MySQL calls innobase_commit to commit the transaction of the current user. diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 0cb55e02ae3..2154e238fd1 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -159,6 +159,7 @@ class ha_innobase: public handler int create(const char *name, register TABLE *form, HA_CREATE_INFO *create_info); + int delete_all_rows(); int delete_table(const char *name); int rename_table(const char* from, const char* to); int check(THD* thd, HA_CHECK_OPT* check_opt); diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 87329c6f4af..9631b78bca3 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1467,7 +1467,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, fieldpos <= minpos) { /* skip null fields */ - if (!(temp_length= (*field)->pack_length())) + if (!(temp_length= (*field)->pack_length_in_rec())) continue; /* Skip null-fields */ if (! found || fieldpos < minpos || (fieldpos == minpos && temp_length < length)) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 8a2b8c8d9ae..badb486d16b 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -767,6 +767,13 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field, DBUG_RETURN((ndb_op->setValue(fieldnr, (char*)NULL, pack_len) != 0)); DBUG_PRINT("info", ("bit field")); DBUG_DUMP("value", (char*)&bits, pack_len); +#ifdef WORDS_BIGENDIAN + if (pack_len < 5) + { + DBUG_RETURN(ndb_op->setValue(fieldnr, + ((char*)&bits)+4, pack_len) != 0); + } +#endif DBUG_RETURN(ndb_op->setValue(fieldnr, (char*)&bits, pack_len) != 0); } } @@ -859,7 +866,7 @@ int ha_ndbcluster::get_ndb_blobs_value(NdbBlob *last_ndb_blob) char *buf= m_blobs_buffer + offset; uint32 len= 0xffffffff; // Max uint32 DBUG_PRINT("value", ("read blob ptr=%x len=%u", - (uint)buf, (uint)blob_len)); + (UintPtr)buf, (uint)blob_len)); if (ndb_blob->readData(buf, len) != 0) DBUG_RETURN(-1); DBUG_ASSERT(len == blob_len); @@ -1355,6 +1362,47 @@ ha_ndbcluster::set_index_key(NdbOperation *op, DBUG_RETURN(0); } +inline +int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) +{ + uint i; + THD *thd= current_thd; + + DBUG_ENTER("define_read_attrs"); + + // Define attributes to read + for (i= 0; i < table->s->fields; i++) + { + Field *field= table->field[i]; + if ((thd->query_id == field->query_id) || + ((field->flags & PRI_KEY_FLAG)) || + m_retrieve_all_fields) + { + if (get_ndb_value(op, field, i, buf)) + ERR_RETURN(op->getNdbError()); + } + else + { + m_value[i].ptr= NULL; + } + } + + if (table->s->primary_key == MAX_KEY) + { + DBUG_PRINT("info", ("Getting hidden key")); + // Scanning table with no primary key + int hidden_no= table->s->fields; +#ifndef DBUG_OFF + const NDBTAB *tab= (const NDBTAB *) m_table; + if (!tab->getColumn(hidden_no)) + DBUG_RETURN(1); +#endif + if (get_ndb_value(op, NULL, hidden_no, NULL)) + ERR_RETURN(op->getNdbError()); + } + DBUG_RETURN(0); +} + /* Read one record from NDB using primary key */ @@ -1828,47 +1876,6 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, DBUG_RETURN(0); } -inline -int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) -{ - uint i; - THD *thd= current_thd; - - DBUG_ENTER("define_read_attrs"); - - // Define attributes to read - for (i= 0; i < table->s->fields; i++) - { - Field *field= table->field[i]; - if ((thd->query_id == field->query_id) || - ((field->flags & PRI_KEY_FLAG)) || - m_retrieve_all_fields) - { - if (get_ndb_value(op, field, i, buf)) - ERR_RETURN(op->getNdbError()); - } - else - { - m_value[i].ptr= NULL; - } - } - - if (table->s->primary_key == MAX_KEY) - { - DBUG_PRINT("info", ("Getting hidden key")); - // Scanning table with no primary key - int hidden_no= table->s->fields; -#ifndef DBUG_OFF - const NDBTAB *tab= (const NDBTAB *) m_table; - if (!tab->getColumn(hidden_no)) - DBUG_RETURN(1); -#endif - if (get_ndb_value(op, NULL, hidden_no, NULL)) - ERR_RETURN(op->getNdbError()); - } - DBUG_RETURN(0); -} - /* Start ordered index scan in NDB */ @@ -2734,13 +2741,13 @@ int ha_ndbcluster::index_read_last(byte * buf, const byte * key, uint key_len) inline int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, const key_range *end_key, - bool eq_range, bool sorted, + bool eq_r, bool sorted, byte* buf) { KEY* key_info; int error= 1; DBUG_ENTER("ha_ndbcluster::read_range_first_to_buf"); - DBUG_PRINT("info", ("eq_range: %d, sorted: %d", eq_range, sorted)); + DBUG_PRINT("info", ("eq_r: %d, sorted: %d", eq_r, sorted)); switch (get_index_type(active_index)){ case PRIMARY_KEY_ORDERED_INDEX: @@ -2781,14 +2788,14 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, int ha_ndbcluster::read_range_first(const key_range *start_key, const key_range *end_key, - bool eq_range, bool sorted) + bool eq_r, bool sorted) { byte* buf= table->record[0]; DBUG_ENTER("ha_ndbcluster::read_range_first"); DBUG_RETURN(read_range_first_to_buf(start_key, end_key, - eq_range, + eq_r, sorted, buf)); } @@ -3472,7 +3479,7 @@ int ha_ndbcluster::start_stmt(THD *thd) #if 0 NdbTransaction *tablock_trans= (NdbTransaction*)thd->transaction.all.ndb_tid; - DBUG_PRINT("info", ("tablock_trans: %x", (uint)tablock_trans)); + DBUG_PRINT("info", ("tablock_trans: %x", (UintPtr)tablock_trans)); DBUG_ASSERT(tablock_trans); // trans= ndb->hupp(tablock_trans); #endif @@ -4148,7 +4155,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): HA_AUTO_PART_KEY | HA_NO_PREFIX_CHAR_KEYS | HA_NEED_READ_RANGE_BUFFER | - HA_CAN_BIT_FIELD), + HA_CAN_BIT_FIELD), m_share(0), m_use_write(FALSE), m_ignore_dup_key(FALSE), @@ -5100,7 +5107,8 @@ ndb_get_table_statistics(Ndb* ndb, const char * table, if (check == -1) break; - Uint64 rows, commits, size, mem; + Uint64 rows, commits, mem; + Uint32 size; pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&rows); pOp->getValue(NdbDictionary::Column::COMMIT_COUNT, (char*)&commits); pOp->getValue(NdbDictionary::Column::ROW_SIZE, (char*)&size); diff --git a/sql/item.cc b/sql/item.cc index c84496f8eb7..763ab84582d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -46,7 +46,7 @@ void item_init(void) Item::Item(): name(0), orig_name(0), name_length(0), fixed(0), - collation(default_charset(), DERIVATION_COERCIBLE) + collation(&my_charset_bin, DERIVATION_COERCIBLE) { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; @@ -1290,11 +1290,12 @@ double Item_param::val_real() return (double) value.integer; case STRING_VALUE: case LONG_DATA_VALUE: - { - int dummy_err; - return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0, &dummy_err); - } + { + int dummy_err; + char *end_not_used; + return my_strntod(str_value.charset(), (char*) str_value.ptr(), + str_value.length(), &end_not_used, &dummy_err); + } case TIME_VALUE: /* This works for example when user says SELECT ?+0.0 and supplies @@ -2545,8 +2546,9 @@ Item_num *Item_uint::neg() Item_real::Item_real(const char *str_arg, uint length) { int error; - char *end; - value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end, &error); + char *end_not_used; + value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used, + &error); if (error) { /* @@ -3522,12 +3524,12 @@ void Item_cache_str::store(Item *item) double Item_cache_str::val_real() { DBUG_ASSERT(fixed == 1); - int err; + int err_not_used; + char *end_not_used; if (value) return my_strntod(value->charset(), (char*) value->ptr(), - value->length(), (char**) 0, &err); - else - return (double)0; + value->length(), &end_not_used, &err_not_used); + return (double) 0; } diff --git a/sql/item.h b/sql/item.h index d70e55b094f..c8b2d774696 100644 --- a/sql/item.h +++ b/sql/item.h @@ -888,9 +888,10 @@ public: double val_real() { DBUG_ASSERT(fixed == 1); - int err; + int err_not_used; + char *end_not_used; return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0, &err); + str_value.length(), &end_not_used, &err_not_used); } longlong val_int() { @@ -1241,10 +1242,11 @@ public: enum_field_types field_type() const { return cached_field_type; } double val_real() { - int err; + int err_not_used; + char *end_not_used; return (null_value ? 0.0 : my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(),NULL,&err)); + str_value.length(), &end_not_used, &err_not_used)); } longlong val_int() { diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e840d66c962..a8c580d45f1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1119,6 +1119,9 @@ Item_func_nullif::fix_length_and_dec() max_length=args[0]->max_length; decimals=args[0]->decimals; agg_result_type(&cached_result_type, args, 2); + if (cached_result_type == STRING_RESULT && + agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV)) + return; } } @@ -1773,64 +1776,13 @@ void Item_func_in::fix_length_and_dec() agg_cmp_type(&cmp_type, args, arg_count); + if (cmp_type == STRING_RESULT && + agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV)) + return; + for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++) const_itm&= arg[0]->const_item(); - - if (cmp_type == STRING_RESULT) - { - /* - We allow consts character set conversion for - - item IN (const1, const2, const3, ...) - - if item is in a superset for all arguments, - and if it is a stong side according to coercibility rules. - - TODO: add covnersion for non-constant IN values - via creating Item_func_conv_charset(). - */ - - if (agg_arg_collations_for_comparison(cmp_collation, args, arg_count, - MY_COLL_ALLOW_SUPERSET_CONV)) - return; - if ((!my_charset_same(args[0]->collation.collation, - cmp_collation.collation) || !const_itm)) - { - if (agg_arg_collations_for_comparison(cmp_collation, args, arg_count)) - return; - } - else - { - /* - Conversion is possible: - All IN arguments are constants. - */ - Item_arena *arena, backup; - arena= thd->change_arena_if_needed(&backup); - - for (arg= args+1, arg_end= args+arg_count; arg < arg_end; arg++) - { - if (!arg[0]->null_value && - !my_charset_same(cmp_collation.collation, - arg[0]->collation.collation)) - { - Item_string *conv; - String tmp, cstr, *ostr= arg[0]->val_str(&tmp); - uint dummy_errors; - cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), - cmp_collation.collation, &dummy_errors); - conv= new Item_string(cstr.ptr(),cstr.length(), cstr.charset(), - arg[0]->collation.derivation); - conv->str_value.copy(); - arg[0]= conv; - } - } - if (arena) - thd->restore_backup_item_arena(arena, &backup); - } - } - /* Row item with NULLs inside can return NULL or FALSE => they can't be processed as static diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index a2e244cfae2..ccc3fb2eb60 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -264,6 +264,7 @@ public: longlong val_int() { return *trig_var ? args[0]->val_int() : 1; } enum Functype functype() const { return TRIG_COND_FUNC; }; const char *func_name() const { return "trigcond"; }; + bool const_item() const { return FALSE; } }; class Item_func_not_all :public Item_func_not diff --git a/sql/item_func.h b/sql/item_func.h index 7c7c397bce0..cb6cc00c046 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -837,15 +837,19 @@ public: String *val_str(String *); double val_real() { - int err; - String *res; res=val_str(&str_value); - return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0,&err) : 0.0; + int err_not_used; + char *end_not_used; + String *res; + res= val_str(&str_value); + return res ? my_strntod(res->charset(),(char*) res->ptr(), + res->length(), &end_not_used, &err_not_used) : 0.0; } longlong val_int() { - int err; + int err_not_used; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,(char**) 0,&err) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, + (char**) 0, &err_not_used) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9e28acdd091..5d018b22055 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -58,17 +58,19 @@ uint nr_of_decimals(const char *str) return 0; } + double Item_str_func::val_real() { DBUG_ASSERT(fixed == 1); - int err; - char buff[64]; + int err_not_used; + char *end_not_used, buff[64]; String *res, tmp(buff,sizeof(buff), &my_charset_bin); res= val_str(&tmp); - return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - NULL, &err) : 0.0; + return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), + &end_not_used, &err_not_used) : 0.0; } + longlong Item_str_func::val_int() { DBUG_ASSERT(fixed == 1); @@ -275,7 +277,8 @@ String *Item_func_concat::val_str(String *str) current_thd->variables.max_allowed_packet); goto null; } - if (res->alloced_length() >= res->length()+res2->length()) + if (!args[0]->const_item() && + res->alloced_length() >= res->length()+res2->length()) { // Use old buffer res->append(*res2); } @@ -1904,6 +1907,7 @@ b1: str->append((char)(num>>8)); #endif str->append((char)num); } + str->set_charset(collation.collation); str->realloc(str->length()); // Add end 0 (for Purify) return str; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 2d4f88ed57b..d6d58adaf7c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -177,6 +177,8 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) } fix_length_and_dec(); } + else + return 1; uint8 uncacheable= engine->uncacheable(); if (uncacheable) { @@ -264,7 +266,6 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex) { DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect"); init(select_lex, new select_singlerow_subselect(this)); - max_columns= 1; maybe_null= 1; max_columns= UINT_MAX; DBUG_VOID_RETURN; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 168c68ad706..be89aa3f86d 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -591,14 +591,17 @@ void Item_sum_hybrid::clear() double Item_sum_hybrid::val_real() { DBUG_ASSERT(fixed == 1); - int err; if (null_value) return 0.0; switch (hybrid_type) { case STRING_RESULT: + { + char *end_not_used; + int err_not_used; String *res; res=val_str(&str_value); - return (res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - (char**) 0, &err) : 0.0); + return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), + &end_not_used, &err_not_used) : 0.0); + } case INT_RESULT: if (unsigned_flag) return ulonglong2double(sum_int); diff --git a/sql/item_sum.h b/sql/item_sum.h index 68899268b31..7866a9ae913 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -643,16 +643,18 @@ public: String *val_str(String *); double val_real() { - int err; + int err_not_used; + char *end_not_used; String *res; res=val_str(&str_value); return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(), - (char**) 0, &err) : 0.0; + &end_not_used, &err_not_used) : 0.0; } longlong val_int() { - int err; + int err_not_used; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, (char**) 0, &err) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, + (char**) 0, &err_not_used) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); @@ -783,9 +785,10 @@ class Item_func_group_concat : public Item_sum String *res; char *end_ptr; int error; - res= val_str(&str_value); + if (!(res= val_str(&str_value))) + return (longlong) 0; end_ptr= (char*) res->ptr()+ res->length(); - return res ? my_strtoll10(res->ptr(), &end_ptr, &error) : (longlong) 0; + return my_strtoll10(res->ptr(), &end_ptr, &error); } String* val_str(String* str); Item *copy_or_same(THD* thd); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2d0e5d7632f..0c1cd3cbad3 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2441,36 +2441,37 @@ void Item_func_add_time::print(String *str) /* + Calculate difference between two datetime values as seconds + microseconds. + SYNOPSIS calc_time_diff() - l_time1 TIME/DATE/DATETIME value - l_time2 TIME/DATE/DATETIME value - l_sign Can be 1 (operation of addition) - or -1 (substraction) - seconds_out Returns count of seconds bitween - l_time1 and l_time2 - microseconds_out Returns count of microseconds bitween - l_time1 and l_time2. + l_time1 - TIME/DATE/DATETIME value + l_time2 - TIME/DATE/DATETIME value + l_sign - 1 absolute values are substracted, + -1 absolute values are added. + seconds_out - Out parameter where difference between + l_time1 and l_time2 in seconds is stored. + microseconds_out- Out parameter where microsecond part of difference + between l_time1 and l_time2 is stored. - DESCRIPTION - Calculates difference in seconds(seconds_out) - and microseconds(microseconds_out) - bitween two TIME/DATE/DATETIME values. + NOTE + This function calculates difference between l_time1 and l_time2 absolute + values. So one should set l_sign and correct result if he want to take + signs into account (i.e. for TIME values). RETURN VALUES - Rertuns sign of difference. + Returns sign of difference. 1 means negative result 0 means positive result */ -bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign, - longlong *seconds_out, long *microseconds_out) +static bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign, + longlong *seconds_out, long *microseconds_out) { long days; bool neg; - longlong seconds= *seconds_out; - long microseconds= *microseconds_out; + longlong microseconds; /* We suppose that if first argument is MYSQL_TIMESTAMP_TIME @@ -2487,29 +2488,20 @@ bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign, (uint) l_time2->month, (uint) l_time2->day)); - microseconds= l_time1->second_part - l_sign*l_time2->second_part; - seconds= ((longlong) days*86400L + l_time1->hour*3600L + - l_time1->minute*60L + l_time1->second + microseconds/1000000L - - (longlong)l_sign*(l_time2->hour*3600L+l_time2->minute*60L+l_time2->second)); + microseconds= ((longlong)days*86400L + + l_time1->hour*3600L + l_time1->minute*60L + l_time1->second - + (longlong)l_sign*(l_time2->hour*3600L + l_time2->minute*60L + + l_time2->second))*1000000L + + l_time1->second_part - l_sign*l_time2->second_part; neg= 0; - if (seconds < 0) - { - seconds= -seconds; - neg= 1; - } - else if (seconds == 0 && microseconds < 0) + if (microseconds < 0) { microseconds= -microseconds; neg= 1; } - if (microseconds < 0) - { - microseconds+= 1000000L; - seconds--; - } - *seconds_out= seconds; - *microseconds_out= microseconds; + *seconds_out= microseconds/1000000L; + *microseconds_out= (long) (microseconds%1000000L); return neg; } @@ -2544,9 +2536,10 @@ String *Item_func_timediff::val_str(String *str) /* For MYSQL_TIMESTAMP_TIME only: If both argumets are negative values and diff between them - is negative we need to swap sign as result should be positive. + is non-zero we need to swap sign to get proper result. */ - if ((l_time2.neg == l_time1.neg) && l_time1.neg) + if ((l_time2.neg == l_time1.neg) && l_time1.neg && + (seconds || microseconds)) l_time3.neg= 1-l_time3.neg; // Swap sign of result calc_time_from_sec(&l_time3, (long) seconds, microseconds); @@ -2712,13 +2705,11 @@ longlong Item_func_timestamp_diff::val_int() case INTERVAL_SECOND: return seconds*neg; case INTERVAL_MICROSECOND: - { - longlong max_sec= LONGLONG_MAX/1000000; - if (max_sec > seconds || - max_sec == seconds && LONGLONG_MAX%1000000 >= microseconds) - return (longlong) (seconds*1000000L+microseconds)*neg; - goto null_date; - } + /* + In MySQL difference between any two valid datetime values + in microseconds fits into longlong. + */ + return (seconds*1000000L+microseconds)*neg; default: break; } diff --git a/sql/lock.cc b/sql/lock.cc index fffd48d5305..2dd12fce802 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -182,12 +182,12 @@ static int lock_external(THD *thd, TABLE **tables, uint count) if ((error=(*tables)->file->external_lock(thd,lock_type))) { + print_lock_error(error, (*tables)->file->table_type()); for (; i-- ; tables--) { (*tables)->file->external_lock(thd, F_UNLCK); (*tables)->current_lock=F_UNLCK; } - print_lock_error(error, (*tables)->file->table_type()); DBUG_RETURN(error); } else @@ -375,12 +375,13 @@ static int unlock_external(THD *thd, TABLE **table,uint count) { (*table)->current_lock = F_UNLCK; if ((error=(*table)->file->external_lock(thd, F_UNLCK))) + { error_code=error; + print_lock_error(error_code, (*table)->file->table_type()); + } } table++; } while (--count); - if (error_code) - print_lock_error(error_code, (*table)->file->table_type()); DBUG_RETURN(error_code); } diff --git a/sql/log_event.cc b/sql/log_event.cc index 2fa4e09913e..5ee034d785e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3201,7 +3201,7 @@ void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* las */ fprintf(file, ":=???;\n"); else - fprintf(file, ":=_%s %s COLLATE %s;\n", cs->csname, hex_str, cs->name); + fprintf(file, ":=_%s %s COLLATE `%s`;\n", cs->csname, hex_str, cs->name); my_afree(hex_str); } break; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6f569ea3ef4..322b38abe13 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -831,6 +831,7 @@ void wait_for_refresh(THD *thd); int open_tables(THD *thd, TABLE_LIST *tables, uint *counter); int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables); bool open_and_lock_tables(THD *thd,TABLE_LIST *tables); +bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables); int lock_tables(THD *thd, TABLE_LIST *tables, uint counter); TABLE *open_temporary_table(THD *thd, const char *path, const char *db, const char *table_name, bool link_in_list); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 94c780301e1..58bcbfd641c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -54,7 +54,7 @@ #endif #ifdef HAVE_NDBCLUSTER_DB #define OPT_NDBCLUSTER_DEFAULT 0 -#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 +#if defined(NOT_ENOUGH_TESTED) && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 #define OPT_NDB_SHM_DEFAULT 1 #else #define OPT_NDB_SHM_DEFAULT 0 @@ -2700,12 +2700,37 @@ with --log-bin instead."); mysql_bin_log.purge_logs_before_date(purge_time); } #endif - } - else if (opt_log_slave_updates) - { + if (!opt_bin_logname && !opt_binlog_index_name) + { + /* + User didn't give us info to name the binlog index file. + Picking `hostname`-bin.index like did in 4.x, causes replication to + fail if the hostname is changed later. So, we would like to instead + require a name. But as we don't want to break many existing setups, we + only give warning, not error. + */ sql_print_warning("\ -you need to use --log-bin to make --log-slave-updates work. \ -Now disabling --log-slave-updates."); +No argument was provided to --log-bin, and --log-bin-index was not used; \ +so replication may break when this MySQL server acts as a master and \ +has his hostname changed!! Please use '--log-bin=%s' to avoid \ +this problem.", + mysql_bin_log.get_name()); + } + } + else + { + if (opt_log_slave_updates) + { + sql_print_error("\ +You need to use --log-bin=# to make --log-slave-updates work."); + unireg_abort(1); + } + if (opt_binlog_index_name) + { + sql_print_error("\ +You need to use --log-bin=# to make --log-bin-index work."); + unireg_abort(1); + } } #ifdef HAVE_REPLICATION @@ -4425,9 +4450,11 @@ Disable with --skip-large-pages.", Disable with --skip-innodb (will save memory).", (gptr*) &opt_innodb, (gptr*) &opt_innodb, 0, GET_BOOL, NO_ARG, OPT_INNODB_DEFAULT, 0, 0, 0, 0, 0}, +#ifdef HAVE_INNOBASE_DB {"innodb_checksums", OPT_INNODB_CHECKSUMS, "Enable InnoDB checksums validation (enabled by default). \ Disable with --skip-innodb-checksums.", (gptr*) &innobase_use_checksums, (gptr*) &innobase_use_checksums, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, +#endif {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH, "Path to individual files and their sizes.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -4503,14 +4530,16 @@ Disable with --skip-isam.", {"log", 'l', "Log connections and queries to file.", (gptr*) &opt_logname, (gptr*) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin", OPT_BIN_LOG, - "Log update queries in binary format.", + "Log update queries in binary format. Optional (but strongly recommended " + "to avoid replication problems if server's hostname changes) argument " + "should be the chosen location for the binary log files.", (gptr*) &opt_bin_logname, (gptr*) &opt_bin_logname, 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin-index", OPT_BIN_LOG_INDEX, "File that holds the names for last binary log files.", (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"log-error", OPT_ERROR_LOG_FILE, "Log error file.", + {"log-error", OPT_ERROR_LOG_FILE, "Error log file.", (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.", diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4b0e5f036cb..e67a9881bba 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -50,6 +50,11 @@ #define test_use_count(A) {} #endif +/* + Convert double value to #rows. Currently this does floor(), and we + might consider using round() instead. +*/ +#define double2rows(x) ((ha_rows)(x)) static int sel_cmp(Field *f,char *a,char *b,uint8 a_flag,uint8 b_flag); @@ -720,7 +725,7 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, key_part_info= head->key_info[index].key_part; my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16); - /* 'thd' is not accessible in QUICK_RANGE_SELECT::get_next_init(). */ + /* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */ multi_range_bufsiz= thd->variables.read_rnd_buff_size; multi_range_count= thd->variables.multi_range_count; multi_range_length= 0; @@ -744,9 +749,6 @@ int QUICK_RANGE_SELECT::init() { DBUG_ENTER("QUICK_RANGE_SELECT::init"); - if ((error= get_next_init())) - DBUG_RETURN(error); - if (file->inited == handler::NONE) DBUG_RETURN(error= file->ha_index_init(index)); error= 0; @@ -1628,6 +1630,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu", keys_to_use.to_ulonglong(), (ulong) prev_tables, (ulong) const_tables)); + DBUG_PRINT("info", ("records=%lu", (ulong)head->file->records)); delete quick; quick=0; needed_reg.clear_all(); @@ -1874,6 +1877,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, double get_sweep_read_cost(const PARAM *param, ha_rows records) { double result; + DBUG_ENTER("get_sweep_read_cost"); if (param->table->file->primary_key_is_clustered()) { result= param->table->file->read_time(param->table->s->primary_key, @@ -1912,7 +1916,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) } } DBUG_PRINT("info",("returning cost=%g", result)); - return result; + DBUG_RETURN(result); } @@ -2393,43 +2397,27 @@ typedef struct { const PARAM *param; MY_BITMAP covered_fields; /* union of fields covered by all scans */ - - /* TRUE if covered_fields is a superset of needed_fields */ - bool is_covering; - - double index_scan_costs; /* SUM(cost of 'index-only' scans) */ - double total_cost; /* Fraction of table records that satisfies conditions of all scans. This is the number of full records that will be retrieved if a non-index_only index intersection will be employed. */ - double records_fract; + double out_rows; + /* TRUE if covered_fields is a superset of needed_fields */ + bool is_covering; + ha_rows index_records; /* sum(#records to look in indexes) */ + double index_scan_costs; /* SUM(cost of 'index-only' scans) */ + double total_cost; } ROR_INTERSECT_INFO; -/* - Re-initialize an allocated intersect info to contain zero scans. - SYNOPSIS - info Intersection info structure to re-initialize. -*/ - -static void ror_intersect_reinit(ROR_INTERSECT_INFO *info) -{ - info->is_covering= FALSE; - info->index_scan_costs= 0.0f; - info->records_fract= 1.0f; - bitmap_clear_all(&info->covered_fields); -} - /* Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans. SYNOPSIS ror_intersect_init() param Parameter from test_quick_select - is_index_only If TRUE, set ROR_INTERSECT_INFO to be covering RETURN allocated structure @@ -2437,7 +2425,7 @@ static void ror_intersect_reinit(ROR_INTERSECT_INFO *info) */ static -ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) +ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param) { ROR_INTERSECT_INFO *info; uchar* buf; @@ -2450,46 +2438,39 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) if (bitmap_init(&info->covered_fields, buf, param->fields_bitmap_size*8, FALSE)) return NULL; - ror_intersect_reinit(info); + info->is_covering= FALSE; + info->index_scan_costs= 0.0; + info->index_records= 0; + info->out_rows= param->table->file->records; + bitmap_clear_all(&info->covered_fields); return info; } - +void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) +{ + dst->param= src->param; + memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap, + src->covered_fields.bitmap_size); + dst->out_rows= src->out_rows; + dst->is_covering= src->is_covering; + dst->index_records= src->index_records; + dst->index_scan_costs= src->index_scan_costs; + dst->total_cost= src->total_cost; +} /* - Check if adding a ROR scan to a ROR-intersection reduces its cost of - ROR-intersection and if yes, update parameters of ROR-intersection, - including its cost. + Get selectivity of a ROR scan wrt ROR-intersection. SYNOPSIS - ror_intersect_add() - param Parameter from test_quick_select - info ROR-intersection structure to add the scan to. - ror_scan ROR scan info to add. - is_cpk_scan If TRUE, add the scan as CPK scan (this can be inferred - from other parameters and is passed separately only to - avoid duplicating the inference code) - + ror_scan_selectivity() + info ROR-interection + scan ROR scan + NOTES - Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR- - intersection decreases. The cost of ROR-intersection is caclulated as - follows: - - cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval - - if (union of indexes used covers all needed fields) - cost_of_full_rows_retrieval= 0; - else - { - cost_of_full_rows_retrieval= - cost_of_sweep_read(E(rows_to_retrieve), rows_in_table); - } - - E(rows_to_retrieve) is caclulated as follows: Suppose we have a condition on several keys cond=k_11=c_11 AND k_12=c_12 AND ... // parts of first key k_21=c_21 AND k_22=c_22 AND ... // parts of second key ... - k_n1=c_n1 AND k_n3=c_n3 AND ... (1) + k_n1=c_n1 AND k_n3=c_n3 AND ... (1) //parts of the key used by *scan where k_ij may be the same as any k_pq (i.e. keys may have common parts). @@ -2563,38 +2544,30 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) and reduce adjacent fractions. RETURN - TRUE ROR scan added to ROR-intersection, cost updated. - FALSE It doesn't make sense to add this ROR scan to this ROR-intersection. + Selectivity of given ROR scan. + */ -bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, - ROR_SCAN_INFO* ror_scan, bool is_cpk_scan=FALSE) +static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, + const ROR_SCAN_INFO *scan) { - int i; - SEL_ARG *sel_arg; - KEY_PART_INFO *key_part= - info->param->table->key_info[ror_scan->keynr].key_part; double selectivity_mult= 1.0; + KEY_PART_INFO *key_part= info->param->table->key_info[scan->keynr].key_part; byte key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */ - - DBUG_ENTER("ror_intersect_add"); - DBUG_PRINT("info", ("Current selectivity= %g", info->records_fract)); - DBUG_PRINT("info", ("Adding scan on %s", - info->param->table->key_info[ror_scan->keynr].name)); - SEL_ARG *tuple_arg= NULL; char *key_ptr= (char*) key_val; - bool cur_covered, prev_covered= - bitmap_is_set(&info->covered_fields, key_part->fieldnr); - - ha_rows prev_records= param->table->file->records; + SEL_ARG *sel_arg, *tuple_arg= NULL; + bool cur_covered; + bool prev_covered= bitmap_is_set(&info->covered_fields, key_part->fieldnr); key_range min_range; key_range max_range; min_range.key= (byte*) key_val; min_range.flag= HA_READ_KEY_EXACT; max_range.key= (byte*) key_val; max_range.flag= HA_READ_AFTER_KEY; - - for(i= 0, sel_arg= ror_scan->sel_arg; sel_arg; + ha_rows prev_records= info->param->table->file->records; + int i; + DBUG_ENTER("ror_intersect_selectivity"); + for(i= 0, sel_arg= scan->sel_arg; sel_arg; i++, sel_arg= sel_arg->next_key_part) { cur_covered= bitmap_is_set(&info->covered_fields, (key_part + i)->fieldnr); @@ -2604,7 +2577,7 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, { if (!tuple_arg) { - tuple_arg= ror_scan->sel_arg; + tuple_arg= scan->sel_arg; tuple_arg->store_min(key_part->length, &key_ptr, 0); } while (tuple_arg->next_key_part != sel_arg) @@ -2615,10 +2588,8 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, } ha_rows records; min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val); - records= param->table->file-> - records_in_range(ror_scan->keynr, - &min_range, - &max_range); + records= info->param->table->file-> + records_in_range(scan->keynr, &min_range, &max_range); if (cur_covered) { /* uncovered -> covered */ @@ -2637,49 +2608,105 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, } if (!prev_covered) { - double tmp= rows2double(param->table->quick_rows[ror_scan->keynr]) / + double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) / rows2double(prev_records); DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp)); selectivity_mult *= tmp; } + DBUG_PRINT("info", ("Returning multiplier: %g", selectivity_mult)); + DBUG_RETURN(selectivity_mult); +} +/* + Check if adding a ROR scan to a ROR-intersection reduces its cost of + ROR-intersection and if yes, update parameters of ROR-intersection, + including its cost. + + SYNOPSIS + ror_intersect_add() + param Parameter from test_quick_select + info ROR-intersection structure to add the scan to. + ror_scan ROR scan info to add. + is_cpk_scan If TRUE, add the scan as CPK scan (this can be inferred + from other parameters and is passed separately only to + avoid duplicating the inference code) + + NOTES + Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR- + intersection decreases. The cost of ROR-intersection is calculated as + follows: + + cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval + + When we add a scan the first increases and the second decreases. + + cost_of_full_rows_retrieval= + (union of indexes used covers all needed fields) ? + cost_of_sweep_read(E(rows_to_retrieve), rows_in_table) : + 0 + + E(rows_to_retrieve) = #rows_in_table * ror_scan_selectivity(null, scan1) * + ror_scan_selectivity({scan1}, scan2) * ... * + ror_scan_selectivity({scan1,...}, scanN). + RETURN + TRUE ROR scan added to ROR-intersection, cost updated. + FALSE It doesn't make sense to add this ROR scan to this ROR-intersection. +*/ + +static bool ror_intersect_add(ROR_INTERSECT_INFO *info, + ROR_SCAN_INFO* ror_scan, bool is_cpk_scan) +{ + double selectivity_mult= 1.0; + + DBUG_ENTER("ror_intersect_add"); + DBUG_PRINT("info", ("Current out_rows= %g", info->out_rows)); + DBUG_PRINT("info", ("Adding scan on %s", + info->param->table->key_info[ror_scan->keynr].name)); + DBUG_PRINT("info", ("is_cpk_scan=%d",is_cpk_scan)); + + selectivity_mult = ror_scan_selectivity(info, ror_scan); if (selectivity_mult == 1.0) { /* Don't add this scan if it doesn't improve selectivity. */ DBUG_PRINT("info", ("The scan doesn't improve selectivity.")); - DBUG_RETURN(FALSE); + DBUG_RETURN(false); } - - info->records_fract *= selectivity_mult; - ha_rows cur_scan_records= info->param->table->quick_rows[ror_scan->keynr]; + + info->out_rows *= selectivity_mult; + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); + if (is_cpk_scan) { - info->index_scan_costs += rows2double(cur_scan_records)* + /* + CPK scan is used to filter out rows. We apply filtering for + each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID + per check this gives us: + */ + info->index_scan_costs += rows2double(info->index_records) / TIME_FOR_COMPARE_ROWID; } else { - info->index_records += cur_scan_records; + info->index_records += info->param->table->quick_rows[ror_scan->keynr]; info->index_scan_costs += ror_scan->index_read_cost; bitmap_union(&info->covered_fields, &ror_scan->covered_fields); - } - - if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields, - &info->covered_fields)) - { - DBUG_PRINT("info", ("ROR-intersect is covering now")); - info->is_covering= TRUE; + if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields, + &info->covered_fields)) + { + DBUG_PRINT("info", ("ROR-intersect is covering now")); + info->is_covering= TRUE; + } } info->total_cost= info->index_scan_costs; + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); if (!info->is_covering) { - ha_rows table_recs= info->param->table->file->records; - info->total_cost += - get_sweep_read_cost(info->param, - (ha_rows)(info->records_fract*table_recs)); + info->total_cost += + get_sweep_read_cost(info->param, double2rows(info->out_rows)); + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); } - DBUG_PRINT("info", ("New selectivity= %g", info->records_fract)); + DBUG_PRINT("info", ("New out_rows= %g", info->out_rows)); DBUG_PRINT("info", ("New cost= %g, %scovering", info->total_cost, info->is_covering?"" : "non-")); DBUG_RETURN(TRUE); @@ -2701,9 +2728,13 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, a covering ROR-intersection) NOTES - get_key_scans_params must be called before for the same SEL_TREE before - this function can be called. + get_key_scans_params must be called before this function can be called. + + When this function is called by ROR-union construction algorithm it + assumes it is building an uncovered ROR-intersection (and thus # of full + records to be retrieved is wrong here). This is a hack. + IMPLEMENTATION The approximate best non-covering plan search algorithm is as follows: find_min_ror_intersection_scan() @@ -2717,11 +2748,11 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, min_scan= make_scan(S); while (R is not empty) { - if (!selectivity(S + first(R) < selectivity(S))) + firstR= R - first(R); + if (!selectivity(S + firstR < selectivity(S))) continue; - + S= S + first(R); - R= R - first(R); if (cost(S) < min_cost) { min_cost= cost(S); @@ -2752,15 +2783,15 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, bool *are_all_covering) { uint idx; - double min_cost= read_time; + double min_cost= DBL_MAX; DBUG_ENTER("get_best_ror_intersect"); if ((tree->n_ror_scans < 2) || !param->table->file->records) DBUG_RETURN(NULL); /* - Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of them. - Also find and save clustered PK scan if there is one. + Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of + them. Also find and save clustered PK scan if there is one. */ ROR_SCAN_INFO **cur_ror_scan; ROR_SCAN_INFO *cpk_scan= NULL; @@ -2796,8 +2827,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, tree->ror_scans_end);); /* Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized - ROR_SCAN_INFOs. - Now, get a minimal key scan using an approximate algorithm. + ROR_SCAN_INFO's. + Step 2: Get best ROR-intersection using an approximate algorithm. */ qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*), (qsort_cmp)cmp_ror_scan_info); @@ -2814,45 +2845,41 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, intersect_scans_end= intersect_scans; /* Create and incrementally update ROR intersection. */ - ROR_INTERSECT_INFO *intersect; - if (!(intersect= ror_intersect_init(param, FALSE))) + ROR_INTERSECT_INFO *intersect, *intersect_best; + if (!(intersect= ror_intersect_init(param)) || + !(intersect_best= ror_intersect_init(param))) return NULL; - /* [intersect_scans, intersect_scans_best) will hold the best combination */ + /* [intersect_scans,intersect_scans_best) will hold the best intersection */ ROR_SCAN_INFO **intersect_scans_best; - ha_rows best_rows; - bool is_best_covering; - double best_index_scan_costs; - LINT_INIT(best_rows); /* protected by intersect_scans_best */ - LINT_INIT(is_best_covering); - LINT_INIT(best_index_scan_costs); - cur_ror_scan= tree->ror_scans; - /* Start with one scan */ intersect_scans_best= intersect_scans; while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering) { - /* S= S + first(R); */ - if (ror_intersect_add(param, intersect, *cur_ror_scan)) - *(intersect_scans_end++)= *cur_ror_scan; - /* R= R - first(R); */ - cur_ror_scan++; + /* S= S + first(R); R= R - first(R); */ + if (!ror_intersect_add(intersect, *cur_ror_scan, false)) + { + cur_ror_scan++; + continue; + } + + *(intersect_scans_end++)= *(cur_ror_scan++); if (intersect->total_cost < min_cost) { /* Local minimum found, save it */ - min_cost= intersect->total_cost; - best_rows= (ha_rows)(intersect->records_fract* - rows2double(param->table->file->records)); - /* Prevent divisons by zero */ - if (!best_rows) - best_rows= 1; - is_best_covering= intersect->is_covering; + ror_intersect_cpy(intersect_best, intersect); intersect_scans_best= intersect_scans_end; - best_index_scan_costs= intersect->index_scan_costs; + min_cost = intersect->total_cost; } } + if (intersect_scans_best == intersect_scans) + { + DBUG_PRINT("info", ("None of scans increase selectivity")); + DBUG_RETURN(NULL); + } + DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "best ROR-intersection", intersect_scans, @@ -2860,48 +2887,26 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, *are_all_covering= intersect->is_covering; uint best_num= intersect_scans_best - intersect_scans; + ror_intersect_cpy(intersect, intersect_best); + /* Ok, found the best ROR-intersection of non-CPK key scans. - Check if we should add a CPK scan. - - If the obtained ROR-intersection is covering, it doesn't make sense - to add CPK scan - Clustered PK contains all fields and if we're doing - CPK scan doing other CPK scans will only add more overhead. + Check if we should add a CPK scan. If the obtained ROR-intersection is + covering, it doesn't make sense to add CPK scan. */ if (cpk_scan && !intersect->is_covering) { - /* - Handle the special case: ROR-intersect(PRIMARY, key1) is - the best, but cost(range(key1)) > cost(best_non_ror_range_scan) - */ - if (best_num == 0) - { - cur_ror_scan= tree->ror_scans; - intersect_scans_end= intersect_scans; - ror_intersect_reinit(intersect); - if (!ror_intersect_add(param, intersect, *cur_ror_scan)) - DBUG_RETURN(NULL); /* shouldn't happen actually */ - *(intersect_scans_end++)= *cur_ror_scan; - best_num++; - } - - if (ror_intersect_add(param, intersect, cpk_scan)) + if (ror_intersect_add(intersect, cpk_scan, TRUE) && + (intersect->total_cost < min_cost)) { cpk_scan_used= TRUE; - min_cost= intersect->total_cost; - best_rows= (ha_rows)(intersect->records_fract* - rows2double(param->table->file->records)); - /* Prevent divisons by zero */ - if (!best_rows) - best_rows= 1; - is_best_covering= intersect->is_covering; - best_index_scan_costs= intersect->index_scan_costs; + intersect_best= intersect; //just set pointer here } } /* Ok, return ROR-intersect plan if we have found one */ TRP_ROR_INTERSECT *trp= NULL; - if (best_num > 1 || cpk_scan_used) + if (min_cost < read_time && (cpk_scan_used || best_num > 1)) { if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT)) DBUG_RETURN(trp); @@ -2911,14 +2916,18 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, DBUG_RETURN(NULL); memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*)); trp->last_scan= trp->first_scan + best_num; - trp->is_covering= is_best_covering; - trp->read_cost= min_cost; + trp->is_covering= intersect_best->is_covering; + trp->read_cost= intersect_best->total_cost; + /* Prevent divisons by zero */ + ha_rows best_rows = double2rows(intersect_best->out_rows); + if (!best_rows) + best_rows= 1; trp->records= best_rows; - trp->index_scan_costs= best_index_scan_costs; - trp->cpk_scan= cpk_scan; - DBUG_PRINT("info", - ("Returning non-covering ROR-intersect plan: cost %g, records %lu", - trp->read_cost, (ulong) trp->records)); + trp->index_scan_costs= intersect_best->index_scan_costs; + trp->cpk_scan= cpk_scan_used? cpk_scan: NULL; + DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:" + "cost %g, records %lu", + trp->read_cost, (ulong) trp->records)); } DBUG_RETURN(trp); } @@ -3145,8 +3154,9 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, found_records) + cpu_cost; - DBUG_PRINT("info",("read_time: %g found_read_time: %g", - read_time, found_read_time)); + DBUG_PRINT("info",("key %s: found_read_time: %g (cur. read_time: %g)", + param->table->key_info[keynr].name, found_read_time, + read_time)); if (read_time > found_read_time && found_records != HA_POS_ERROR /*|| read_time == DBL_MAX*/ ) @@ -5642,9 +5652,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() We reuse the same instance of handler so we need to call both init and reset here. */ - if (cur_quick->init()) + if (cur_quick->init() || cur_quick->reset()) DBUG_RETURN(1); - cur_quick->reset(); unique= new Unique(refpos_order_cmp, (void *)head->file, head->file->ref_length, @@ -5662,10 +5671,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (cur_quick->file->inited != handler::NONE) cur_quick->file->ha_index_end(); - if (cur_quick->init()) + if (cur_quick->init() || cur_quick->reset()) DBUG_RETURN(1); - /* QUICK_RANGE_SELECT::reset never fails */ - cur_quick->reset(); } if (result) @@ -5732,9 +5739,8 @@ int QUICK_INDEX_MERGE_SELECT::get_next() if (pk_quick_select) { doing_pk_scan= TRUE; - if ((result= pk_quick_select->init())) + if ((result= pk_quick_select->init()) || (result= pk_quick_select->reset())) DBUG_RETURN(result); - pk_quick_select->reset(); DBUG_RETURN(pk_quick_select->get_next()); } } @@ -5895,28 +5901,15 @@ int QUICK_ROR_UNION_SELECT::get_next() DBUG_RETURN(error); } - -/* - Initialize data structures needed by get_next(). - - SYNOPSIS - QUICK_RANGE_SELECT::get_next_init() - - DESCRIPTION - This is called from get_next() at its first call for an object. - It allocates memory buffers and sets size variables. - - RETURN - 0 OK. - != 0 Error. -*/ - -int QUICK_RANGE_SELECT::get_next_init(void) +int QUICK_RANGE_SELECT::reset() { uint mrange_bufsiz; byte *mrange_buff; - DBUG_ENTER("QUICK_RANGE_SELECT::get_next_init"); - + DBUG_ENTER("QUICK_RANGE_SELECT::reset"); + next=0; + range= NULL; + cur_range= (QUICK_RANGE**) ranges.buffer; + /* Do not allocate the buffers twice. */ if (multi_range_length) { @@ -5924,15 +5917,8 @@ int QUICK_RANGE_SELECT::get_next_init(void) DBUG_RETURN(0); } - /* If the ranges are not yet initialized, wait for the next call. */ - if (! ranges.elements) - { - DBUG_RETURN(0); - } - - /* - Allocate the ranges array. - */ + /* Allocate the ranges array. */ + DBUG_ASSERT(ranges.elements); multi_range_length= min(multi_range_count, ranges.elements); DBUG_ASSERT(multi_range_length > 0); while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*) @@ -5949,9 +5935,7 @@ int QUICK_RANGE_SELECT::get_next_init(void) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - /* - Allocate the handler buffer if necessary. - */ + /* Allocate the handler buffer if necessary. */ if (file->table_flags() & HA_NEED_READ_RANGE_BUFFER) { mrange_bufsiz= min(multi_range_bufsiz, @@ -5979,9 +5963,6 @@ int QUICK_RANGE_SELECT::get_next_init(void) multi_range_buff->buffer_end= mrange_buff + mrange_bufsiz; multi_range_buff->end_of_used_area= mrange_buff; } - - /* Initialize the current QUICK_RANGE pointer. */ - cur_range= (QUICK_RANGE**) ranges.buffer; DBUG_RETURN(0); } @@ -7935,10 +7916,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void) file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */ result= file->ha_index_init(index); result= file->index_last(record); - if (quick_prefix_select) - quick_prefix_select->reset(); if (result) DBUG_RETURN(result); + if (quick_prefix_select && quick_prefix_select->reset()) + DBUG_RETURN(1); /* Save the prefix of the last group. */ key_copy(last_prefix, record, index_info, group_prefix_len); diff --git a/sql/opt_range.h b/sql/opt_range.h index 71981dfb5c7..97d646cedbe 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -59,6 +59,44 @@ class QUICK_RANGE :public Sql_alloc { /* Quick select interface. This class is a parent for all QUICK_*_SELECT and FT_SELECT classes. + + The usage scenario is as follows: + 1. Create quick select + quick= new QUICK_XXX_SELECT(...); + + 2. Perform lightweight initialization. This can be done in 2 ways: + 2.a: Regular initialization + if (quick->init()) + { + //the only valid action after failed init() call is delete + delete quick; + } + 2.b: Special initialization for quick selects merged by QUICK_ROR_*_SELECT + if (quick->init_ror_merged_scan()) + delete quick; + + 3. Perform zero, one, or more scans. + while (...) + { + // initialize quick select for scan. This may allocate + // buffers and/or prefetch rows. + if (quick->reset()) + { + //the only valid action after failed reset() call is delete + delete quick; + //abort query + } + + // perform the scan + do + { + res= quick->get_next(); + } while (res && ...) + } + + 4. Delete the select: + delete quick; + */ class QUICK_SELECT_I @@ -117,27 +155,16 @@ public: reset() should be called when it is certain that row retrieval will be necessary. This call may do heavyweight initialization like buffering first N records etc. If reset() call fails get_next() must not be called. - Note that reset() may be called several times if this quick select - executes in a subselect. + Note that reset() may be called several times if + * the quick select is executed in a subselect + * a JOIN buffer is used + RETURN 0 OK other Error code */ virtual int reset(void) = 0; - /* - Initialize get_next() for row retrieval. - SYNOPSIS - get_next_init() - - get_next_init() must be called before the first get_next(). - If get_next_init() call fails get_next() must not be called. - - RETURN - 0 OK - other Error code - */ - virtual int get_next_init() { return false; } virtual int get_next() = 0; /* get next record to retrieve */ /* Range end should be called when we have looped over the whole index */ @@ -284,18 +311,7 @@ public: ~QUICK_RANGE_SELECT(); int init(); - int reset(void) - { - next=0; - range= NULL; - cur_range= (QUICK_RANGE**) ranges.buffer; - /* - Note: in opt_range.cc there are places where it is assumed that this - function always succeeds - */ - return 0; - } - int get_next_init(void); + int reset(void); int get_next(); void range_end(); int get_next_prefix(uint prefix_length, byte *cur_prefix); @@ -310,6 +326,8 @@ public: #ifndef DBUG_OFF void dbug_dump(int indent, bool verbose); #endif +private: + /* Used only by QUICK_SELECT_DESC */ QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I() { bcopy(&org, this, sizeof(*this)); @@ -685,6 +703,7 @@ public: QUICK_RANGE_SELECT (thd, table, key, 1) { init(); } ~FT_SELECT() { file->ft_end(); } int init() { return error=file->ft_init(); } + int reset() { return 0; } int get_next() { return error=file->ft_read(record); } int get_type() { return QS_TYPE_FULLTEXT; } }; diff --git a/sql/procedure.h b/sql/procedure.h index 4212a9246a5..33c1288c88e 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -59,10 +59,18 @@ public: void set(double nr) { value=nr; } void set(longlong nr) { value=(double) nr; } void set(const char *str,uint length,CHARSET_INFO *cs) - { int err; value=my_strntod(cs,(char*) str,length,(char**)0,&err); } + { + int err_not_used; + char *end_not_used; + value= my_strntod(cs,(char*) str,length, &end_not_used, &err_not_used); + } double val_real() { return value; } longlong val_int() { return (longlong) value; } - String *val_str(String *s) { s->set(value,decimals,default_charset()); return s; } + String *val_str(String *s) + { + s->set(value,decimals,default_charset()); + return s; + } unsigned int size_of() { return sizeof(*this);} }; @@ -98,10 +106,11 @@ public: { str_value.copy(str,length,cs); } double val_real() { - int err; + int err_not_used; + char *end_not_used; CHARSET_INFO *cs=str_value.charset(); return my_strntod(cs, (char*) str_value.ptr(), str_value.length(), - (char**) 0, &err); + &end_not_used, &err_not_used); } longlong val_int() { diff --git a/sql/records.cc b/sql/records.cc index 9a506cadf0c..00da1ac1adc 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -100,19 +100,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, } else if (select && select->quick) { - int error; DBUG_PRINT("info",("using rr_quick")); - - if (!table->file->inited) - table->file->ha_index_init(select->quick->index); info->read_record=rr_quick; - - if ((error= select->quick->get_next_init())) - { - /* Cannot return error code here. Instead print to error log. */ - table->file->print_error(error,MYF(ME_NOREFRESH)); - thd->fatal_error(); - } } else if (table->sort.record_pointers) { diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 951bffd698d..3cdcef7c8ee 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -1,4 +1,4 @@ -languages czech=cze latin2, danish=dan latin1, dutch=nla latin1, english=eng latin1, estonian=est latin7, french=fre latin1, german=ger latin1, greek=greek greek, hungarian=hun latin2, italian=ita latin1, japanese=jpn ujis, korean=kor euckr, norwegian-ny=norwegian-ny latin1, norwegian=nor latin1, polish=pol latin2, portuguese=por latin1, romanian=rum latin2, russian=rus koi8r, serbian=serbian cp1250, slovak=slo latin2, spanish=spa latin1, swedish=swe latin1, ukrainian=ukr koi8u; +languages czech=cze latin2, danish=dan latin1, dutch=nla latin1, english=eng latin1, estonian=est latin7, french=fre latin1, german=ger latin1, greek=greek greek, hungarian=hun latin2, italian=ita latin1, japanese=jpn ujis, japanese-sjis=jps sjis, korean=kor euckr, norwegian-ny=norwegian-ny latin1, norwegian=nor latin1, polish=pol latin2, portuguese=por latin1, romanian=rum latin2, russian=rus koi8r, serbian=serbian cp1250, slovak=slo latin2, spanish=spa latin1, swedish=swe latin1, ukrainian=ukr koi8u; default-language eng @@ -79,6 +79,7 @@ ER_CANT_CREATE_TABLE dan "Kan ikke oprette tabellen '%-.64s' (Fejlkode: %d)" nla "Kan tabel '%-.64s' niet aanmaken (Errcode: %d)" eng "Can't create table '%-.64s' (errno: %d)" + jps "'%-.64s' e[u܂.(errno: %d)", est "Ei suuda luua tabelit '%-.64s' (veakood: %d)" fre "Ne peut crer la table '%-.64s' (Errcode: %d)" ger "Kann Tabelle '%-.64s' nicht erzeugen (Fehler: %d)" @@ -103,6 +104,7 @@ ER_CANT_CREATE_DB dan "Kan ikke oprette databasen '%-.64s' (Fejlkode: %d)" nla "Kan database '%-.64s' niet aanmaken (Errcode: %d)" eng "Can't create database '%-.64s' (errno: %d)" + jps "'%-.64s' f[^x[X܂ (errno: %d)", est "Ei suuda luua andmebaasi '%-.64s' (veakood: %d)" fre "Ne peut crer la base '%-.64s' (Erreur %d)" ger "Kann Datenbank '%-.64s' nicht erzeugen (Fehler: %d)" @@ -127,6 +129,7 @@ ER_DB_CREATE_EXISTS dan "Kan ikke oprette databasen '%-.64s'; databasen eksisterer" nla "Kan database '%-.64s' niet aanmaken; database bestaat reeds" eng "Can't create database '%-.64s'; database exists" + jps "'%-.64s' f[^x[X܂.ɂ̃f[^x[X݂܂", est "Ei suuda luua andmebaasi '%-.64s': andmebaas juba eksisteerib" fre "Ne peut crer la base '%-.64s'; elle existe dj" ger "Kann Datenbank '%-.64s' nicht erzeugen. Datenbank '%-.64s' existiert bereits" @@ -151,6 +154,7 @@ ER_DB_DROP_EXISTS dan "Kan ikke slette (droppe) '%-.64s'; databasen eksisterer ikke" nla "Kan database '%-.64s' niet verwijderen; database bestaat niet" eng "Can't drop database '%-.64s'; database doesn't exist" + jps "'%-.64s' f[^x[Xjł܂. ̃f[^x[XȂ̂ł.", est "Ei suuda kustutada andmebaasi '%-.64s': andmebaasi ei eksisteeri" fre "Ne peut effacer la base '%-.64s'; elle n'existe pas" ger "Kann Datenbank '%-.64s' nicht lschen. Keine Datenbank '%-.64s' vorhanden" @@ -175,6 +179,7 @@ ER_DB_DROP_DELETE dan "Fejl ved sletning (drop) af databasen (kan ikke slette '%-.64s', Fejlkode %d)" nla "Fout bij verwijderen database (kan '%-.64s' niet verwijderen, Errcode: %d)" eng "Error dropping database (can't delete '%-.64s', errno: %d)" + jps "f[^x[XjG[ ('%-.64s' 폜ł܂, errno: %d)", est "Viga andmebaasi kustutamisel (ei suuda kustutada faili '%-.64s', veakood: %d)" fre "Ne peut effacer la base '%-.64s' (erreur %d)" ger "Fehler beim Lschen der Datenbank ('%-.64s' kann nicht gelscht werden, Fehlernuumer: %d)" @@ -199,6 +204,7 @@ ER_DB_DROP_RMDIR dan "Fejl ved sletting af database (kan ikke slette folderen '%-.64s', Fejlkode %d)" nla "Fout bij verwijderen database (kan rmdir '%-.64s' niet uitvoeren, Errcode: %d)" eng "Error dropping database (can't rmdir '%-.64s', errno: %d)" + jps "f[^x[XjG[ ('%-.64s' rmdir ł܂, errno: %d)", est "Viga andmebaasi kustutamisel (ei suuda kustutada kataloogi '%-.64s', veakood: %d)" fre "Erreur en effaant la base (rmdir '%-.64s', erreur %d)" ger "Fehler beim Lschen der Datenbank (Verzeichnis '%-.64s' kann nicht gelscht werden, Fehlernummer: %d)" @@ -223,6 +229,7 @@ ER_CANT_DELETE_FILE dan "Fejl ved sletning af '%-.64s' (Fejlkode: %d)" nla "Fout bij het verwijderen van '%-.64s' (Errcode: %d)" eng "Error on delete of '%-.64s' (errno: %d)" + jps "'%-.64s' ̍폜G[ (errno: %d)", est "Viga '%-.64s' kustutamisel (veakood: %d)" fre "Erreur en effaant '%-.64s' (Errcode: %d)" ger "Fehler beim Lschen von '%-.64s' (Fehler: %d)" @@ -247,6 +254,7 @@ ER_CANT_FIND_SYSTEM_REC dan "Kan ikke lse posten i systemfolderen" nla "Kan record niet lezen in de systeem tabel" eng "Can't read record in system table" + jps "system table ̃R[hǂގł܂ł", est "Ei suuda lugeda kirjet ssteemsest tabelist" fre "Ne peut lire un enregistrement de la table 'system'" ger "Datensatz in der Systemtabelle nicht lesbar" @@ -271,6 +279,7 @@ ER_CANT_GET_STAT dan "Kan ikke lse status af '%-.64s' (Fejlkode: %d)" nla "Kan de status niet krijgen van '%-.64s' (Errcode: %d)" eng "Can't get status of '%-.64s' (errno: %d)" + jps "'%-.64s' ̃XeC^X܂. (errno: %d)", est "Ei suuda lugeda '%-.64s' olekut (veakood: %d)" fre "Ne peut obtenir le status de '%-.64s' (Errcode: %d)" ger "Kann Status von '%-.64s' nicht ermitteln (Fehler: %d)" @@ -295,6 +304,7 @@ ER_CANT_GET_WD dan "Kan ikke lse aktive folder (Fejlkode: %d)" nla "Kan de werkdirectory niet krijgen (Errcode: %d)" eng "Can't get working directory (errno: %d)" + jps "working directory 𓾂鎖ł܂ł (errno: %d)", est "Ei suuda identifitseerida jooksvat kataloogi (veakood: %d)" fre "Ne peut obtenir le rpertoire de travail (Errcode: %d)" ger "Kann Arbeitsverzeichnis nicht ermitteln (Fehler: %d)" @@ -319,6 +329,7 @@ ER_CANT_LOCK dan "Kan ikke lse fil (Fejlkode: %d)" nla "Kan de file niet blokeren (Errcode: %d)" eng "Can't lock file (errno: %d)" + jps "t@CbNł܂ (errno: %d)", est "Ei suuda lukustada faili (veakood: %d)" fre "Ne peut verrouiller le fichier (Errcode: %d)" ger "Datei kann nicht gesperrt werden (Fehler: %d)" @@ -343,6 +354,7 @@ ER_CANT_OPEN_FILE dan "Kan ikke bne fil: '%-.64s' (Fejlkode: %d)" nla "Kan de file '%-.64s' niet openen (Errcode: %d)" eng "Can't open file: '%-.64s' (errno: %d)" + jps "'%-.64s' t@CJł܂ (errno: %d)", est "Ei suuda avada faili '%-.64s' (veakood: %d)" fre "Ne peut ouvrir le fichier: '%-.64s' (Errcode: %d)" ger "Datei '%-.64s' nicht ffnen (Fehler: %d)" @@ -367,6 +379,7 @@ ER_FILE_NOT_FOUND dan "Kan ikke finde fila: '%-.64s' (Fejlkode: %d)" nla "Kan de file: '%-.64s' niet vinden (Errcode: %d)" eng "Can't find file: '%-.64s' (errno: %d)" + jps "'%-.64s' t@Ct鎖ł܂.(errno: %d)", est "Ei suuda leida faili '%-.64s' (veakood: %d)" fre "Ne peut trouver le fichier: '%-.64s' (Errcode: %d)" ger "Kann Datei '%-.64s' nicht finden (Fehler: %d)" @@ -391,6 +404,7 @@ ER_CANT_READ_DIR dan "Kan ikke lse folder '%-.64s' (Fejlkode: %d)" nla "Kan de directory niet lezen van '%-.64s' (Errcode: %d)" eng "Can't read dir of '%-.64s' (errno: %d)" + jps "'%-.64s' fBNgǂ߂܂.(errno: %d)", est "Ei suuda lugeda kataloogi '%-.64s' (veakood: %d)" fre "Ne peut lire le rpertoire de '%-.64s' (Errcode: %d)" ger "Verzeichnis von '%-.64s' nicht lesbar (Fehler: %d)" @@ -415,6 +429,7 @@ ER_CANT_SET_WD dan "Kan ikke skifte folder til '%-.64s' (Fejlkode: %d)" nla "Kan de directory niet veranderen naar '%-.64s' (Errcode: %d)" eng "Can't change dir to '%-.64s' (errno: %d)" + jps "'%-.64s' fBNg chdir ł܂.(errno: %d)", est "Ei suuda siseneda kataloogi '%-.64s' (veakood: %d)" fre "Ne peut changer le rpertoire pour '%-.64s' (Errcode: %d)" ger "Kann nicht in das Verzeichnis '%-.64s' wechseln (Fehler: %d)" @@ -462,6 +477,7 @@ ER_DISK_FULL dan "Ikke mere diskplads (%s). Venter p at f frigjort plads..." nla "Schijf vol (%s). Aan het wachten totdat er ruimte vrij wordt gemaakt..." eng "Disk full (%s); waiting for someone to free some space..." + jps "Disk full (%s). N炷܂ł܂Ă...", est "Ketas tis (%s). Ootame kuni tekib vaba ruumi..." fre "Disque plein (%s). J'attend que quelqu'un libre de l'espace..." ger "Festplatte voll (%-.64s). Warte, bis jemand Platz schafft ..." @@ -486,6 +502,7 @@ ER_DUP_KEY 23000 dan "Kan ikke skrive, flere ens ngler i tabellen '%-.64s'" nla "Kan niet schrijven, dubbele zoeksleutel in tabel '%-.64s'" eng "Can't write; duplicate key in table '%-.64s'" + jps "table '%-.64s' key dĂď߂܂", est "Ei saa kirjutada, korduv vti tabelis '%-.64s'" fre "Ecriture impossible, doublon dans une cl de la table '%-.64s'" ger "Kann nicht speichern, Grund: doppelter Schlssel in Tabelle '%-.64s'" @@ -533,6 +550,7 @@ ER_ERROR_ON_READ dan "Fejl ved lsning af '%-.64s' (Fejlkode: %d)" nla "Fout bij het lezen van file '%-.64s' (Errcode: %d)" eng "Error reading file '%-.64s' (errno: %d)" + jps "'%-.64s' t@C̓ǂݍ݃G[ (errno: %d)", est "Viga faili '%-.64s' lugemisel (veakood: %d)" fre "Erreur en lecture du fichier '%-.64s' (Errcode: %d)" ger "Fehler beim Lesen der Datei '%-.64s' (Fehler: %d)" @@ -557,6 +575,7 @@ ER_ERROR_ON_RENAME dan "Fejl ved omdbning af '%-.64s' til '%-.64s' (Fejlkode: %d)" nla "Fout bij het hernoemen van '%-.64s' naar '%-.64s' (Errcode: %d)" eng "Error on rename of '%-.64s' to '%-.64s' (errno: %d)" + jps "'%-.64s' '%-.64s' rename ł܂ (errno: %d)", est "Viga faili '%-.64s' mbernimetamisel '%-.64s'-ks (veakood: %d)" fre "Erreur en renommant '%-.64s' en '%-.64s' (Errcode: %d)" ger "Fehler beim Umbenennen von '%-.64s' in '%-.64s' (Fehler: %d)" @@ -581,6 +600,7 @@ ER_ERROR_ON_WRITE dan "Fejl ved skriving av filen '%-.64s' (Fejlkode: %d)" nla "Fout bij het wegschrijven van file '%-.64s' (Errcode: %d)" eng "Error writing file '%-.64s' (errno: %d)" + jps "'%-.64s' t@Cł܂ (errno: %d)", est "Viga faili '%-.64s' kirjutamisel (veakood: %d)" fre "Erreur d'criture du fichier '%-.64s' (Errcode: %d)" ger "Fehler beim Speichern der Datei '%-.64s' (Fehler: %d)" @@ -605,6 +625,7 @@ ER_FILE_USED dan "'%-.64s' er lst mod opdateringer" nla "'%-.64s' is geblokeerd tegen veranderingen" eng "'%-.64s' is locked against change" + jps "'%-.64s' ̓bNĂ܂", est "'%-.64s' on lukustatud muudatuste vastu" fre "'%-.64s' est verrouill contre les modifications" ger "'%-.64s' ist fr nderungen gesperrt" @@ -629,6 +650,7 @@ ER_FILSORT_ABORT dan "Sortering afbrudt" nla "Sorteren afgebroken" eng "Sort aborted" + jps "Sort f", est "Sorteerimine katkestatud" fre "Tri alphabtique abandonn" ger "Sortiervorgang abgebrochen" @@ -653,6 +675,7 @@ ER_FORM_NOT_FOUND dan "View '%-.64s' eksisterer ikke for '%-.64s'" nla "View '%-.64s' bestaat niet voor '%-.64s'" eng "View '%-.64s' doesn't exist for '%-.64s'" + jps "View '%-.64s' '%-.64s' ɒ`Ă܂", est "Vaade '%-.64s' ei eksisteeri '%-.64s' jaoks" fre "La vue (View) '%-.64s' n'existe pas pour '%-.64s'" ger "View '%-.64s' existiert fr '%-.64s' nicht" @@ -725,6 +748,7 @@ ER_KEY_NOT_FOUND dan "Kan ikke finde posten i '%-.64s'" nla "Kan record niet vinden in '%-.64s'" eng "Can't find record in '%-.64s'" + jps "'%-.64s'̂ȂɃR[ht܂", est "Ei suuda leida kirjet '%-.64s'-s" fre "Ne peut trouver l'enregistrement dans '%-.64s'" ger "Kann Datensatz nicht finden" @@ -749,6 +773,7 @@ ER_NOT_FORM_FILE dan "Forkert indhold i: '%-.64s'" nla "Verkeerde info in file: '%-.64s'" eng "Incorrect information in file: '%-.64s'" + jps "t@C '%-.64s' info ԈĂ悤ł", est "Vigane informatsioon failis '%-.64s'" fre "Information erronne dans le fichier: '%-.64s'" ger "Falsche Information in Datei '%-.64s'" @@ -773,6 +798,7 @@ ER_NOT_KEYFILE dan "Fejl i indeksfilen til tabellen '%-.64s'; prv at reparere den" nla "Verkeerde zoeksleutel file voor tabel: '%-.64s'; probeer het te repareren" eng "Incorrect key file for table '%-.64s'; try to repair it" + jps "'%-.64s' e[u key file ԈĂ悤ł. CĂ", est "Tabeli '%-.64s' vtmefail on vigane; proovi seda parandada" fre "Index corrompu dans la table: '%-.64s'; essayez de le rparer" ger "Falsche Schlssel-Datei fr Tabelle '%-.64s'. versuche zu reparieren" @@ -797,6 +823,7 @@ ER_OLD_KEYFILE dan "Gammel indeksfil for tabellen '%-.64s'; reparer den" nla "Oude zoeksleutel file voor tabel '%-.64s'; repareer het!" eng "Old key file for table '%-.64s'; repair it!" + jps "'%-.64s' e[u͌Â` key file ̂悤ł; CĂ", est "Tabeli '%-.64s' vtmefail on aegunud; paranda see!" fre "Vieux fichier d'index pour la table '%-.64s'; rparez le!" ger "Alte Schlssel-Datei fr Tabelle '%-.64s'. Bitte reparieren" @@ -821,6 +848,7 @@ ER_OPEN_AS_READONLY dan "'%-.64s' er skrivebeskyttet" nla "'%-.64s' is alleen leesbaar" eng "Table '%-.64s' is read only" + jps "'%-.64s' ͓ǂݍݐpł", est "Tabel '%-.64s' on ainult lugemiseks" fre "'%-.64s' est en lecture seulement" ger "'%-.64s' ist nur lesbar" @@ -845,6 +873,7 @@ ER_OUTOFMEMORY HY001 S1001 dan "Ikke mere hukommelse. Genstart serveren og prv igen (mangler %d bytes)" nla "Geen geheugen meer. Herstart server en probeer opnieuw (%d bytes nodig)" eng "Out of memory; restart server and try again (needed %d bytes)" + jps "Out of memory. f[X^[gĂ݂Ă (%d bytes Kv)", est "Mlu sai otsa. Proovi MySQL uuesti kivitada (puudu ji %d baiti)" fre "Manque de mmoire. Redmarrez le dmon et r-essayez (%d octets ncessaires)" ger "Kein Speicher vorhanden (%d Bytes bentigt). Bitte Server neu starten" @@ -869,6 +898,7 @@ ER_OUT_OF_SORTMEMORY HY001 S1001 dan "Ikke mere sorteringshukommelse. g sorteringshukommelse (sort buffer size) for serveren" nla "Geen geheugen om te sorteren. Verhoog de server sort buffer size" eng "Out of sort memory; increase server sort buffer size" + jps "Out of sort memory. sort buffer size Ȃ悤ł.", est "Mlu sai sorteerimisel otsa. Suurenda MySQL-i sorteerimispuhvrit" fre "Manque de mmoire pour le tri. Augmentez-la." ger "Kein Speicher zum Sortieren vorhanden. sort_buffer_size sollte erhht werden" @@ -893,6 +923,7 @@ ER_UNEXPECTED_EOF dan "Uventet afslutning p fil (eof) ved lsning af filen '%-.64s' (Fejlkode: %d)" nla "Onverwachte eof gevonden tijdens het lezen van file '%-.64s' (Errcode: %d)" eng "Unexpected EOF found when reading file '%-.64s' (errno: %d)" + jps "'%-.64s' t@Cǂݍݒ EOF \ʏŌ܂. (errno: %d)", est "Ootamatu faililpumrgend faili '%-.64s' lugemisel (veakood: %d)" fre "Fin de fichier inattendue en lisant '%-.64s' (Errcode: %d)" ger "Unerwartetes Ende beim Lesen der Datei '%-.64s' (Fehler: %d)" @@ -917,6 +948,7 @@ ER_CON_COUNT_ERROR 08004 dan "For mange forbindelser (connections)" nla "Te veel verbindingen" eng "Too many connections" + jps "ڑ܂", est "Liiga palju samaaegseid hendusi" fre "Trop de connections" ger "Zu viele Verbindungen" @@ -941,6 +973,7 @@ ER_OUT_OF_RESOURCES dan "Udget for trde/hukommelse" nla "Geen thread geheugen meer; controleer of mysqld of andere processen al het beschikbare geheugen gebruikt. Zo niet, dan moet u wellicht 'ulimit' gebruiken om mysqld toe te laten meer geheugen te benutten, of u kunt extra swap ruimte toevoegen" eng "Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space" + jps "Out of memory; mysqld ̑̃vZX[SĎgĂ邩mFĂ. [g؂ĂȂꍇA'ulimit' ݒ肵 mysqld ̃[gpEʂ𑽂邩Aswap space 𑝂₵Ă݂Ă", est "Mlu sai otsa. Vimalik, et aitab swap-i lisamine vi ksu 'ulimit' abil MySQL-le rohkema mlu kasutamise lubamine" fre "Manque de 'threads'/mmoire" ger "Kein Speicher mehr vorhanden. Prfen Sie, ob mysqld oder ein anderer Prozess allen Speicher verbraucht. Wenn nicht, sollten Sie mit 'ulimit' dafr sorgen, dass mysqld mehr Speicher benutzen darf, oder mehr Swap-Speicher einrichten" @@ -965,6 +998,7 @@ ER_BAD_HOST_ERROR 08S01 dan "Kan ikke f vrtsnavn for din adresse" nla "Kan de hostname niet krijgen van uw adres" eng "Can't get hostname for your address" + jps " address hostname ܂.", est "Ei suuda lahendada IP aadressi masina nimeks" fre "Ne peut obtenir de hostname pour votre adresse" ger "Kann Hostnamen fr diese Adresse nicht erhalten" @@ -1011,6 +1045,7 @@ ER_DBACCESS_DENIED_ERROR 42000 dan "Adgang ngtet bruger: '%-.32s'@'%-.64s' til databasen '%-.64s'" nla "Toegang geweigerd voor gebruiker: '%-.32s'@'%-.64s' naar database '%-.64s'" eng "Access denied for user '%-.32s'@'%-.64s' to database '%-.64s'" + jps "[U[ '%-.32s'@'%-.64s' '%-.64s' f[^x[Xւ̃ANZXۂ܂", est "Ligips keelatud kasutajale '%-.32s'@'%-.64s' andmebaasile '%-.64s'" fre "Accs refus pour l'utilisateur: '%-.32s'@'@%-.64s'. Base '%-.64s'" ger "Benutzer '%-.32s'@'%-.64s' hat keine Zugriffsberechtigung fr Datenbank '%-.64s'" @@ -1034,6 +1069,7 @@ ER_ACCESS_DENIED_ERROR 28000 dan "Adgang ngtet bruger: '%-.32s'@'%-.64s' (Bruger adgangskode: %s)" nla "Toegang geweigerd voor gebruiker: '%-.32s'@'%-.64s' (Wachtwoord gebruikt: %s)" eng "Access denied for user '%-.32s'@'%-.64s' (using password: %s)" + jps "[U[ '%-.32s'@'%-.64s' ۂ܂.uUsing password: %s)", est "Ligips keelatud kasutajale '%-.32s'@'%-.64s' (kasutab parooli: %s)" fre "Accs refus pour l'utilisateur: '%-.32s'@'@%-.64s' (mot de passe: %s)" ger "Benutzer '%-.32s'@'%-.64s' hat keine Zugriffsberechtigung (verwendetes Passwort: %-.64s)" @@ -1057,6 +1093,7 @@ ER_NO_DB_ERROR 3D000 dan "Ingen database valgt" nla "Geen database geselecteerd" eng "No database selected" + jps "f[^x[XIĂ܂.", est "Andmebaasi ei ole valitud" fre "Aucune base n'a t slectionne" ger "Keine Datenbank ausgewhlt" @@ -1081,6 +1118,7 @@ ER_UNKNOWN_COM_ERROR 08S01 dan "Ukendt kommando" nla "Onbekend commando" eng "Unknown command" + jps "̃R}h͉H", est "Tundmatu ksk" fre "Commande inconnue" ger "Unbekannter Befehl" @@ -1105,6 +1143,7 @@ ER_BAD_NULL_ERROR 23000 dan "Kolonne '%-.64s' kan ikke vre NULL" nla "Kolom '%-.64s' kan niet null zijn" eng "Column '%-.64s' cannot be null" + jps "Column '%-.64s' null ɂ͂łȂ̂ł", est "Tulp '%-.64s' ei saa omada nullvrtust" fre "Le champ '%-.64s' ne peut tre vide (null)" ger "Feld '%-.64s' darf nicht NULL sein" @@ -1129,6 +1168,7 @@ ER_BAD_DB_ERROR 42000 dan "Ukendt database '%-.64s'" nla "Onbekende database '%-.64s'" eng "Unknown database '%-.64s'" + jps "'%-.64s' Ȃăf[^x[X͒m܂.", est "Tundmatu andmebaas '%-.64s'" fre "Base '%-.64s' inconnue" ger "Unbekannte Datenbank '%-.64s'" @@ -1153,6 +1193,7 @@ ER_TABLE_EXISTS_ERROR 42S01 dan "Tabellen '%-.64s' findes allerede" nla "Tabel '%-.64s' bestaat al" eng "Table '%-.64s' already exists" + jps "Table '%-.64s' ͊ɂ܂", est "Tabel '%-.64s' juba eksisteerib" fre "La table '%-.64s' existe dj" ger "Tabelle '%-.64s' bereits vorhanden" @@ -1177,6 +1218,7 @@ ER_BAD_TABLE_ERROR 42S02 dan "Ukendt tabel '%-.64s'" nla "Onbekende tabel '%-.64s'" eng "Unknown table '%-.64s'" + jps "table '%-.64s' ͂܂.", est "Tundmatu tabel '%-.64s'" fre "Table '%-.64s' inconnue" ger "Unbekannte Tabelle '%-.64s'" @@ -1225,6 +1267,7 @@ ER_SERVER_SHUTDOWN 08S01 dan "Database nedlukning er i gang" nla "Bezig met het stoppen van de server" eng "Server shutdown in progress" + jps "Server shutdown ...", est "Serveri seiskamine kib" fre "Arrt du serveur en cours" ger "Der Server wird heruntergefahren" @@ -1249,6 +1292,7 @@ ER_BAD_FIELD_ERROR 42S22 S0022 dan "Ukendt kolonne '%-.64s' i tabel %s" nla "Onbekende kolom '%-.64s' in %s" eng "Unknown column '%-.64s' in '%-.64s'" + jps "'%-.64s' column '%-.64s' ɂ͂܂.", est "Tundmatu tulp '%-.64s' '%-.64s'-s" fre "Champ '%-.64s' inconnu dans %s" ger "Unbekanntes Tabellenfeld '%-.64s' in %-.64s" @@ -1273,6 +1317,7 @@ ER_WRONG_FIELD_WITH_GROUP 42000 S1009 dan "Brugte '%-.64s' som ikke var i group by" nla "Opdracht gebruikt '%-.64s' dat niet in de GROUP BY voorkomt" eng "'%-.64s' isn't in GROUP BY" + jps "'%-.64s' isn't in GROUP BY", est "'%-.64s' puudub GROUP BY klauslis" fre "'%-.64s' n'est pas dans 'group by'" ger "'%-.64s' ist nicht in GROUP BY vorhanden" @@ -1363,6 +1408,7 @@ ER_TOO_LONG_IDENT 42000 S1009 dan "Navnet '%-.64s' er for langt" nla "Naam voor herkenning '%-.64s' is te lang" eng "Identifier name '%-.100s' is too long" + jps "Identifier name '%-.100s' ͒܂", est "Identifikaatori '%-.100s' nimi on liiga pikk" fre "Le nom de l'identificateur '%-.64s' est trop long" ger "Name des Bezeichners '%-.64s' ist zu lang" @@ -1387,6 +1433,7 @@ ER_DUP_FIELDNAME 42S21 S1009 dan "Feltnavnet '%-.64s' findes allerede" nla "Dubbele kolom naam '%-.64s'" eng "Duplicate column name '%-.64s'" + jps "'%-.64s' Ƃ column ͏dĂ܂", est "Kattuv tulba nimi '%-.64s'" fre "Nom du champ '%-.64s' dj utilis" ger "Doppelter Spaltenname vorhanden: '%-.64s'" @@ -1411,6 +1458,7 @@ ER_DUP_KEYNAME 42000 S1009 dan "Indeksnavnet '%-.64s' findes allerede" nla "Dubbele zoeksleutel naam '%-.64s'" eng "Duplicate key name '%-.64s'" + jps "'%-.64s' Ƃ key ̖O͏dĂ܂", est "Kattuv vtme nimi '%-.64s'" fre "Nom de clef '%-.64s' dj utilis" ger "Doppelter Name fr Schlssel (Key) vorhanden: '%-.64s'" @@ -1435,6 +1483,7 @@ ER_DUP_ENTRY 23000 S1009 dan "Ens vrdier '%-.64s' for indeks %d" nla "Dubbele ingang '%-.64s' voor zoeksleutel %d" eng "Duplicate entry '%-.64s' for key %d" + jps "'%-.64s' key %d ɂďdĂ܂", est "Kattuv vrtus '%-.64s' vtmele %d" fre "Duplicata du champ '%-.64s' pour la clef %d" ger "Doppelter Eintrag '%-.64s' fr Schlssel %d" @@ -1482,6 +1531,7 @@ ER_PARSE_ERROR 42000 dan "%s nr '%-.64s' p linje %d" nla "%s bij '%-.64s' in regel %d" eng "%s near '%-.80s' at line %d" + jps "%s : '%-.80s' t : %d s", est "%s '%-.80s' ligidal real %d" fre "%s prs de '%-.64s' la ligne %d" ger "%s bei '%-.80s' in Zeile %d" @@ -1506,6 +1556,7 @@ ER_EMPTY_QUERY 42000 dan "Foresprgsel var tom" nla "Query was leeg" eng "Query was empty" + jps "Query ł.", est "Thi pring" fre "Query est vide" ger "Leere Abfrage" @@ -1530,6 +1581,7 @@ ER_NONUNIQ_TABLE 42000 S1009 dan "Tabellen/aliaset: '%-.64s' er ikke unikt" nla "Niet unieke waarde tabel/alias: '%-.64s'" eng "Not unique table/alias: '%-.64s'" + jps "'%-.64s' ͈ӂ table/alias ł͂܂", est "Ei ole unikaalne tabel/alias '%-.64s'" fre "Table/alias: '%-.64s' non unique" ger "Tabellenname/Alias '%-.64s' nicht eindeutig" @@ -1577,6 +1629,7 @@ ER_MULTIPLE_PRI_KEY 42000 S1009 dan "Flere primrngler specificeret" nla "Meerdere primaire zoeksleutels gedefinieerd" eng "Multiple primary key defined" + jps " primary key `܂", est "Mitut primaarset vtit ei saa olla" fre "Plusieurs clefs primaires dfinies" ger "Mehrfacher Primrschlssel (PRIMARY KEY) definiert" @@ -1601,6 +1654,7 @@ ER_TOO_MANY_KEYS 42000 S1009 dan "For mange ngler specificeret. Kun %d ngler m bruges" nla "Teveel zoeksleutels gedefinieerd. Maximaal zijn %d zoeksleutels toegestaan" eng "Too many keys specified; max %d keys allowed" + jps "key ̎w肪܂. key ͍ő %d ܂łł", est "Liiga palju vtmeid. Maksimaalselt vib olla %d vtit" fre "Trop de clefs sont dfinies. Maximum de %d clefs allou" ger "Zu viele Schlssel definiert. Maximal %d Schlssel erlaubt" @@ -1648,6 +1702,7 @@ ER_TOO_LONG_KEY 42000 S1009 dan "Specificeret ngle var for lang. Maksimal nglelngde er %d" nla "Gespecificeerde zoeksleutel was te lang. De maximale lengte is %d" eng "Specified key was too long; max key length is %d bytes" + jps "key ܂. key ͍̒ő %d ł", est "Vti on liiga pikk. Maksimaalne vtmepikkus on %d" fre "La cl est trop longue. Longueur maximale: %d" ger "Schlssel ist zu lang. Die maximale Schlssellnge betrgt %d" @@ -1672,6 +1727,7 @@ ER_KEY_COLUMN_DOES_NOT_EXITS 42000 S1009 dan "Nglefeltet '%-.64s' eksisterer ikke i tabellen" nla "Zoeksleutel kolom '%-.64s' bestaat niet in tabel" eng "Key column '%-.64s' doesn't exist in table" + jps "Key column '%-.64s' e[uɂ܂.", est "Vtme tulp '%-.64s' puudub tabelis" fre "La cl '%-.64s' n'existe pas dans la table" ger "In der Tabelle gibt es keine Schlsselspalte '%-.64s'" @@ -1719,6 +1775,7 @@ ER_TOO_BIG_FIELDLENGTH 42000 S1009 dan "For stor feltlngde for kolonne '%-.64s' (maks = %d). Brug BLOB i stedet" nla "Te grote kolomlengte voor '%-.64s' (max = %d). Maak hiervoor gebruik van het type BLOB" eng "Column length too big for column '%-.64s' (max = %d); use BLOB instead" + jps "column '%-.64s' ,mۂ column ̑傫܂. (ő %d ܂). BLOB ɎgpĂ.", est "Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %d). Kasuta BLOB vljatpi" fre "Champ '%-.64s' trop long (max = %d). Utilisez un BLOB" ger "Feldlnge fr Feld '%-.64s' zu gro (maximal %d). BLOB-Feld verwenden!" @@ -1743,6 +1800,7 @@ ER_WRONG_AUTO_KEY 42000 S1009 dan "Der kan kun specificeres eet AUTO_INCREMENT-felt, og det skal vre indekseret" nla "Er kan slechts 1 autofield zijn en deze moet als zoeksleutel worden gedefinieerd." eng "Incorrect table definition; there can be only one auto column and it must be defined as a key" + jps "e[u̒`Ⴂ܂; there can be only one auto column and it must be defined as a key", est "Vigane tabelikirjeldus; Tabelis tohib olla ks auto_increment tpi tulp ning see peab olema defineeritud vtmena" fre "Un seul champ automatique est permis et il doit tre index" ger "Falsche Tabellendefinition. Es darf nur ein Auto-Feld geben und dieses muss als Schlssel definiert werden" @@ -1767,6 +1825,7 @@ ER_READY dan "%s: klar til tilslutninger" nla "%s: klaar voor verbindingen" eng "%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d" + jps "%s: ", est "%s: ootab hendusi" fre "%s: Prt pour des connections" ger "%-.64s: Bereit fr Verbindungen" @@ -1814,6 +1873,7 @@ ER_GOT_SIGNAL dan "%s: Fangede signal %d. Afslutter!!\n" nla "%s: Signaal %d. Systeem breekt af!\n" eng "%s: Got signal %d. Aborting!\n" + jps "%s: Got signal %d. f!\n", est "%s: sain signaali %d. Lpetan!\n" fre "%s: Reu le signal %d. Abandonne!\n" ger "%-.64s: Signal %d erhalten. Abbruch!\n" @@ -1838,6 +1898,7 @@ ER_SHUTDOWN_COMPLETE dan "%s: Server lukket\n" nla "%s: Afsluiten afgerond\n" eng "%s: Shutdown complete\n" + jps "%s: Shutdown \n", est "%s: Lpp\n" fre "%s: Arrt du serveur termin\n" ger "%-.64s: Heruntergefahren (shutdown)\n" @@ -1862,6 +1923,7 @@ ER_FORCING_CLOSE 08S01 dan "%s: Forceret nedlukning af trd: %ld bruger: '%-.64s'\n" nla "%s: Afsluiten afgedwongen van thread %ld gebruiker: '%-.64s'\n" eng "%s: Forcing close of thread %ld user: '%-.32s'\n" + jps "%s: Xbh %ld I user: '%-.64s'\n", est "%s: Sulgen juga lime %ld kasutaja: '%-.32s'\n" fre "%s: Arrt forc de la tche (thread) %ld utilisateur: '%-.64s'\n" ger "%s: Thread %ld zwangsweise beendet. Benutzer: '%-.32s'\n" @@ -1886,6 +1948,7 @@ ER_IPSOCK_ERROR 08S01 dan "Kan ikke oprette IP socket" nla "Kan IP-socket niet openen" eng "Can't create IP socket" + jps "IP socket ܂", est "Ei suuda luua IP socketit" fre "Ne peut crer la connection IP (socket)" ger "Kann IP-Socket nicht erzeugen" @@ -1910,6 +1973,7 @@ ER_NO_SUCH_INDEX 42S12 S1009 dan "Tabellen '%-.64s' har ikke den ngle, som blev brugt i CREATE INDEX. Genopret tabellen" nla "Tabel '%-.64s' heeft geen INDEX zoals deze gemaakt worden met CREATE INDEX. Maak de tabel opnieuw" eng "Table '%-.64s' has no index like the one used in CREATE INDEX; recreate the table" + jps "Table '%-.64s' ͂̂悤 index Ă܂(CREATE INDEX sɎw肳Ă܂). e[u蒼Ă", est "Tabelil '%-.64s' puuduvad vtmed. Loo tabel uuesti" fre "La table '%-.64s' n'a pas d'index comme celle utilise dans CREATE INDEX. Recrez la table" ger "Tabelle '%-.64s' besitzt keinen wie den in CREATE INDEX verwendeten Index. Index neu anlegen" @@ -1981,6 +2045,7 @@ ER_TEXTFILE_NOT_READABLE dan "Filen '%-.64s' skal vre i database-folderen og kunne lses af alle" nla "Het bestand '%-.64s' dient in de database directory voor the komen of leesbaar voor iedereen te zijn." eng "The file '%-.64s' must be in the database directory or be readable by all" + jps "t@C '%-.64s' databse directory ɂ邩SẴ[U[ǂ߂悤ɋ‚ĂȂ΂Ȃ܂.", est "Fail '%-.64s' peab asuma andmebaasi kataloogis vi olema kigile loetav" fre "Le fichier '%-.64s' doit tre dans le rpertoire de la base et lisible par tous" ger "Datei '%-.64s' muss im Datenbank-Verzeichnis vorhanden und lesbar fr alle sein" @@ -2005,6 +2070,7 @@ ER_FILE_EXISTS_ERROR dan "Filen '%-.64s' eksisterer allerede" nla "Het bestand '%-.64s' bestaat reeds" eng "File '%-.80s' already exists" + jps "File '%-.64s' ͊ɑ݂܂", est "Fail '%-.80s' juba eksisteerib" fre "Le fichier '%-.64s' existe dj" ger "Datei '%-.64s' bereits vorhanden" @@ -2029,6 +2095,7 @@ ER_LOAD_INFO dan "Poster: %ld Fjernet: %ld Sprunget over: %ld Advarsler: %ld" nla "Records: %ld Verwijderd: %ld Overgeslagen: %ld Waarschuwingen: %ld" eng "Records: %ld Deleted: %ld Skipped: %ld Warnings: %ld" + jps "R[h: %ld 폜: %ld Skipped: %ld Warnings: %ld", est "Kirjeid: %ld Kustutatud: %ld Vahele jetud: %ld Hoiatusi: %ld" fre "Enregistrements: %ld Effacs: %ld Non traits: %ld Avertissements: %ld" ger "Datenstze: %ld Gelscht: %ld Ausgelassen: %ld Warnungen: %ld" @@ -2053,6 +2120,7 @@ ER_ALTER_INFO dan "Poster: %ld Ens: %ld" nla "Records: %ld Dubbel: %ld" eng "Records: %ld Duplicates: %ld" + jps "R[h: %ld d: %ld", est "Kirjeid: %ld Kattuvaid: %ld" fre "Enregistrements: %ld Doublons: %ld" ger "Datenstze: %ld Duplikate: %ld" @@ -2101,6 +2169,7 @@ ER_CANT_REMOVE_ALL_FIELDS 42000 dan "Man kan ikke slette alle felter med ALTER TABLE. Brug DROP TABLE i stedet." nla "Het is niet mogelijk alle velden te verwijderen met ALTER TABLE. Gebruik a.u.b. DROP TABLE hiervoor!" eng "You can't delete all columns with ALTER TABLE; use DROP TABLE instead" + jps "ALTER TABLE őSĂ column ͍폜ł܂. DROP TABLE gpĂ", est "ALTER TABLE kasutades ei saa kustutada kiki tulpasid. Kustuta tabel DROP TABLE abil" fre "Vous ne pouvez effacer tous les champs avec ALTER TABLE. Utilisez DROP TABLE" ger "Mit ALTER TABLE knnen nicht alle Felder auf einmal gelscht werden. Dafr DROP TABLE verwenden" @@ -2125,6 +2194,7 @@ ER_CANT_DROP_FIELD_OR_KEY 42000 dan "Kan ikke udfre DROP '%-.64s'. Undersg om feltet/nglen eksisterer." nla "Kan '%-.64s' niet weggooien. Controleer of het veld of de zoeksleutel daadwerkelijk bestaat." eng "Can't DROP '%-.64s'; check that column/key exists" + jps "'%-.64s' jł܂ł; check that column/key exists", est "Ei suuda kustutada '%-.64s'. Kontrolli kas tulp/vti eksisteerib" fre "Ne peut effacer (DROP) '%-.64s'. Vrifiez s'il existe" ger "Kann '%-.64s' nicht lschen. Existiert das Feld / der Schlssel?" @@ -2149,6 +2219,7 @@ ER_INSERT_INFO dan "Poster: %ld Ens: %ld Advarsler: %ld" nla "Records: %ld Dubbel: %ld Waarschuwing: %ld" eng "Records: %ld Duplicates: %ld Warnings: %ld" + jps "R[h: %ld d: %ld Warnings: %ld", est "Kirjeid: %ld Kattuvaid: %ld Hoiatusi: %ld" fre "Enregistrements: %ld Doublons: %ld Avertissements: %ld" ger "Datenstze: %ld Duplikate: %ld Warnungen: %ld" @@ -2179,6 +2250,7 @@ ER_NO_SUCH_THREAD dan "Ukendt trd id: %lu" nla "Onbekend thread id: %lu" eng "Unknown thread id: %lu" + jps "thread id: %lu ͂܂", est "Tundmatu lim: %lu" fre "Numro de tche inconnu: %lu" ger "Unbekannte Thread-ID: %lu" @@ -2203,6 +2275,7 @@ ER_KILL_DENIED_ERROR dan "Du er ikke ejer af trden %lu" nla "U bent geen bezitter van thread %lu" eng "You are not owner of thread %lu" + jps "thread %lu ̃I[i[ł͂܂", est "Ei ole lime %lu omanik" fre "Vous n'tes pas propritaire de la tche no: %lu" ger "Sie sind nicht Eigentmer von Thread %lu" @@ -2296,6 +2369,7 @@ ER_TABLE_NOT_LOCKED_FOR_WRITE dan "Tabellen '%-.64s' var lst med READ ls og kan ikke opdateres" nla "Tabel '%-.64s' was gelocked met een lock om te lezen. Derhalve kunnen geen wijzigingen worden opgeslagen." eng "Table '%-.64s' was locked with a READ lock and can't be updated" + jps "Table '%-.64s' READ lock ɂȂĂāAXV͂ł܂", est "Tabel '%-.64s' on lukustatud READ lukuga ning ei ole muudetav" fre "Table '%-.64s' verrouille lecture (READ): modification impossible" ger "Tabelle '%-.64s' ist mit Lesesperre versehen und kann nicht aktualisiert werden" @@ -2320,6 +2394,7 @@ ER_TABLE_NOT_LOCKED dan "Tabellen '%-.64s' var ikke lst med LOCK TABLES" nla "Tabel '%-.64s' was niet gelocked met LOCK TABLES" eng "Table '%-.64s' was not locked with LOCK TABLES" + jps "Table '%-.64s' LOCK TABLES ɂăbNĂ܂", est "Tabel '%-.64s' ei ole lukustatud ksuga LOCK TABLES" fre "Table '%-.64s' non verrouille: utilisez LOCK TABLES" ger "Tabelle '%-.64s' wurde nicht mit LOCK TABLES gesperrt" @@ -2368,6 +2443,7 @@ ER_WRONG_DB_NAME 42000 dan "Ugyldigt database navn '%-.64s'" nla "Databasenaam '%-.64s' is niet getoegestaan" eng "Incorrect database name '%-.100s'" + jps "w肵 database '%-.100s' ԈĂ܂", est "Vigane andmebaasi nimi '%-.100s'" fre "Nom de base de donne illgal: '%-.64s'" ger "Unerlaubter Datenbankname '%-.64s'" @@ -2392,6 +2468,7 @@ ER_WRONG_TABLE_NAME 42000 dan "Ugyldigt tabel navn '%-.64s'" nla "Niet toegestane tabelnaam '%-.64s'" eng "Incorrect table name '%-.100s'" + jps "w肵 table '%-.100s' ͂܂Ă܂", est "Vigane tabeli nimi '%-.100s'" fre "Nom de table illgal: '%-.64s'" ger "Unerlaubter Tabellenname '%-.64s'" @@ -2620,6 +2697,7 @@ ER_TABLE_MUST_HAVE_COLUMNS 42000 dan "En tabel skal have mindst een kolonne" nla "Een tabel moet minstens 1 kolom bevatten" eng "A table must have at least 1 column" + jps "e[u͍Œ 1 ‚ column Kvł", est "Tabelis peab olema vhemalt ks tulp" fre "Une table doit comporter au moins une colonne" ger "Eine Tabelle mu mindestens 1 Spalte besitzen" @@ -2641,6 +2719,7 @@ ER_RECORD_FILE_FULL dan "Tabellen '%-.64s' er fuld" nla "De tabel '%-.64s' is vol" eng "The table '%-.64s' is full" + jps "table '%-.64s' ͂ςł", est "Tabel '%-.64s' on tis" fre "La table '%-.64s' est pleine" ger "Tabelle '%-.64s' ist voll" @@ -2662,6 +2741,7 @@ ER_UNKNOWN_CHARACTER_SET 42000 dan "Ukendt tegnst: '%-.64s'" nla "Onbekende character set: '%-.64s'" eng "Unknown character set: '%-.64s'" + jps "character set '%-.64s' ̓T|[gĂ܂", est "Vigane kooditabel '%-.64s'" fre "Jeu de caractres inconnu: '%-.64s'" ger "Unbekannter Zeichensatz: '%-.64s'" @@ -2683,6 +2763,7 @@ ER_TOO_MANY_TABLES dan "For mange tabeller. MySQL kan kun bruge %d tabeller i et join" nla "Teveel tabellen. MySQL kan slechts %d tabellen in een join bevatten" eng "Too many tables; MySQL can only use %d tables in a join" + jps "e[u܂; MySQL can only use %d tables in a join", est "Liiga palju tabeleid. MySQL suudab JOINiga hendada kuni %d tabelit" fre "Trop de tables. MySQL ne peut utiliser que %d tables dans un JOIN" ger "Zu viele Tabellen. MySQL kann in einem Join maximal %d Tabellen verwenden" @@ -2704,6 +2785,7 @@ ER_TOO_MANY_FIELDS dan "For mange felter" nla "Te veel velden" eng "Too many columns" + jps "column ܂", est "Liiga palju tulpasid" fre "Trop de champs" ger "Zu viele Spalten" @@ -2725,6 +2807,7 @@ ER_TOO_BIG_ROWSIZE 42000 dan "For store poster. Max post strrelse, uden BLOB's, er %d. Du m lave nogle felter til BLOB's" nla "Rij-grootte is groter dan toegestaan. Maximale rij grootte, blobs niet meegeteld, is %d. U dient sommige velden in blobs te veranderen." eng "Row size too large. The maximum row size for the used table type, not counting BLOBs, is %ld. You have to change some columns to TEXT or BLOBs" + jps "row size 傫܂. BLOB ܂܂Ȃꍇ row size ̍ő %d ł. ‚ field BLOB ɕςĂ.", est "Liiga pikk kirje. Kirje maksimumpikkus arvestamata BLOB-tpi vlju on %d. Muuda mned vljad BLOB-tpi vljadeks" fre "Ligne trop grande. Le taille maximale d'une ligne, sauf les BLOBs, est %d. Changez le type de quelques colonnes en BLOB" ger "Zeilenlnge zu gro. Die maximale Spaltenlnge fr den verwendeten Tabellentyp (ohne BLOB-Felder) betrgt %d. Einige Felder mssen in BLOB oder TEXT umgewandelt werden" @@ -2746,6 +2829,7 @@ ER_STACK_OVERRUN dan "Thread stack brugt: Brugt: %ld af en %ld stak. Brug 'mysqld -O thread_stack=#' for at allokere en strre stak om ndvendigt" nla "Thread stapel overrun: Gebruikte: %ld van een %ld stack. Gebruik 'mysqld -O thread_stack=#' om een grotere stapel te definieren (indien noodzakelijk)." eng "Thread stack overrun: Used: %ld of a %ld stack. Use 'mysqld -O thread_stack=#' to specify a bigger stack if needed" + jps "Thread stack overrun: Used: %ld of a %ld stack. X^bN𑽂̈Ƃ肽ꍇA'mysqld -O thread_stack=#' Ǝw肵Ă", fre "Dbordement de la pile des tches (Thread stack). Utilises: %ld pour une pile de %ld. Essayez 'mysqld -O thread_stack=#' pour indiquer une plus grande valeur" ger "Thread-Stack-berlauf. Benutzt: %ld von %ld Stack. 'mysqld -O thread_stack=#' verwenen, um notfalls einen greren Stack anzulegen" greek "Stack overrun thread: Used: %ld of a %ld stack. 'mysqld -O thread_stack=#' stack " @@ -2785,6 +2869,7 @@ ER_NULL_COLUMN_IN_INDEX 42000 dan "Kolonne '%-.32s' bruges som UNIQUE eller INDEX men er ikke defineret som NOT NULL" nla "Kolom '%-.64s' wordt gebruikt met UNIQUE of INDEX maar is niet gedefinieerd als NOT NULL" eng "Column '%-.64s' is used with UNIQUE or INDEX but is not defined as NOT NULL" + jps "Column '%-.64s' UNIQUE INDEX Ŏgp܂. ̃J NOT NULL ƒ`Ă܂.", est "Tulp '%-.64s' on kasutusel indeksina, kuid ei ole mratletud kui NOT NULL" fre "La colonne '%-.32s' fait partie d'un index UNIQUE ou INDEX mais n'est pas dfinie comme NOT NULL" ger "Spalte '%-.64s' wurde mit UNIQUE oder INDEX benutzt, ist aber nicht als NOT NULL definiert" @@ -2809,6 +2894,7 @@ ER_CANT_FIND_UDF dan "Kan ikke lse funktionen '%-.64s'" nla "Kan functie '%-.64s' niet laden" eng "Can't load function '%-.64s'" + jps "function '%-.64s' [hł܂", est "Ei suuda avada funktsiooni '%-.64s'" fre "Imposible de charger la fonction '%-.64s'" ger "Kann Funktion '%-.64s' nicht laden" @@ -2830,6 +2916,7 @@ ER_CANT_INITIALIZE_UDF dan "Kan ikke starte funktionen '%-.64s'; %-.80s" nla "Kan functie '%-.64s' niet initialiseren; %-.80s" eng "Can't initialize function '%-.64s'; %-.80s" + jps "function '%-.64s' ł܂; %-.80s", est "Ei suuda algvrtustada funktsiooni '%-.64s'; %-.80s" fre "Impossible d'initialiser la fonction '%-.64s'; %-.80s" ger "Kann Funktion '%-.64s' nicht initialisieren: %-.80s" @@ -2851,6 +2938,7 @@ ER_UDF_NO_PATHS dan "Angivelse af sti ikke tilladt for delt bibliotek" nla "Geen pad toegestaan voor shared library" eng "No paths allowed for shared library" + jps "shared library ւ̃pXʂĂ܂", est "Teegi nimes ei tohi olla kataloogi" fre "Chemin interdit pour les bibliothques partages" ger "Keine Pfade gestattet fr Shared Library" @@ -2872,6 +2960,7 @@ ER_UDF_EXISTS dan "Funktionen '%-.64s' findes allerede" nla "Functie '%-.64s' bestaat reeds" eng "Function '%-.64s' already exists" + jps "Function '%-.64s' ͊ɒ`Ă܂", est "Funktsioon '%-.64s' juba eksisteerib" fre "La fonction '%-.64s' existe dj" ger "Funktion '%-.64s' existiert schon" @@ -2893,6 +2982,7 @@ ER_CANT_OPEN_LIBRARY dan "Kan ikke bne delt bibliotek '%-.64s' (errno: %d %s)" nla "Kan shared library '%-.64s' niet openen (Errcode: %d %s)" eng "Can't open shared library '%-.64s' (errno: %d %-.64s)" + jps "shared library '%-.64s' Jł܂ (errno: %d %s)", est "Ei suuda avada jagatud teeki '%-.64s' (veakood: %d %-.64s)" fre "Impossible d'ouvrir la bibliothque partage '%-.64s' (errno: %d %s)" ger "Kann Shared Library '%-.64s' nicht ffnen (Fehler: %d %-.64s)" @@ -2917,6 +3007,7 @@ ER_CANT_FIND_DL_ENTRY dan "Kan ikke finde funktionen '%-.64s' i bibliotek'" nla "Kan functie '%-.64s' niet in library vinden" eng "Can't find function '%-.64s' in library'" + jps "function '%-.64s' Cu[Ɍt鎖ł܂", est "Ei leia funktsiooni '%-.64s' antud teegis" fre "Impossible de trouver la fonction '%-.64s' dans la bibliothque'" ger "Kann Funktion '%-.64s' in der Library nicht finden" @@ -2938,6 +3029,7 @@ ER_FUNCTION_NOT_DEFINED dan "Funktionen '%-.64s' er ikke defineret" nla "Functie '%-.64s' is niet gedefinieerd" eng "Function '%-.64s' is not defined" + jps "Function '%-.64s' ͒`Ă܂", est "Funktsioon '%-.64s' ei ole defineeritud" fre "La fonction '%-.64s' n'est pas dfinie" ger "Funktion '%-.64s' ist nicht definiert" @@ -2959,6 +3051,7 @@ ER_HOST_IS_BLOCKED dan "Vrten er blokeret p grund af mange fejlforesprgsler. Ls op med 'mysqladmin flush-hosts'" nla "Host '%-.64s' is geblokkeeerd vanwege te veel verbindings fouten. Deblokkeer met 'mysqladmin flush-hosts'" eng "Host '%-.64s' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'" + jps "Host '%-.64s' many connection error ̂߁Aۂ܂. 'mysqladmin flush-hosts' ʼnĂ", est "Masin '%-.64s' on blokeeritud hulgaliste hendusvigade tttu. Blokeeringu saab thistada 'mysqladmin flush-hosts' ksuga" fre "L'hte '%-.64s' est bloqu cause d'un trop grand nombre d'erreur de connection. Dbloquer le par 'mysqladmin flush-hosts'" ger "Host '%-.64s' blockiert wegen zu vieler Verbindungsfehler. Aufheben der Blockierung mit 'mysqladmin flush-hosts'" @@ -2979,6 +3072,7 @@ ER_HOST_NOT_PRIVILEGED dan "Vrten '%-.64s' kan ikke tilkoble denne MySQL-server" nla "Het is host '%-.64s' is niet toegestaan verbinding te maken met deze MySQL server" eng "Host '%-.64s' is not allowed to connect to this MySQL server" + jps "Host '%-.64s' MySQL server ɐڑ‚Ă܂", est "Masinal '%-.64s' puudub ligips sellele MySQL serverile" fre "Le hte '%-.64s' n'est pas authoris se connecter ce serveur MySQL" ger "Host '%-.64s' hat keine Berechtigung, sich mit diesem MySQL-Server zu verbinden" @@ -2999,6 +3093,7 @@ ER_PASSWORD_ANONYMOUS_USER 42000 dan "Du bruger MySQL som anonym bruger. Anonyme brugere m ikke ndre adgangskoder" nla "U gebruikt MySQL als anonieme gebruiker en deze mogen geen wachtwoorden wijzigen" eng "You are using MySQL as an anonymous user and anonymous users are not allowed to change passwords" + jps "MySQL anonymous users ŎgpĂԂł́ApX[h̕ύX͂ł܂", est "Te kasutate MySQL-i anonmse kasutajana, kelledel pole parooli muutmise igust" fre "Vous utilisez un utilisateur anonyme et les utilisateurs anonymes ne sont pas autoriss changer les mots de passe" ger "Sie benutzen MySQL als anonymer Benutzer und drfen daher keine Passwrter ndern" @@ -3019,6 +3114,7 @@ ER_PASSWORD_NOT_ALLOWED 42000 dan "Du skal have tilladelse til at opdatere tabeller i MySQL databasen for at ndre andres adgangskoder" nla "U moet tabel update priveleges hebben in de mysql database om wachtwoorden voor anderen te mogen wijzigen" eng "You must have privileges to update tables in the mysql database to be able to change passwords for others" + jps "̃[U[̃pX[hύX邽߂ɂ, mysql f[^x[Xɑ΂ update ̋‚Ȃ΂Ȃ܂.", est "Teiste paroolide muutmiseks on nutav tabelite muutmisigus 'mysql' andmebaasis" fre "Vous devez avoir le privilge update sur les tables de la base de donne mysql pour pouvoir changer les mots de passe des autres" ger "Sie bentigen die Berechtigung zum Aktualisieren von Tabellen in der Datenbank 'mysql', um die Passwrter anderer Benutzer ndern zu knnen" @@ -3058,6 +3154,7 @@ ER_UPDATE_INFO dan "Poster fundet: %ld ndret: %ld Advarsler: %ld" nla "Passende rijen: %ld Gewijzigd: %ld Waarschuwingen: %ld" eng "Rows matched: %ld Changed: %ld Warnings: %ld" + jps "v(Rows matched): %ld ύX: %ld Warnings: %ld", est "Sobinud kirjeid: %ld Muudetud: %ld Hoiatusi: %ld" fre "Enregistrements correspondants: %ld Modifis: %ld Warnings: %ld" ger "Datenstze gefunden: %ld Gendert: %ld Warnungen: %ld" @@ -3077,6 +3174,7 @@ ER_CANT_CREATE_THREAD dan "Kan ikke danne en ny trd (fejl nr. %d). Hvis computeren ikke er lbet tr for hukommelse, kan du se i brugervejledningen for en mulig operativ-system - afhngig fejl" nla "Kan geen nieuwe thread aanmaken (Errcode: %d). Indien er geen tekort aan geheugen is kunt u de handleiding consulteren over een mogelijke OS afhankelijke fout" eng "Can't create a new thread (errno %d); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug" + jps "VKɃXbh܂ł (errno %d). őgpƒ[zĂȂ̂ɃG[ĂȂ, }jA̒ 'possible OS-dependent bug' ƂTĂ݂Ă.", est "Ei suuda luua uut lime (veakood %d). Kui mlu ei ole otsas, on tenoliselt tegemist operatsioonissteemispetsiifilise veaga" fre "Impossible de crer une nouvelle tche (errno %d). S'il reste de la mmoire libre, consultez le manual pour trouver un ventuel bug dpendant de l'OS" ger "Kann keinen neuen Thread erzeugen (Fehler: %d). Sollte noch Speicher verfgbar sein, bitte im Handbuch wegen mglicher Fehler im Betriebssystem nachschlagen" @@ -3138,6 +3236,7 @@ ER_INVALID_USE_OF_NULL 22004 dan "Forkert brug af nulvrdi (NULL)" nla "Foutief gebruik van de NULL waarde" eng "Invalid use of NULL value" + jps "NULL l̎gp@sK؂ł", est "NULL vrtuse vrkasutus" fre "Utilisation incorrecte de la valeur NULL" ger "Unerlaubte Verwendung eines NULL-Werts" @@ -3193,6 +3292,7 @@ ER_NONEXISTING_GRANT 42000 dan "Denne tilladelse findes ikke for brugeren '%-.32s' p vrt '%-.64s'" nla "Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s'" eng "There is no such grant defined for user '%-.32s' on host '%-.64s'" + jps "[U[ '%-.32s' (zXg '%-.64s' ̃[U[) ͋‚Ă܂", est "Sellist igust ei ole defineeritud kasutajale '%-.32s' masinast '%-.64s'" fre "Un tel droit n'est pas dfini pour l'utilisateur '%-.32s' sur l'hte '%-.64s'" ger "Fr Benutzer '%-.32s' auf Host '%-.64s' gibt es keine solche Berechtigung" @@ -3212,6 +3312,7 @@ ER_TABLEACCESS_DENIED_ERROR 42000 dan "%-.16s-kommandoen er ikke tilladt for brugeren '%-.32s'@'%-.64s' for tabellen '%-.64s'" nla "%-.16s commando geweigerd voor gebruiker: '%-.32s'@'%-.64s' voor tabel '%-.64s'" eng "%-.16s command denied to user '%-.32s'@'%-.64s' for table '%-.64s'" + jps "R}h %-.16s [U[ '%-.32s'@'%-.64s' ,e[u '%-.64s' ɑ΂ċ‚Ă܂", est "%-.16s ksk ei ole lubatud kasutajale '%-.32s'@'%-.64s' tabelis '%-.64s'" fre "La commande '%-.16s' est interdite l'utilisateur: '%-.32s'@'@%-.64s' sur la table '%-.64s'" ger "%-.16s Befehl nicht erlaubt fr Benutzer '%-.32s'@'%-.64s' und fr Tabelle '%-.64s'" @@ -3231,6 +3332,7 @@ ER_COLUMNACCESS_DENIED_ERROR 42000 dan "%-.16s-kommandoen er ikke tilladt for brugeren '%-.32s'@'%-.64s' for kolonne '%-.64s' in tabellen '%-.64s'" nla "%-.16s commando geweigerd voor gebruiker: '%-.32s'@'%-.64s' voor kolom '%-.64s' in tabel '%-.64s'" eng "%-.16s command denied to user '%-.32s'@'%-.64s' for column '%-.64s' in table '%-.64s'" + jps "R}h %-.16s [U[ '%-.32s'@'%-.64s'\n J '%-.64s' e[u '%-.64s' ɑ΂ċ‚Ă܂", est "%-.16s ksk ei ole lubatud kasutajale '%-.32s'@'%-.64s' tulbale '%-.64s' tabelis '%-.64s'" fre "La commande '%-.16s' est interdite l'utilisateur: '%-.32s'@'@%-.64s' sur la colonne '%-.64s' de la table '%-.64s'" ger "%-.16s Befehl nicht erlaubt fr Benutzer '%-.32s'@'%-.64s' und Spalte '%-.64s' in Tabelle '%-.64s'" diff --git a/sql/slave.cc b/sql/slave.cc index 0bcc1b7e852..5332dbf9c5b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1418,7 +1418,12 @@ not always make sense; please check the manual before using it)."; values of these 2 are never used (new connections don't use them). We don't test equality of global collation_database either as it's is going to be deprecated (made read-only) in 4.1 very soon. + We don't do it for <3.23.57 because masters <3.23.50 hang on + SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). */ + if (strncmp(mi->rli.relay_log.description_event_for_queue->server_version, + "3.23.57",7) < 0) + goto err; if (!mysql_real_query(mysql, "SELECT @@GLOBAL.COLLATION_SERVER", 32) && (master_res= mysql_store_result(mysql))) { @@ -1455,6 +1460,7 @@ be equal for replication to work"; mysql_free_result(master_res); } +err: if (errmsg) { sql_print_error(errmsg); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 48855892567..fc41643e8d4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1853,8 +1853,8 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) { - DBUG_ENTER("open_and_lock_tables"); uint counter; + DBUG_ENTER("open_and_lock_tables"); if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter) || mysql_handle_derived(thd->lex, &mysql_derived_prepare) || @@ -1866,6 +1866,36 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) } +/* + Open all tables in list and process derived tables + + SYNOPSIS + open_normal_and_derived_tables + thd - thread handler + tables - list of tables for open&locking + + RETURN + FALSE - ok + TRUE - error + + NOTE + This is to be used on prepare stage when you don't read any + data from the tables. +*/ + +bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) +{ + uint counter; + DBUG_ENTER("open_normal_and_derived_tables"); + DBUG_ASSERT(!thd->fill_derived_tables()); + if (open_tables(thd, tables, &counter) || + mysql_handle_derived(thd->lex, &mysql_derived_prepare)) + DBUG_RETURN(TRUE); /* purecov: inspected */ + relink_tables_for_multidelete(thd); // Not really needed, but + DBUG_RETURN(0); +} + + /* Let us propagate pointers to open tables from global table list to table lists for multi-delete @@ -2090,7 +2120,7 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list, Field_translator *trans= table_list->field_translation; for (uint i= 0; i < num; i ++) { - if (strcmp(trans[i].name, name) == 0) + if (!my_strcasecmp(system_charset_info, trans[i].name, name)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_grants_view && diff --git a/sql/sql_class.h b/sql/sql_class.h index a33dba023d7..f635aa62000 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -205,6 +205,7 @@ public: inline bool is_open() { return log_type != LOG_CLOSED; } inline char* get_index_fname() { return index_file_name;} inline char* get_log_fname() { return log_file_name; } + inline char* get_name() { return name; } inline pthread_mutex_t* get_log_lock() { return &LOCK_log; } inline IO_CACHE* get_log_file() { return &log_file; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 495fa4a0bd1..2f6e74225fd 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -944,6 +944,7 @@ int yylex(void *arg, void *yythd) if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) && (thd->command != COM_PREPARE)) { + lex->safe_to_cache_query= 0; lex->found_colon= (char*) lex->ptr; thd->server_status|= SERVER_MORE_RESULTS_EXISTS; lex->next_state= MY_LEX_END; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9e4f6c1334c..a71b8148f8e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -900,8 +900,12 @@ static bool mysql_test_insert(Prepared_statement *stmt, /* open temporary memory pool for temporary data allocated by derived tables & preparation procedure + Note that this is done without locks (should not be needed as we will not + access any data here) + If we would use locks, then we have to ensure we are not using + TL_WRITE_DELAYED as having two such locks can cause table corruption. */ - if (open_and_lock_tables(thd, table_list)) + if (open_normal_and_derived_tables(thd, table_list)) { DBUG_RETURN(TRUE); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index edf950ce8d4..dba0b844de7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7826,12 +7826,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, if (temp_pool_slot != MY_BIT_NONE) // we got a slot sprintf(filename, "%s_%lx_%i", tmp_file_prefix, current_pid, temp_pool_slot); - else // if we run out of slots or we are not using tempool + else + { + /* if we run out of slots or we are not using tempool */ sprintf(filename,"%s%lx_%lx_%x",tmp_file_prefix,current_pid, thd->thread_id, thd->tmp_table++); + } - if (lower_case_table_names) - my_casedn_str(files_charset_info, path); + /* + No need for change table name to lower case as we are only creating + MyISAM or HEAP tables here + */ sprintf(path, "%s%s", mysql_tmpdir, filename); if (group) @@ -10424,15 +10429,24 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } else { - select->quick->head->file->ha_index_end(); - /* - We have verified above that select->quick is not - index_merge quick select. - */ - select->quick->index= new_ref_key; - select->quick->init(); + /* + The range optimizer constructed QUICK_RANGE for ref_key, and + we want to use instead new_ref_key as the index. We can't + just change the index of the quick select, because this may + result in an incosistent QUICK_SELECT object. Below we + create a new QUICK_SELECT from scratch so that all its + parameres are set correctly by the range optimizer. + */ + key_map new_ref_key_map; + new_ref_key_map.clear_all(); /* Force the creation of quick select */ + new_ref_key_map.set_bit(new_ref_key); /* only for new_ref_key. */ + + if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0, + (tab->join->select_options & OPTION_FOUND_ROWS) ? + HA_POS_ERROR : tab->join->unit->select_limit_cnt) <= 0) + DBUG_RETURN(0); } - ref_key= new_ref_key; + ref_key= new_ref_key; } } /* Check if we get the rows in requested sorted order by using the key */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2aa8a67fbab..c7b4b61ca33 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1534,25 +1534,6 @@ static bool show_status_array(THD *thd, const char *wild, } -bool mysqld_show(THD *thd, const char *wild, show_var_st *variables, - enum enum_var_type value_type, - pthread_mutex_t *mutex, - struct system_status_var *status_var, TABLE *table) -{ - DBUG_ENTER("mysqld_show"); - ha_update_statistics(); /* Export engines statistics */ - pthread_mutex_lock(mutex); - if (show_status_array(thd, wild, variables, value_type, status_var, "", table)) - goto err; - pthread_mutex_unlock(mutex); - DBUG_RETURN(FALSE); - - err: - pthread_mutex_unlock(mutex); - DBUG_RETURN(TRUE); -} - - /* collect status for all running threads */ void calc_sum_of_all_status(STATUS_VAR *to) @@ -2874,10 +2855,13 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) { DBUG_ENTER("fill_variables"); + int res= 0; LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; - int res= mysqld_show(thd, wild, init_vars, lex->option_type, - &LOCK_global_system_variables, 0, tables->table); + pthread_mutex_lock(&LOCK_global_system_variables); + res= show_status_array(thd, wild, init_vars, + lex->option_type, 0, "", tables->table); + pthread_mutex_unlock(&LOCK_global_system_variables); DBUG_RETURN(res); } @@ -2889,17 +2873,14 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) const char *wild= lex->wild ? lex->wild->ptr() : NullS; int res= 0; STATUS_VAR tmp; - + ha_update_statistics(); /* Export engines statistics */ + pthread_mutex_lock(&LOCK_status); if (lex->option_type == OPT_GLOBAL) - { - pthread_mutex_lock(&LOCK_status); calc_sum_of_all_status(&tmp); - } - res= mysqld_show(thd, wild, status_vars, OPT_GLOBAL, &LOCK_status, - (lex->option_type == OPT_GLOBAL ? - &tmp: &thd->status_var), tables->table); - if (lex->option_type == OPT_GLOBAL) - pthread_mutex_unlock(&LOCK_status); + res= show_status_array(thd, wild, status_vars, OPT_GLOBAL, + (lex->option_type == OPT_GLOBAL ? + &tmp: &thd->status_var), "",tables->table); + pthread_mutex_unlock(&LOCK_status); DBUG_RETURN(res); } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index ce84be47243..0a91eb4c0e1 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -478,11 +478,14 @@ bool st_select_lex_unit::exec() } res= sl->join->error; offset_limit_cnt= sl->offset_limit; - if (!res && union_result->flush()) + if (!res) { - examined_rows+= thd->examined_row_count; - thd->lex->current_select= lex_select_save; - DBUG_RETURN(TRUE); + examined_rows+= thd->examined_row_count; + if (union_result->flush()) + { + thd->lex->current_select= lex_select_save; + DBUG_RETURN(1); + } } } if (res) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 533876b6718..e2c4b1289fd 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -948,11 +948,12 @@ frm_type_enum mysql_frm_type(char *path) { DBUG_RETURN(FRMTYPE_ERROR); } - length= my_read(file, (byte*) header, 10, MYF(MY_WME)); + length= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME)); my_close(file, MYF(MY_WME)); if (length == (int) MY_FILE_ERROR) DBUG_RETURN(FRMTYPE_ERROR); - if (!strncmp(header, "TYPE=VIEW\n", 10)) + if (length < (int) sizeof(header) || + !strncmp(header, "TYPE=VIEW\n", sizeof(header))) DBUG_RETURN(FRMTYPE_VIEW); DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6b1456dfbd3..cc2443bd41b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2793,7 +2793,7 @@ type: | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } | DATE_SYM { $$=FIELD_TYPE_DATE; } | TIME_SYM { $$=FIELD_TYPE_TIME; } - | TIMESTAMP + | TIMESTAMP opt_len { if (YYTHD->variables.sql_mode & MODE_MAXDB) $$=FIELD_TYPE_DATETIME; @@ -2806,13 +2806,6 @@ type: $$=FIELD_TYPE_TIMESTAMP; } } - | TIMESTAMP '(' NUM ')' - { - LEX *lex= Lex; - lex->length= $3.str; - lex->type|= NOT_NULL_FLAG; - $$= FIELD_TYPE_TIMESTAMP; - } | DATETIME { $$=FIELD_TYPE_DATETIME; } | TINYBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_TINY_BLOB; } diff --git a/sql/table.cc b/sql/table.cc index 97f17ea2417..a030da95db4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -103,11 +103,11 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, O_RDONLY | O_SHARE, MYF(0))) < 0) - goto err_w_init; + goto err; error= 4; if (my_read(file,(byte*) head,64,MYF(MY_NABP))) - goto err_w_init; + goto err; if (memcmp(head, "TYPE=", 5) == 0) { @@ -116,9 +116,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (db_stat & NO_ERR_ON_NEW_FRM) DBUG_RETURN(5); - + file= -1; // caller can't process new .frm - goto err_w_init; + goto err; } share->blob_ptr_size= sizeof(char*); @@ -131,21 +131,21 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, share->path= strdup_root(&outparam->mem_root, name); outparam->alias= my_strdup(alias, MYF(MY_WME)); if (!share->table_name || !share->path || !outparam->alias) - goto err_not_open; + goto err; *fn_ext(share->table_name)='\0'; // Remove extension *fn_ext(share->path)='\0'; // Remove extension if (head[0] != (uchar) 254 || head[1] != 1 || (head[2] != FRM_VER && head[2] != FRM_VER+1 && ! (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ new_field_pack_flag=head[27]; new_frm_ver= (head[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; error=3; if (!(pos=get_form_pos(file,head,(TYPELIB*) 0))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ *fn_ext(index_file)='\0'; // Remove .frm extension share->frm_version= head[2]; @@ -166,6 +166,14 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (!share->table_charset) { /* unknown charset in head[38] or pre-3.23 frm */ + if (use_mb(default_charset_info)) + { + /* Warn that we may be changing the size of character columns */ + sql_print_warning("'%s' had no or invalid character set, " + "and default character set is multi-byte, " + "so character column sizes may have changed", + name); + } share->table_charset= default_charset_info; } share->db_record_offset= 1; @@ -181,7 +189,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, key_info_length= (uint) uint2korr(head+28); VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0))); if (read_string(file,(gptr*) &disk_buff,key_info_length)) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (disk_buff[0] & 0x80) { share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f); @@ -201,7 +209,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); if (!(keyinfo = (KEY*) alloc_root(&outparam->mem_root, n_length+uint2korr(disk_buff+4)))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ bzero((char*) keyinfo,n_length); outparam->key_info=keyinfo; key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys); @@ -210,7 +218,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, ulong *rec_per_key; if (!(rec_per_key= (ulong*) alloc_root(&outparam->mem_root, sizeof(ulong*)*key_parts))) - goto err_not_open; + goto err; for (i=0 ; i < keys ; i++, keyinfo++) { @@ -279,7 +287,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, /* Allocate handler */ if (!(outparam->file= get_new_handler(outparam, share->db_type))) - goto err_not_open; + goto err; error=4; outparam->reginfo.lock_type= TL_UNLOCK; @@ -296,14 +304,14 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, share->rec_buff_length= rec_buff_length; if (!(record= (char *) alloc_root(&outparam->mem_root, rec_buff_length * records))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ share->default_values= record; if (my_pread(file,(byte*) record, (uint) share->reclength, (ulong) (uint2korr(head+6)+ ((uint2korr(head+14) == 0xffff ? uint4korr(head+47) : uint2korr(head+14)))), MYF(MY_NABP))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (records == 1) { @@ -332,12 +340,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, } #endif VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0))); - if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open; + if (my_read(file,(byte*) head,288,MYF(MY_NABP))) + goto err; if (crypted) { crypted->decode((char*) head+256,288-256); if (sint2korr(head+284) != 0) // Should be 0 - goto err_not_open; // Wrong password + goto err; // Wrong password } share->fields= uint2korr(head+258); @@ -359,13 +368,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, (share->fields+interval_parts+ keys+3)*sizeof(my_string)+ (n_length+int_length+com_length))))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ outparam->field=field_ptr; read_length=(uint) (share->fields * field_pack_length + pos+ (uint) (n_length+int_length+com_length)); if (read_string(file,(gptr*) &disk_buff,read_length)) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (crypted) { crypted->decode((char*) disk_buff,read_length); @@ -398,7 +407,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, uint count= (uint) (interval->count + 1) * sizeof(uint); if (!(interval->type_lengths= (uint *) alloc_root(&outparam->mem_root, count))) - goto err_not_open; + goto err; for (count= 0; count < interval->count; count++) interval->type_lengths[count]= strlen(interval->type_names[count]); interval->type_lengths[count]= 0; @@ -459,7 +468,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, charset= &my_charset_bin; #else error= 4; // unsupported field type - goto err_not_open; + goto err; #endif } else @@ -470,7 +479,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, { error= 5; // Unknown or unavailable charset errarg= (int) strpos[14]; - goto err_not_open; + goto err; } } if (!comment_length) @@ -543,7 +552,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (!reg_field) // Not supported field type { error= 4; - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ } reg_field->comment=comment; if (field_type == FIELD_TYPE_BIT) @@ -616,7 +625,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, (uint) key_part->length); #ifdef EXTRA_DEBUG if (key_part->fieldnr > share->fields) - goto err_not_open; // sanity check + goto err; // sanity check #endif if (key_part->fieldnr) { // Should always be true ! @@ -767,7 +776,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (!(share->blob_field= save= (uint*) alloc_root(&outparam->mem_root, (uint) (share->blob_fields* sizeof(uint))))) - goto err_not_open; + goto err; for (i=0, ptr= outparam->field ; *ptr ; ptr++, i++) { if ((*ptr)->flags & BLOB_FLAG) @@ -779,25 +788,25 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, error=2; if (db_stat) { - int err; + int ha_err; unpack_filename(index_file,index_file); - if ((err=(outparam->file-> - ha_open(index_file, - (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), - (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : - ((db_stat & HA_WAIT_IF_LOCKED) || - (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? - HA_OPEN_WAIT_IF_LOCKED : - (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? - HA_OPEN_ABORT_IF_LOCKED : - HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) + if ((ha_err= (outparam->file-> + ha_open(index_file, + (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), + (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : + ((db_stat & HA_WAIT_IF_LOCKED) || + (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? + HA_OPEN_WAIT_IF_LOCKED : + (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? + HA_OPEN_ABORT_IF_LOCKED : + HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) { /* Set a flag if the table is crashed and it can be auto. repaired */ - share->crashed= ((err == HA_ERR_CRASHED_ON_USAGE) && + share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) && outparam->file->auto_repair() && !(ha_open_flags & HA_OPEN_FOR_REPAIR)); - if (err == HA_ERR_NO_SUCH_TABLE) + if (ha_err == HA_ERR_NO_SUCH_TABLE) { /* The table did not exists in storage engine, use same error message as if the .frm file didn't exist */ @@ -806,10 +815,10 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, } else { - outparam->file->print_error(err, MYF(0)); + outparam->file->print_error(ha_err, MYF(0)); error_reported= TRUE; } - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ } } share->db_low_byte_first= outparam->file->low_byte_first(); @@ -822,15 +831,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, #endif DBUG_RETURN (0); - err_w_init: - /* - Avoid problem with uninitialized data - Note that we don't have to initialize outparam->s here becasue - the caller will check if the pointer exists in case of errors - */ - bzero((char*) outparam,sizeof(*outparam)); - - err_not_open: + err: x_free((gptr) disk_buff); if (file > 0) VOID(my_close(file,MYF(MY_WME))); @@ -843,7 +844,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, outparam->file=0; // For easier errorchecking outparam->db_stat=0; hash_free(&share->name_hash); - free_root(&outparam->mem_root, MYF(0)); + free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR)); DBUG_RETURN (error); } /* openfrm */ diff --git a/strings/Makefile.am b/strings/Makefile.am index 508c127dcb4..62b20b56a8b 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -40,7 +40,6 @@ endif libmystrings_a_SOURCES = $(ASRCS) $(CSRCS) noinst_PROGRAMS = conf_to_src -DISTCLEANFILES = ctype_autoconf.c # Default charset definitions EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \ diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 218fc72ad17..804f87b2a5b 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -243,8 +243,10 @@ static int my_strnncoll_cp932(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_cp932(CHARSET_INFO *cs __attribute__((unused)), - const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *a, uint a_length, + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference + __attribute__((unused))) { const uchar *a_end= a + a_length; const uchar *b_end= b + b_length; @@ -291,7 +293,9 @@ static int my_strnxfrm_cp932(CHARSET_INFO *cs __attribute__((unused)), else *dest++ = sort_order_cp932[(uchar)*src++]; } - return srclen; + if (len > srclen) + bfill(dest, len - srclen, ' '); + return len; } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 1df81c88258..bb623ef66f1 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -791,31 +791,10 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), char *str, uint length, char **end, int *err) { - char end_char; - double result; - - errno= 0; /* Safety */ - - /* - The following define is to avoid warnings from valgrind as str[length] - may not be defined (which is not fatal in real life) - */ - -#ifdef HAVE_purify if (length == INT_MAX32) -#else - if (length == INT_MAX32 || str[length] == 0) -#endif - result= my_strtod(str, end); - else - { - end_char= str[length]; - str[length]= 0; - result= my_strtod(str, end); - str[length]= end_char; /* Restore end char */ - } - *err= errno; - return result; + length= 65535; /* Should be big enough */ + *end= str + length; + return my_strtod(str, end, err); } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 6bd93a93e8a..adfd4794e36 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -926,15 +926,16 @@ bs: return (negative ? -((longlong) res) : (longlong) res); } -double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), - char *nptr, uint length, - char **endptr, int *err) + +double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), + char *nptr, uint length, + char **endptr, int *err) { char buf[256]; double res; register char *b=buf; register const uchar *s= (const uchar*) nptr; - register const uchar *end; + const uchar *end; my_wc_t wc; int cnv; @@ -951,13 +952,10 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), break; /* Can't be part of double */ *b++= (char) wc; } - *b= 0; - errno= 0; - res=my_strtod(buf, endptr); - *err= errno; - if (endptr) - *endptr=(char*) (*endptr-buf+nptr); + *endptr= b; + res= my_strtod(buf, endptr, err); + *endptr= nptr + (uint) (*endptr- buf); return res; } diff --git a/strings/strtod.c b/strings/strtod.c index bc8105b8040..92d93612dd0 100644 --- a/strings/strtod.c +++ b/strings/strtod.c @@ -2,7 +2,7 @@ An alternative implementation of "strtod()" that is both simplier, and thread-safe. - From mit-threads as bundled with MySQL 3.23 + Original code from mit-threads as bundled with MySQL 3.23 SQL:2003 specifies a number as @@ -29,6 +29,8 @@ #include "my_base.h" /* Includes errno.h */ #include "m_ctype.h" +#define MAX_DBL_EXP 308 +#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232 static double scaler10[] = { 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90 }; @@ -37,89 +39,154 @@ static double scaler1[] = { }; -double my_strtod(const char *str, char **end) +/* + Convert string to double (string doesn't have to be null terminated) + + SYNOPSIS + my_strtod() + str String to convert + end_ptr Pointer to pointer that points to end of string + Will be updated to point to end of double. + error Will contain error number in case of error (else 0) + + RETURN + value of str as double +*/ + +double my_strtod(const char *str, char **end_ptr, int *error) { double result= 0.0; - int negative, ndigits; - const char *old_str; + uint negative= 0, ndigits, dec_digits= 0, pre_zero, neg_exp= 0; + int exp= 0; + const char *old_str, *end= *end_ptr, *start_of_number; + char next_char; my_bool overflow=0; - while (my_isspace(&my_charset_latin1, *str)) - str++; + *error= 0; + if (str >= end) + goto done; + while (my_isspace(&my_charset_latin1, *str)) + { + if (++str == end) + goto done; + } + + start_of_number= str; if ((negative= (*str == '-')) || *str=='+') - str++; + { + if (++str == end) + goto done; /* Could be changed to error */ + } + + /* Skip pre-zero for easier calculation of overflows */ + while (*str == '0') + { + if (++str == end) + goto done; + start_of_number= 0; /* Found digit */ + } old_str= str; - while (my_isdigit (&my_charset_latin1, *str)) + while ((next_char= *str) >= '0' && next_char <= '9') { - result= result*10.0 + (*str - '0'); - str++; - } - ndigits= str-old_str; - - if (*str == '.') - { - double p10=10; - str++; - old_str= str; - while (my_isdigit (&my_charset_latin1, *str)) + result= result*10.0 + (next_char - '0'); + if (++str == end) { - result+= (*str++ - '0')/p10; - p10*=10; + next_char= 0; /* Found end of string */ + break; } - ndigits+= str-old_str; - if (!ndigits) str--; + start_of_number= 0; /* Found digit */ } - if (ndigits && (*str=='e' || *str=='E')) + ndigits= (uint) (str-old_str); + + pre_zero= 0; + if (next_char == '.' && str < end-1) + { + double p10= 10; + old_str= ++str; + while (my_isdigit(&my_charset_latin1, (next_char= *str))) + { + result+= (next_char - '0')/p10; + if (!result) + pre_zero++; + else + p10*= 10; + if (++str == end) + { + next_char= 0; + break; + } + } + /* If we found just '+.' or '.' then point at first character */ + if (!(dec_digits= (uint) (str-old_str)) && start_of_number) + str= start_of_number; /* Point at '+' or '.' */ + } + if ((next_char == 'e' || next_char == 'E') && + dec_digits + ndigits != 0 && str < end-1) { - int exp= 0; - int neg= 0; const char *old_str= str++; - if ((neg= (*str == '-')) || *str == '+') + if ((neg_exp= (*str == '-')) || *str == '+') str++; - if (!my_isdigit (&my_charset_latin1, *str)) + if (str == end || !my_isdigit(&my_charset_latin1, *str)) str= old_str; else { - double scaler= 1.0; - while (my_isdigit (&my_charset_latin1, *str)) + do { - if (exp < 9999) /* protection against exp overflow */ + if (exp < 9999) /* protec against exp overfl. */ exp= exp*10 + *str - '0'; str++; - } - if (exp >= 1000) + } while (str < end && my_isdigit(&my_charset_latin1, *str)); + } + } + if ((exp= neg_exp ? exp + pre_zero : exp - pre_zero)) + { + double scaler; + if (exp < 0) + { + exp= -exp; + neg_exp= 1; /* neg_exp was 0 before */ + } + if (exp + ndigits >= MAX_DBL_EXP + 1 && result) + { + /* + This is not 100 % as we actually will give an owerflow for + 17E307 but not for 1.7E308 but lets cut some corners to make life + simpler + */ + if (exp + ndigits > MAX_DBL_EXP + 1 || + result >= MAX_RESULT_FOR_MAX_EXP) { - if (neg) - result= 0.0; - else + if (neg_exp) + result= 0.0; + else overflow= 1; goto done; } - while (exp >= 100) - { - scaler*= 1.0e100; - exp-= 100; - } - scaler*= scaler10[exp/10]*scaler1[exp%10]; - if (neg) - result/= scaler; - else - result*= scaler; } + scaler= 1.0; + while (exp >= 100) + { + scaler*= 1.0e100; + exp-= 100; + } + scaler*= scaler10[exp/10]*scaler1[exp%10]; + if (neg_exp) + result/= scaler; + else + result*= scaler; } done: - if (end) - *end = (char *)str; + *end_ptr= (char*) str; /* end of number */ if (overflow || isinf(result)) { result= DBL_MAX; - errno= EOVERFLOW; + *error= EOVERFLOW; } return negative ? -result : result; @@ -127,6 +194,7 @@ done: double my_atof(const char *nptr) { - return (my_strtod(nptr, 0)); + int error; + const char *end= nptr+65535; /* Should be enough */ + return (my_strtod(nptr, (char**) &end, &error)); } - diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index d25686f1c21..f7a47054658 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -48,7 +48,7 @@ thread_concurrency = 8 # Replication Master Server (default) # binary logging is required for replication -log-bin +log-bin=mysql-bin # required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host is not set @@ -108,7 +108,7 @@ server-id = 1 #master-port = # # binary logging - not required for slaves, but recommended -#log-bin +#log-bin=mysql-bin # Point the following paths to different dedicated disks #tmpdir = /tmp/ diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh index 062d106ce6a..b3f43272a7d 100644 --- a/support-files/my-innodb-heavy-4G.cnf.sh +++ b/support-files/my-innodb-heavy-4G.cnf.sh @@ -189,7 +189,7 @@ tmp_table_size = 64M # Enable binary logging. This is required for acting as a MASTER in a # replication configuration. You also need the binary log if you need # the ability to do point in time recovery from your latest backup. -log_bin +log-bin=mysql-bin # If you're using replication with chained slaves (A->B->C), you need to # enable this option on server B. It enables logging of updates done by diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index 59aca4b32f2..1e7d9f7aade 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -48,7 +48,7 @@ thread_concurrency = 8 # Replication Master Server (default) # binary logging is required for replication -log-bin +log-bin=mysql-bin # required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host is not set @@ -108,7 +108,7 @@ server-id = 1 #master-port = # # binary logging - not required for slaves, but recommended -#log-bin +#log-bin=mysql-bin # Point the following paths to different dedicated disks #tmpdir = /tmp/ diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh index 529740d59f0..99b6e823f39 100644 --- a/support-files/my-medium.cnf.sh +++ b/support-files/my-medium.cnf.sh @@ -46,7 +46,7 @@ myisam_sort_buffer_size = 8M # Replication Master Server (default) # binary logging is required for replication -log-bin +log-bin=mysql-bin # required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host is not set @@ -106,7 +106,7 @@ server-id = 1 #master-port = # # binary logging - not required for slaves, but recommended -#log-bin +#log-bin=mysql-bin # Point the following paths to different dedicated disks #tmpdir = /tmp/ diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index b2ecca6127e..288df893b4c 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -46,7 +46,7 @@ thread_stack = 64K server-id = 1 # Uncomment the following if you want to log updates -#log-bin +#log-bin=mysql-bin # Uncomment the following if you are NOT using BDB tables #skip-bdb diff --git a/support-files/mysql-log-rotate.sh b/support-files/mysql-log-rotate.sh index a1153c66f40..0ee78b0f7ca 100644 --- a/support-files/mysql-log-rotate.sh +++ b/support-files/mysql-log-rotate.sh @@ -1,4 +1,9 @@ -# This logname is set in mysql.server.sh that ends up in /etc/rc.d/init.d/mysql +# This logname can be set in /etc/my.cnf +# by setting the variable "err-log" +# in the [safe_mysqld] section as follows: +# +# [safe_mysqld] +# err-log=@localstatedir@/mysqld.log # # If the root user has a password you have to create a # /root/.my.cnf configuration file with the following @@ -22,8 +27,10 @@ compress postrotate # just if mysqld is really running - if test -n "`ps acx|grep mysqld`"; then - @bindir@/mysqladmin flush-logs + if test -x @bindir@/mysqladmin && \ + @bindir@/mysqladmin ping &>/dev/null + then + @bindir@/mysqladmin flush-logs fi endscript } diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index cb35b844ff4..b7330d1e5d7 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -27,7 +27,7 @@ Packager: Lenz Grimmer Vendor: MySQL AB Requires: fileutils sh-utils Provides: msqlormysql MySQL-server mysql -BuildPrereq: ncurses-devel +BuildRequires: ncurses-devel Obsoletes: mysql # Think about what you use here since the first step is to @@ -602,6 +602,10 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Fri Jan 14 2005 Lenz Grimmer + +- replaced obsoleted "BuildPrereq" with "BuildRequires" instead + * Thu Jan 13 2005 Lenz Grimmer - enabled the "Federated" storage engine for the max binary diff --git a/tests/client_test.c b/tests/client_test.c index 498b57fdeab..8be970aed29 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -9992,7 +9992,7 @@ static void test_bug3035() printf("%d", (int) bind->error_value); printf("\n"); } - DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0); DIE_UNLESS(int8_val == int8_max); DIE_UNLESS(uint8_val == uint8_max); @@ -11766,6 +11766,7 @@ static void test_bug6096() MYSQL_FIELD *query_field_list, *stmt_field_list; ulong query_field_count, stmt_field_count; int rc; + my_bool update_max_length= TRUE; uint i; myheader("test_bug6096"); @@ -11801,8 +11802,8 @@ static void test_bug6096() check_execute(stmt, rc); rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - rc= 1; - mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc); + mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, + (void*) &update_max_length); mysql_stmt_store_result(stmt); stmt_metadata= mysql_stmt_result_metadata(stmt); stmt_field_list= mysql_fetch_fields(stmt_metadata);