diff options
author | Michael Widenius <monty@askmonty.org> | 2010-11-24 00:09:54 +0200 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2010-11-24 00:09:54 +0200 |
commit | b16c389248d03f0c3de549884f607f3f191827b4 (patch) | |
tree | 6068b9d90b4127b1c3608e29913fa82bf1a1f20e | |
parent | 01b100b5dd3040daa18791abb88a9ffef06efe67 (diff) | |
parent | b52020221e8b4e58d1bc6dd5a5a6f065a6a3a083 (diff) | |
download | mariadb-git-b16c389248d03f0c3de549884f607f3f191827b4.tar.gz |
Automerge with 5.1
525 files changed, 12279 insertions, 4738 deletions
diff --git a/BUILD/build_mccge.sh b/BUILD/build_mccge.sh index f04caef8df8..81dbebff32d 100755 --- a/BUILD/build_mccge.sh +++ b/BUILD/build_mccge.sh @@ -63,41 +63,50 @@ sysadmin_usage() cat <<EOF This script can be used to build MySQL Cluster Carrier Grade Edition - based on a source code release you received from MySQL. + based on a source code release you received from MySQL. It can also + be used to build many variants other variants of MySQL, in particular + various performance-optimised versions of MySQL. It is assumed that you are building on a computer which is of the - same type as that on which you intend to run MySQL Cluster. + same type as that on which you intend to run MySQL/MySQL Cluster. The simplest possible way to run this script is to allow it to use the - built-in defaults everywhere, invoking it simply as: + built-in defaults everywhere, invoking it simply as (from top-level + MySQL directory): - shell> ./build_mccge.sh + shell> BUILD/build_mccge.sh This performs the following operations: 1) Detects the operating system. Currently, Linux, FreeBSD, Solaris - 10/11, and Mac OS X are supported by this script. + 8/9/10/11, and Mac OS X are supported by this script. 2) Detect the type of CPU being used. Currently supported processors are: x86 for all supported operating systems, Itanium for Linux - with GCC, and SPARC for Solaris using the Forte compiler. + with GCC, and x86 + SPARC for Solaris using the Forte compiler and + finally x86 on Linux using the Intel compiler. 3) Invokes the GCC compiler. - 4) Builds a set of MySQL Cluster Carrier Grade Edition binaries; for + 4) Builds a set of MySQL/MySQL Cluster binaries; for more information about these, see --extended-help. + 5) Default compiler is always gcc. The default version assumes that you have a source code tarball from which you are building, and thus autoconf and automake do not need to be run. If you have downloaded a BitKeeper tree then you should read --developer-help. - If you are building MySQL Cluster Carrier Grade Edition for commercial + If you are building MySQL/MySQL Cluster for commercial use then you need to set the --commercial flag to ensure that the commercial libraries are compiled in, rather than the GPL-only libraries. The default is to build a GPL version of MySQL Cluster Carrier Grade Edition. - If your building on a Solaris SPARC machine you must set + If your building on a Solaris SPARC machine and you want to compile + using SunStudio you must set --compiler=forte; if you want to build using the Intel compiler on Linux, you need to set --compiler=icc. + A synonym for forte is SunStudio, so one can also use + --compiler=SunStudio. + If you want to make sure that a 64-bit version is built then you should add the flag --64. This is always set on Solaris machines and when check-cpu is able to discover that a 64-bit CPU is being used. If @@ -120,7 +129,7 @@ cat <<EOF information in the binary then use --debug. If your aim is not to build MySQL Cluster Carrier Grade Edition, you - can also use this script to build MySQL Classic and MySQL Pro + can also use this script to build MySQL Classic and MySQL Enterprise Pro versions; see the --extended-help for descriptions of these packages. EOF } @@ -133,13 +142,20 @@ Usage: $0 [options] --help Show this help message. --sysadmin-help Show help for system administrators wishing to build MySQL Cluster Carrier Grade Edition + or other MySQL versions. --developer-help Show help for developers trying to build MySQL --with-help Show extended help on --with-xxx options to configure --extended-help Show extended help message --without-debug Build non-debug version + --use-comment Set the comment in the build + --with-fast-mutexes Use try/retry method of acquiring mutex --with-debug Build debug version --with-debug=full Build with full debug. + --with-link-time-optimizer + Link time optimizations enabled (Requires GCC 4.5 + if GCC used), available for icc as well. This flag + is only considered if also fast is set. --configure-only Stop after running configure. --use-autotools Start by running autoconf, automake,.. tools --no-autotools Start from configure @@ -155,10 +171,10 @@ Usage: $0 [options] MySQL use --commercial Use commercial libraries --gpl Use gpl libraries - --compiler=[gcc|icc|forte] Select compiler - --cpu=[x86|x86_64|sparc] Select CPU type - x86 => 32-bit binary - x86_64 => 64 bit binary unless Mac OS X + --compiler=[gcc|icc|forte|SunStudio] Select compiler + --cpu=[x86|x86_64|sparc|itanium] Select CPU type + x86 => x86 and 32-bit binary + x86_64 => x86 and 64 bit binary --warning-mode=[extra|pedantic|normal|no] Set warning mode level --warnings Set warning mode to normal --32 Build a 32-bit binary even if CPU is 64-bit @@ -170,8 +186,9 @@ Usage: $0 [options] --error-inject Enable error injection into MySQL Server and data nodes --valgrind Build with valgrind - --fast Optimise for CPU architecture buildt on + --fast Optimise for CPU architecture built on --static-linking Statically link system libraries into binaries + --use-tcmalloc Link with tcmalloc instead of standard malloc (Linux only) --with-flags * Pass extra --with-xxx options to configure EOF if test "x$1" != "x" ; then @@ -186,13 +203,14 @@ extended_usage() Extended help text for this script: ----------------------------------- This script is intended to make it easier for customers using MySQL - Cluster Carrier Grade Edition to build the product from source on - these platforms/compilers: Linux/x86 (32-bit and 64-bit), - Solaris 10 and 11/x86/gcc, Solaris 9/Sparc/Forte, and MacOSX/x86/gcc. - The script automatically detects CPU type and operating system; in - most cases this also determines which compiler to use, the exception - being Linux/x86 where you can choose between gcc and icc (gcc is the - default). + Cluster Carrier Grade Edition, customers using performance-optimised + MySQL versions and developers to build the product from source on + these platforms/compilers: Linux/x86 (32-bit and 64-bit) (either using + gcc or icc), Linux Itanium, Solaris 8,9,10 and 11 x86 and SPARC using + gcc or SunStudio and MacOSX/x86/gcc. + + The script automatically detects CPU type and operating system; The + default compiler is always gcc. To build on other platforms you can use the --print-only option on a supported platform and edit the output for a proper set of commands on @@ -213,7 +231,7 @@ extended_usage() --package=cge storage engines: - ARCHIVE, BLACKHOLE, CSV, EXAMPLE, FEDERATED, MYISAM, NDB + ARCHIVE, BLACKHOLE, CSV, FEDERATED, MYISAM, NDB (All storage engines except InnoDB) comment: MySQL Cluster Carrier Grade Edition GPL/Commercial version built from source @@ -221,7 +239,7 @@ extended_usage() --package=extended storage engines: - ARCHIVE, BLACKHOLE, CSV, EXAMPLE, FEDERATED, MYISAM, INNODB, NDB + ARCHIVE, BLACKHOLE, CSV, FEDERATED, MYISAM, INNODB, NDB (All storage engines) comment: MySQL Cluster Carrier Grade Extended Edition GPL/Commercial version built from source @@ -229,7 +247,7 @@ extended_usage() --package=pro storage engines: - ARCHIVE, BLACKHOLE, CSV, EXAMPLE, FEDERATED, INNODB, MYISAM + ARCHIVE, BLACKHOLE, CSV, FEDERATED, INNODB, MYISAM (All storage engines except NDB) comment: MySQL Pro GPL/Commercial version built from source @@ -291,11 +309,16 @@ extended_usage() by MySQL (cannot be overridden). --with-ssl: Enable use of yaSSL library included in the MySQL source + if possible (GCC and same CC and CXX). (cannot be overridden). --with-pic: Build all binaries using position independent assembler to avoid problems with dynamic linkers (cannot be overridden). + --without-example-engine: Ensure that the example engine isn't built, + it cannot do any useful things, it's merely intended as documentation. + (cannot be overridden) + --with-csv-storage-engine: Ensure that the CSV storage engine is included in all builds. Since CSV is required for log tables in MySQL 5.1, this option cannot be overridden. @@ -314,10 +337,6 @@ extended_usage() In addition there are some configure options that are specific to Linux operating systems: - --with-fast-mutexes - Include an alternative implementation of mutexes that is faster on - Linux systems - --enable-assembler Include assembler code optimisations for a number of mostly string methods. Used for x86 processors only. @@ -364,17 +383,24 @@ extended_usage() --with-mysqld-libs=-lmtmalloc Used on Solaris to ensure that the proper malloc library is used. + Investigations have shown mtmalloc to be the best choice on Solaris, + also umem has good performance on Solaris but better debugging + capabilities. Compiler options: ----------------- - This section describes the compiler options for each of the different - platforms supported by thisscript. + This section describes the compiler options for each of the different + platforms supported by this script. + + The --fast option adds -mtune=cpu_arg to the C/C++ flags (provides + support for Nocona, K8, and other processors). - The --fast option adds -mtune=cpu_arg to the C/C++ flags (provides - support for Nocona, K8, and other processors). + Use of the --debug option adds -g to the C/C++ flags. - Use of the --debug option adds -g to the C/C++ flags. + In all cases it is possible to override the definition of CC and CXX + by calling the script as follows: + CC="/usr/local/bin/gcc" CXX="/usr/local/bin/gcc" BUILD/build_mccge.sh FreeBSD/x86/gcc --------------- @@ -383,8 +409,7 @@ extended_usage() Linux/x86+Itanium/gcc ------------- - No flags are used. Instead the configure script determines the - proper flags to use for both normal and debug builds. Discovery of a + For debug builds -O is used and otherwise -O3 is used.Discovery of a Nocona or Core 2 Duo CPU causes a 64-bit binary to be built; otherwise, the binary is 32-bit. To build a 64-bit binary, -m64 is added to the C/C++ flags. (To build a 32-bit binary on a 64-bit CPU, @@ -393,48 +418,105 @@ extended_usage() Linux/x86+Itanium/icc ------------- Flags used: - CC = icc -static-libgcc -static-libcxa -i-static - C++ = icpc -static-libgcc -static-libcxa -i-static + CC = icc -static-libgcc -static-intel + C++ = icpc -static-libgcc -static-intel C/C++ flags = -mp -restrict - On Itanium we also add -no-ftz and -no-prefetch to CC and C++ flags. + On Itanium we also add -no-ftz and to CC and C++ flags. - The non-debug versions also add the following: - C/C++ flags += -O3 unroll2 -ip + Note that if the user of this script sets CC or CXX explicitly then + also -static-libgcc and -static-intel needs to be set in the CC and + CXX. - The fast version adds: - C/C++ flags += -ipo + The non-debug versions also add the following: + C/C++ flags += -O3 unroll2 -ip - On discovery of a Core 2 Duo architecture while using icc, -xT is also - added to the C/C++ flags; this provides optimisations specific to Core - 2 Duo. This is added only when the --fast flag is set. + The fast version adds (if --with-link-time-optimizer is used): + C/C++ flags += -ipo + + On discovery of a Core 2 Duo architecture while using icc, -xT is also + added to the C/C++ flags; this provides optimisations specific to Core + 2 Duo. This is added only when the --fast flag is set. Solaris/x86/gcc --------------- - All builds on Solaris are 64-bit, so -m64 is always used in the - C/C++ flags. LDFLAGS is set to -m64 -static-libgcc -O/-O2. + All builds on Solaris are by default 64-bit, so -m64 is always used in + the C/C++ flags. LDFLAGS is set to -m64 -O/-O2/-O3. If for + some reason a 32-bit Solaris is used it is necessary to add the flag + --32 to the script invocation. Due to bugs in compiling with -O3 on + Solaris only -O2 is used by default, when --fast flag is used -O3 will + be used instead. + + Sets -m64 (default) or -m32 (if specifically set) in LDFLAGS and + C/C++ flags. Solaris/Sparc/Forte ------------------- - Uses cc-5.0 as CC - Sets ASFLAGS=LDFLAGS=xarch=v9, so that we compile Sparc v9 binaries - C flags = -Xa -strconst -xc99=none + Uses cc as CC and CC as CXX + Note that SunStudio uses different binaries for C and C++ compilers. + + Set -m64 (default) or -m32 (if specifically set) in ASFLAGS, + LDFLAGS and C/C++ flags. + + Sets ASFLAGS=LDFLAGS=compiler flags=xarch=sparc, so that we compile + Sparc v9 binaries, also -mt is set in all those since we're always + building a multithreaded program. + + C flags = -xstrconst This flag is set only on SPARC C++ flags = -noex - C/C++ flags = -mt -D_FORTEC -xarch=v9 - For non-debug builds, the following flags are also used: + Set the following C/C++ flags: + -fsimple=1 + -ftrap=%none + -nofstore This flag is set only on x86 + -xbuiltin=%all + -xlibmil + -xlibmopt - C/C++ flags = -xO3 + Set the C++ flag: + -noex + -features=no%except This flag is set only on x86 + + When compiling with fast we set (-ipo only used if we have + set --with-link-time-optimizer): + C/C++ flags: -xtarget=native -xunroll=3 -xipo + LDFLAGS: -xipo + + When not compiling with fast we always set -xtarget=generic + + When compiling with fast on SPARC we also set: + C/C++ flags: -xbinopt=prepare + LDFLAGS: -xbinopt=prepare + + When compiling with fast on x86 we also set: + C/C++ flags: -xregs=frameptr + When not compiling with fast we set on x86 + C/C++ flags: -xregs=no%frameptr + + On SPARC we set + ASFLAGS = LDFLAGS = C/C++ flags = -xarch=sparc + + The optimisation level is + -xO Debug builds + -xO2 Production build on SPARC + -xO3 Production build on x86 + -xO4 Fast builds on SPARC/x86 MacOSX/x86/gcc -------------- - C/C++ flags include -fno-common -arch i386. + C/C++ flags include -fno-common -arch i386. + When 64-bits builds then i386 is replaced by x86_64. - Non-debug versions also add -Os -felide-constructors, where "-Os" - means the build is space-optimised as long as the space optimisations - do not negatively affect performance. Debug versions use -O. + Non-debug versions also add -Os -felide-constructors, where "-Os" + means the build is space-optimised as long as the space optimisations + do not negatively affect performance. Debug versions use -O. + + Mac OS X builds will always be 32-bit by default, when --64 is added + the build will be 64 bit instead. Thus the flag --m64 is added only + when specifically given as an option. EOF } + with_usage() { cat <<EOF @@ -495,7 +577,7 @@ parse_package() package="pro" ;; extended ) - package="" + package="extended" ;; cge ) package="cge" @@ -537,11 +619,15 @@ parse_cpu_type() case "$cpu_type" in x86 ) cpu_type="x86" - m32="yes" + if test "x$m64" = "x" ; then + m64="no" + fi ;; x86_64 ) cpu_type="x86" - m64="yes" + if test "x$m64" = "x" ; then + m64="yes" + fi ;; itanium ) cpu_type="itanium" @@ -569,7 +655,7 @@ parse_compiler() icc ) compiler="icc" ;; - forte ) + forte | SunStudio | sunstudio ) compiler="forte" ;; *) @@ -590,6 +676,9 @@ parse_options() --datadir=*) datadir=`get_key_value "$1"` ;; + --with-link-time-optimizer) + with_link_time_optimizer="yes" + ;; --with-debug=full) full_debug="=full" with_debug_flag="yes" @@ -601,6 +690,15 @@ parse_options() fast_flag="generic" fi ;; + --use-comment) + without_comment="no" + ;; + --with-fast-mutexes) + with_fast_mutexes="yes" + ;; + --use-tcmalloc) + use_tcmalloc="yes" + ;; --with-debug) with_debug_flag="yes" fast_flag="no" @@ -636,17 +734,19 @@ parse_options() warning_mode="normal" ;; --32) - if test "x$m64" != "x" ; then + if test "x$explicit_size_set" != "x" ; then echo "Cannot set both --32 and --64" exit 1 fi - m32="yes" + explicit_size_set="yes" + m64="no" ;; --64) - if test "x$m32" != "x" ; then + if test "x$explicit_size_set" != "x" ; then echo "Cannot set both --32 and --64" exit 1 fi + explicit_size_set="yes" m64="yes" ;; --package=*) @@ -750,13 +850,15 @@ set_cpu_base() if test "x$cpu_type" = "x" ; then if test "x$cpu_arg" = "x" ; then usage "CPU type not discovered, cannot proceed" - return 1 + exit 1 fi case "$cpu_arg" in core2 | nocona | prescott | pentium* | i*86 ) + # Intel CPU cpu_base_type="x86" ;; - athlon* | opteron* ) + athlon* | opteron* | k6 | k8 ) + # AMD CPU cpu_base_type="x86" ;; sparc ) @@ -775,18 +877,20 @@ set_cpu_base() check_cpu_cflags="" fi if test "x$os" = "xMacOSX" ; then - m64="no" + if test "x$m64" = "x" ; then + m64="no" + fi elif test "x$os" = "xSolaris" ; then - m64="yes" - elif test "x$m32" = "x" ; then + if test "x$m64" = "x" ; then + m64="yes" + fi + elif test "x$m64" = "x" ; then if test "x$cpu_arg" = "xnocona" || test "x$cpu_arg" = "xcore2" || \ test "x$cpu_arg" = "xathlon64" || test "x$cpu_arg" = "xopteron" ; then m64="yes" - elif test "x$m64" != "xyes" ; then + else m64="no" fi - else - m64="no" fi echo "Discovered CPU of type $cpu_base_type ($cpu_arg) on $os" if test "x$m64" = "xyes" ; then @@ -806,18 +910,15 @@ init_configure_commands() cxxflags="$cxx_warnings $base_cxxflags $compiler_flags" configure="./configure $base_configs $with_flags" - commands="$commands - CC=\"$CC\" CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\"" + env_flags="CC=\"$CC\" CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\"" if test "x$LDFLAGS" != "x" ; then - commands="$commands - LDFLAGS=\"$LDFLAGS\"" + env_flags="$env_flags LDFLAGS=\"$LDFLAGS\"" fi if test "x$ASFLAGS" != "x" ; then - commands="$commands - ASFLAGS=\"$ASFLAGS\"" + env_flags="$env_flags ASFLAGS=\"$ASFLAGS\"" fi commands="$commands - $configure" + $env_flags $configure" } # @@ -920,7 +1021,7 @@ set_libtoolize_version() # We do not use ccache when gcov is used. Also only when # gcc is used. # -set_up_ccache() +set_ccache_usage() { if test "x$compiler" = "xgcc" ; then if ccache -V > /dev/null 2>&1 && test "$USING_GCOV" != "1" @@ -994,7 +1095,7 @@ set_with_debug_flags() if test "x$with_debug_flag" = "xyes" ; then if test "x$developer_flag" = "xyes" ; then loc_debug_flags="-DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS " - loc_debug_flags="$loc_debug_cflags -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC" + loc_debug_flags="$loc_debug_flags -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC" compiler_flags="$compiler_flags $loc_debug_flags" fi fi @@ -1024,6 +1125,18 @@ set_debug_flag() } # +# We compile in SSL support if we can, this isn't possible if CXX +# and CC aren't the same and we're not using GCC. +# +set_ssl() +{ + if test "x$compiler" = "xgcc" && \ + test "x$CC" = "x$CXX" ; then + base_configs="$base_configs --with-ssl" + fi +} + +# # Base options used by all packages # # SSL library to use. --with-ssl selects the bundled yaSSL @@ -1048,9 +1161,12 @@ set_base_configs() base_configs="$base_configs --enable-thread-safe-client" base_configs="$base_configs --with-big-tables" base_configs="$base_configs --with-extra-charsets=all" - base_configs="$base_configs --with-ssl" + if test "x$with_fast_mutexes" = "xyes" ; then + base_configs="$base_configs --with-fast-mutexes" + fi base_configs="$base_configs --with-pic" base_configs="$base_configs --with-csv-storage-engine" + base_configs="$base_configs --with-perfschema" } # @@ -1060,18 +1176,30 @@ set_base_configs() # set_base_engines() { - engine_configs="$engine_configs --with-archive-storage-engine" + engine_configs="--with-archive-storage-engine" engine_configs="$engine_configs --with-blackhole-storage-engine" - engine_configs="$engine_configs --with-example-storage-engine" + engine_configs="$engine_configs --without-example-storage-engine" engine_configs="$engine_configs --with-federated-storage-engine" engine_configs="$engine_configs --with-partition" + base_configs="$base_configs $engine_configs" } -set_pro_package() +set_innodb_engine() { - base_configs="$base_configs $engine_configs" base_configs="$base_configs --with-innodb" - base_configs="$base_configs --with-comment=\"MySQL Pro $version_text built from source\"" +} + +set_ndb_engine() +{ + base_configs="$base_configs --with-ndbcluster" + base_configs="$base_configs --without-ndb-debug" +} + +set_pro_package() +{ + if test "x$without_comment" != "xyes" ; then + base_configs="$base_configs --with-comment=\"MySQL Enterprise Pro $version_text built from source\"" + fi if test "x$with_debug_flag" = "xyes" ; then base_configs="$base_configs --with-server-suffix=\"-debug\"" fi @@ -1079,40 +1207,37 @@ set_pro_package() set_cge_extended_package() { - if test "x$gpl" = "xno" ; then - echo "Cannot build Extended Carrier Grade Edition as Commercial version" + if test "x$without_comment" != "xyes" ; then + base_configs="$base_configs --with-comment=\"MySQL Cluster Carrier Grade Extended Edition $version_text built from source\"" fi - base_configs="$base_configs --with-ndbcluster" - base_configs="$base_configs --without-ndb-debug" - base_configs="$base_configs $engine_configs" - base_configs="$base_configs --with-innodb" - base_configs="$base_configs --with-comment=\"MySQL Cluster Carrier Grade Extended Edition $version_text built from source\"" if test "x$with_debug_flag" = "xyes" ; then base_configs="$base_configs --with-server-suffix=\"-cge-extended-debug\"" else - base_configs="$base_configs --with-server-suffix=\"-cge-extended"\" + base_configs="$base_configs --with-server-suffix=\"-cge-extended\"" fi } set_cge_package() { - base_configs="$base_configs --with-ndbcluster" - base_configs="$base_configs --without-ndb-debug" - base_configs="$base_configs $engine_configs" - base_configs="$base_configs --with-comment=\"MySQL Cluster Carrier Grade Edition $version_text built from source\"" + if test "x$without_comment" != "xyes" ; then + base_configs="$base_configs --with-comment=\"MySQL Cluster Carrier Grade Edition $version_text built from source\"" + fi if test "x$with_debug_flag" = "xyes" ; then base_configs="$base_configs --with-server-suffix=\"-cge-debug\"" else - base_configs="$base_configs --with-server-suffix=\"-cge"\" + base_configs="$base_configs --with-server-suffix=\"-cge\"" fi } set_classic_package() { - base_configs="$base_configs --with-comment=\"MySQL Classic $version_text built from source\"" + if test "x$without_comment" != "xyes" ; then + base_configs="$base_configs --with-comment=\"MySQL Classic $version_text built from source\"" + fi if test "x$with_debug_flag" = "xyes" ; then base_configs="$base_configs --with-server-suffix=\"-debug\"" fi + base_configs="$base_configs --without-example-storage-engine" } # @@ -1140,6 +1265,36 @@ set_gcc_special_options() fi } +set_cc_and_cxx_for_gcc() +{ + if test "x$CC" = "x" ; then + CC="gcc -static-libgcc -fno-exceptions" + fi + if test "x$CXX" = "x" ; then + CXX="gcc -static-libgcc -fno-exceptions" + fi +} + +set_cc_and_cxx_for_icc() +{ + if test "x$CC" = "x" ; then + CC="icc -static-intel -static-libgcc" + fi + if test "x$CXX" = "x" ; then + CXX="icpc -static-intel -static-libgcc" + fi +} + +set_cc_and_cxx_for_forte() +{ + if test "x$CC" = "x" ; then + CC="cc" + fi + if test "x$CXX" = "x" ; then + CXX="CC" + fi +} + # # If we discover a Core 2 Duo architecture and we have enabled the fast # flag, we enable a compile especially optimised for Core 2 Duo. This @@ -1167,42 +1322,116 @@ set_bsd_configs() exit 1 fi base_configs="$base_configs --enable-assembler" - CC="gcc" - CXX="gcc" + if test "x$fast_flag" != "xno" ; then + compiler_flags="$compiler_flags -O3" + else + compiler_flags="$compiler_flags -O0" + fi + set_cc_and_cxx_for_gcc +} + +check_64_bits() +{ + echo "Checking for 32/64-bits compilation" + echo "int main() { return 0; }" > temp_test.c + if test "x$m64" = "xyes" ; then + cmd="$CC $compile_flags -m64 temp_test.c" + if ! $cmd 2>1 ; then + m64="no" + echo "Changing to 32-bits since 64-bits didn't work" + else + echo "Will use 64-bits" + fi + else + cmd="$CC $compile_flags -m32 temp_test.c" + if ! $cmd 2>1 ; then + m64="yes" + echo "Changing to 64-bits since 32-bits didn't work" + else + echo "Will use 32-bits" + fi + fi + rm temp_test.c } # +# Get GCC version +# +get_gcc_version() +{ + # check if compiler is gcc and dump its version + cc_verno=`$cc -dumpversion 2>/dev/null` + if test "x$?" = "x0" ; then + set -- `echo $cc_verno | tr '.' ' '` + cc_ver="GCC" + cc_major=$1 + cc_minor=$2 + cc_patch=$3 + gcc_version=`expr $cc_major '*' 100 '+' $cc_minor` + fi +} + +# +# Link Time Optimizer in GCC (LTO) uses a parameter -flto +# which was added to GCC 4.5, if --with-link-time-optimizer +# is set then use this feature +# +check_for_link_time_optimizer() +{ + get_gcc_version + if test "$gcc_version" -ge 405 && \ + test "x$with_link_time_optimizer" = "xyes" ; then + compiler_flags="$compiler_flags -flto" + LDFLAGS="$LDFLAGS -flto" + fi +} +# # Linux Section # set_linux_configs() { if test "x$cpu_base_type" != "xx86" && \ test "x$cpu_base_type" != "xitanium" ; then - usage "Only x86 and Itanium CPUs supported for 32-bit Linux" + usage "Only x86 and Itanium CPUs supported for Linux" exit 1 fi - base_configs="$base_configs --with-fast-mutexes" + if test "x$use_tcmalloc" = "xyes" ; then + base_configs="$base_configs --with-mysqld-libs=-ltcmalloc_minimal" + fi if test "x$cpu_base_type" = "xx86" ; then base_configs="$base_configs --enable-assembler" fi if test "x$compiler" = "xgcc" ; then - CC="gcc" - CXX="gcc" + set_cc_and_cxx_for_gcc + if test "x$fast_flag" != "xno" ; then + if test "x$fast_flag" = "xyes" ; then + compiler_flags="$compiler_flags -O3" + check_for_link_time_optimizer + else + compiler_flags="$compiler_flags -O2" + fi + else + compiler_flags="$compiler_flags -O0" + fi + check_64_bits if test "x$m64" = "xyes" ; then compiler_flags="$compiler_flags -m64" + else + compiler_flags="$compiler_flags -m32" fi # configure will set proper compiler flags for gcc on Linux elif test "x$compiler" = "xicc" ; then compiler_flags="$compiler_flags -mp -restrict" - CC="icc -static-intel" - CXX="icpc -static-intel" + set_cc_and_cxx_for_icc if test "x$cpu_base_type" = "xitanium" ; then compiler_flags="$compiler_flags -no-ftz" fi if test "x$fast_flag" != "xno" ; then compiler_flags="$compiler_flags -O3 -unroll2 -ip" - if test "x$fast_flag" = "xyes" ; then + if test "x$fast_flag" = "xyes" && \ + test "x$with_link_time_optimizer" = "xyes" ; then compiler_flags="$compiler_flags -ipo" + LDFLAGS="$LDFLAGS -ipo" fi fi else @@ -1216,53 +1445,111 @@ set_linux_configs() # set_solaris_configs() { - base_configs="$base_configs --with-mysqld-libs=-lmtmalloc" +# Use mtmalloc as malloc, see Tim Cook blog +# For information on optimal compiler settings, see article at +# http://developers.sun.com/solaris/articles/mysql_perf_tune.html +# by Luojia Chen at Sun. + base_configs="$base_configs --with-named-curses=-lcurses" case "`uname -a`" in - *5.10*|*5.11*) + *5.8* | *5.9* ) + ;; + + *5.10* | *5.11*) + base_configs="$base_configs --with-mysqld-libs=-lmtmalloc" ;; *) - die "Only versions 10 and 11 supported for Solaris" + usage "Only versions 8,9, 10 and 11 supported for Solaris" + exit 1 esac if test "x$cpu_base_type" != "xx86" && \ test "x$cpu_base_type" != "xsparc" ; then usage "Only x86 and Sparc CPUs supported for Solaris" exit 1 fi + if test "x$compiler" != "xgcc" && \ + test "x$compiler" != "xforte" ; then + usage "Only gcc and Forte compilers supported for Solaris" + exit 1 + fi + if test "x$m64" = "xyes" ; then + compiler_flags="$compiler_flags -m64" + LDFLAGS="-m64" + ASFLAGS="$ASFLAGS -m64" + else + compiler_flags="$compiler_flags -m32" + LDFLAGS="-m32" + ASFLAGS="$ASFLAGS -m32" + fi if test "x$compiler" = "xgcc" ; then - CC="gcc" - CXX="gcc" + set_cc_and_cxx_for_gcc if test "x$cpu_base_type" != "xx86" ; then - usage "Only gcc supported for Solaris 10/11 on SPARC" + usage "gcc currently not supported for Solaris on SPARC" + exit 1 fi - compiler_flags="$compiler_flags -m64 -DMY_ATOMIC_MODE_RWLOCKS" - LDFLAGS="-m64 -static-libgcc" - if test "x$fast_flag" != "xno" ; then - LDFLAGS="$LDFLAGS -O2" - compiler_flags="$compiler_flags -O2" + if test "x$fast_flag" = "xyes" ; then + LDFLAGS="$LDFLAGS -O3" + compiler_flags="$compiler_flags -O3" + check_for_link_time_optimizer else - LDFLAGS="$LDFLAGS -O" - compiler_flags="$compiler_flags -O" - fi - elif test "x$compiler" = "xforte" ; then - if test "x$cpu_base_type" = "xx86" ; then - usage "Only gcc supported for Solaris/x86" + if test "x$fast_flag" = "xgeneric" ; then + LDFLAGS="$LDFLAGS -O2" + compiler_flags="$compiler_flags -O2" + else + LDFLAGS="$LDFLAGS -O0" + compiler_flags="$compiler_flags -O0" + fi fi - if test "x$cpu_base_type" != "xsparc" ; then - usage "Forte compiler supported for Solaris 9/SPARC only" + else +#Using Forte compiler (SunStudio) + set_cc_and_cxx_for_forte + compiler_flags="$compiler_flags -mt" + LDFLAGS="$LDFLAGS -mt" + compiler_flags="$compiler_flags -fsimple=1" + compiler_flags="$compiler_flags -ftrap=%none" + compiler_flags="$compiler_flags -xbuiltin=%all" + compiler_flags="$compiler_flags -xlibmil" + compiler_flags="$compiler_flags -xlibmopt" + if test "x$fast_flag" = "xyes" ; then + compiler_flags="$compiler_flags -xtarget=native" + compiler_flags="$compiler_flags -xunroll=3" + if test "x$with_link_time_optimizer" = "xyes" ; then + compiler_flags="$compiler_flags -xipo" + LDFLAGS="$LDFLAGS -xipo" + fi + else + compiler_flags="$compiler_flags -xtarget=generic" fi - CC="cc-5.0" - CXX=CC - ASFLAGS="xarch=v9" - LDFLAGS="xarch=v9" - base_cflags="$base_cflags -Xa -xstrconst -xc99=none" - base_cxxflags="$base_cxxflags -noex" - compiler_flags="$compiler_flags -mt -D_FORTEC -xarch=v9" - if test "x$fast_flag" != "xno" ; then - compiler_flags="$compiler_flags -xO3" + if test "x$cpu_base_type" = "xx86" ; then + compiler_flags="$compiler_flags -nofstore" + base_cxx_flags="$base_cxx_flags -features=no%except" + if test "x$fast_flag" = "xyes" ; then + compiler_flags="$compiler_flags -xregs=frameptr" + compiler_flags="$compiler_flags -xO4" + else + compiler_flags="$compiler_flags -xregs=no%frameptr" + if test "x$fast_flag" = "xgeneric" ; then + compiler_flags="$compiler_flags -xO2" + else + compiler_flags="$compiler_flags -xO0" + fi + fi + else +#Using SPARC cpu with SunStudio (Forte) compiler + ASFLAGS="$ASFLAGS -xarch=sparc" + LDFLAGS="$LDFLAGS -xarch=sparc" + base_cxxflags="$base_cxxflags -noex" + base_cflags="$base_cflags -xstrconst" + compiler_flags="$compiler_flags -xarch=sparc" + if test "x$fast_flag" = "xyes" ; then + compiler_flags="$compiler_flags -xbinopt=prepare" + LDFLAGS="$LDFLAGS -xbinopt=prepare" + compiler_flags="$compiler_flags -xO4" + elif test "x$fast_flag" = "xgeneric" ; then + compiler_flags="$compiler_flags -xO3" + else + compiler_flags="$compiler_flags -xO0" + fi fi - else - usage "Only gcc and Forte compilers supported for Solaris" - exit 1 fi } @@ -1271,10 +1558,7 @@ set_solaris_configs() # set_macosx_configs() { - base_cxxflags="$base_cxxflags -fno-common" - if test "x$cpu_base_type" = "xx86" && test "x$compiler" = "xgcc" ; then - compiler_flags="$compiler_flags -arch i386" - else + if test "x$cpu_base_type" != "xx86" || test "x$compiler" != "xgcc" ; then usage "Only gcc/x86 supported for Mac OS X" exit 1 fi @@ -1282,14 +1566,21 @@ set_macosx_configs() # Optimize for space as long as it doesn't affect performance, use some # optimisations also when not in fast mode. # + base_cxxflags="$base_cxxflags -felide-constructors" + compiler_flags="$compiler_flags -fno-common" + if test "x$m64" = "xyes" ; then + compiler_flags="$compiler_flags -m64" + compiler_flags="$compiler_flags -arch x86_64" + else + compiler_flags="$compiler_flags -m32" + compiler_flags="$compiler_flags -arch i386" + fi if test "x$fast_flag" != "xno" ; then compiler_flags="$compiler_flags -Os" - base_cxxflags="$base_cxxflags -felide-constructors" else - compiler_flags="$compiler_flags -O" + compiler_flags="$compiler_flags -O0" fi - CC="gcc" - CXX="gcc" + set_cc_and_cxx_for_gcc } # @@ -1370,7 +1661,7 @@ fi cpu_type= package= prefix="/usr/local/mysql" -parallelism="4" +parallelism="8" fast_flag="generic" compiler="gcc" gpl="yes" @@ -1398,11 +1689,19 @@ base_cxxflags= base_configs= debug_flags= cxxflags= -m32= m64= +explicit_size_set= datadir= commands= use_autotools= +engine_configs= +ASFLAGS= +LDFLAGS= +use_tcmalloc= +without_comment="yes" +with_fast_mutexes= +with_link_time_optimizer= +gcc_version="0" set_defaults_based_on_environment @@ -1419,7 +1718,14 @@ set -e # This call sets the cpu_arg and check_cpu_args parameters # path=`dirname $0` +if test "x$compiler" = "xgcc" ; then + compiler= +fi . "$path/check-cpu" +if test "x$compiler" = "x" ; then + compiler="gcc" +fi +check_os set_cpu_base if test "x$?" = "x1" ; then exit 1 @@ -1447,17 +1753,23 @@ set_icc_special_options # including all storage engines except InnoDB, and to use GPL libraries. # set_base_configs -set_base_engines if test "x$gpl" = "xyes" ; then version_text="GPL version" else version_text="Commercial version" fi if test "x$package" = "xpro" ; then + set_base_engines + set_innodb_engine set_pro_package elif test "x$package" = "xextended" ; then + set_base_engines + set_ndb_engine + set_innodb_engine set_cge_extended_package elif test "x$package" = "xcge" ; then + set_base_engines + set_ndb_engine set_cge_package elif test "x$package" = "xclassic" ; then set_classic_package @@ -1473,7 +1785,6 @@ set_error_inject_configs # operating systems, and processors. # -check_os if test "x$os" = "xlinux" ; then set_linux_configs elif test "x$os" = "xSolaris" ; then @@ -1485,13 +1796,13 @@ elif test "x$os" = "xbsd" ; then else die "Operating system not supported by this script" fi - +set_ssl # # Final step before setting up commands is to set up proper make and # proper libtoolize versions, and to determine whether to use ccache. # set_make_version -set_up_ccache +set_ccache_usage # # Set up commands variable from variables prepared for base diff --git a/BUILD/check-cpu b/BUILD/check-cpu index 390ba545405..90f42ef67cc 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -16,12 +16,14 @@ check_cpu () { # on Linux (and others?) we can get detailed CPU information out of /proc cpuinfo="cat $CPUINFO" + # detect CPU architecture + cpu_arch=`$cpuinfo | grep 'arch' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` + # detect CPU family cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` if test -z "$cpu_family" ; then cpu_family=`$cpuinfo | grep 'cpu' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` fi - # detect CPU vendor and model cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` model_name=`$cpuinfo | grep 'model name' | cut -d ':' -f 2 | head -1` @@ -56,8 +58,8 @@ check_cpu () { fi ;; *) - cpu_family=`uname -m`; - model_name=`uname -p`; + cpu_family=`uname -p`; + model_name=`uname -m`; ;; esac fi @@ -65,9 +67,10 @@ check_cpu () { # detect CPU shortname as used by gcc options # this list is not complete, feel free to add further entries cpu_arg="" - case "$cpu_family--$model_name" in + low_cpu_arg="" + case "$cpu_vendor--$cpu_family--$model_name--$cpu_arch" in # DEC Alpha - Alpha*EV6*) + *Alpha*EV6*) cpu_arg="ev6"; ;; #Core 2 Duo @@ -96,6 +99,13 @@ check_cpu () { *Pentium*4*Mobile*) cpu_arg="pentium4m" ;; + *Pentium\(R\)*\ M*) + cpu_arg="pentium-m" + low_cpu_arg="pentium3" + ;; + *Pentium\(R\)*\ D*) + cpu_arg="prescott" + ;; *Pentium*4*) cpu_arg="pentium4" ;; @@ -120,6 +130,12 @@ check_cpu () { *Celeron*) cpu_arg="pentium2" ;; + *Atom*) + cpu_arg="prescott" + ;; + *GenuineIntel*) + cpu_arg="pentium" + ;; *Turion*) cpu_arg="athlon64" ;; @@ -129,9 +145,30 @@ check_cpu () { *Athlon*) cpu_arg="athlon" ;; + *AMD-K7*) + cpu_arg="athlon" + ;; + *Athlon*XP\ *) + cpu_arg="athlon-xp" + ;; + *AMD*Sempron\(tm\)*) + cpu_arg="athlon-mp" + ;; + *AMD*Athlon\(tm\)\ 64*) + cpu_arg="k8" + ;; *Opteron*) cpu_arg="opteron" ;; + *Phenom*) + cpu_arg="k8" + ;; + *AuthenticAMD*) + cpu_arg="k6" + ;; + *VIA\ *) + cpu_arg="i686" + ;; # MacOSX / Intel *i386*i486*) cpu_arg="pentium-m" @@ -143,8 +180,11 @@ check_cpu () { *Itanium*) cpu_arg="itanium" ;; + *IA-64*) + cpu_arg="itanium" + ;; # Solaris Sparc - *sparc*sun4u*) + *sparc*sun4[uv]*) cpu_arg="sparc" ;; # Power PC @@ -160,6 +200,10 @@ check_cpu () { ;; esac + if test "x$low_cpu_arg" = "x" ; then + low_cpu_arg="$cpu_arg" + fi + if test -z "$cpu_arg" ; then if test "$CPUINFO" != " " ; then # fallback to uname if necessary @@ -198,7 +242,7 @@ check_cpu () { case `gcc -dumpmachine` in i?86-* | x86_64-*) if test "$cc_comp" -lt 304 ; then - check_cpu_cflags="-mcpu=${cpu_arg}" + check_cpu_cflags="-mcpu=${low_cpu_arg}" elif test "$cc_comp" -ge 402 ; then check_cpu_cflags="-mtune=native" else diff --git a/client/Makefile.am b/client/Makefile.am index ad32117ac35..a491ce364b6 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -74,8 +74,7 @@ mysqlimport_SOURCES= mysqlimport.c mysqlimport_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ - $(LIBMYSQLCLIENT_LA) \ - $(top_builddir)/mysys/libmysys.a + $(LIBMYSQLCLIENT_LA) mysqlshow_SOURCES= mysqlshow.c @@ -83,16 +82,15 @@ mysqlslap_SOURCES= mysqlslap.c mysqlslap_CFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ - $(LIBMYSQLCLIENT_LA) \ - $(top_builddir)/mysys/libmysys.a + $(LIBMYSQLCLIENT_LA) mysqltest_SOURCES= mysqltest.cc mysqltest_CXXFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ - $(LIBMYSQLCLIENT_LA) \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/regex/libregex.a \ + $(LIBMYSQLCLIENT_LA) \ + $(top_builddir)/regex/libregex.la $(CLIENT_THREAD_LIBS) mysql_upgrade_SOURCES= mysql_upgrade.c \ diff --git a/client/mysql.cc b/client/mysql.cc index f9da1a8737b..dfbe394d81c 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4082,7 +4082,7 @@ static int com_source(String *buffer, char *line) If we got an error during source operation, don't abort the client if ignore_errors is set */ - if (error && !batch_abort_on_error && ignore_errors) + if (error && ignore_errors) error= -1; // Ignore error return error; } diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 055d8da5097..9df1837db95 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -109,6 +109,7 @@ static my_bool parsing_disabled= 0; static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, display_metadata= FALSE, display_result_sorted= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; +static my_bool disable_connect_log= 1; static my_bool disable_warnings= 0; static my_bool prepare_warnings_enabled= 0; static my_bool disable_info= 1; @@ -202,6 +203,8 @@ static int replace(DYNAMIC_STRING *ds_str, const char *search_str, ulong search_len, const char *replace_str, ulong replace_len); +static uint opt_protocol=0; + DYNAMIC_ARRAY q_lines; #include "sslopt-vars.h" @@ -253,7 +256,9 @@ struct st_connection int cur_query_len; pthread_mutex_t mutex; pthread_cond_t cond; + pthread_t tid; int query_done; + my_bool has_thread; #endif /*EMBEDDED_LIBRARY*/ }; @@ -284,6 +289,7 @@ enum enum_commands { Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, + Q_ENABLE_CONNECT_LOG, Q_DISABLE_CONNECT_LOG, Q_WAIT_FOR_SLAVE_TO_STOP, Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, Q_ENABLE_INFO, Q_DISABLE_INFO, @@ -352,6 +358,8 @@ const char *command_names[]= /* Enable/disable that the _result_ from a query is logged to result file */ "enable_result_log", "disable_result_log", + "enable_connect_log", + "disable_connect_log", "wait_for_slave_to_stop", "enable_warnings", "disable_warnings", @@ -607,14 +615,14 @@ public: lines++; int show_offset= 0; - char buf[256]; + char buf[256+1]; /* + zero termination for DBUG_PRINT */ size_t bytes; bool found_bof= false; /* Search backward in file until "lines" newline has been found */ while (lines && !found_bof) { - show_offset-= sizeof(buf); + show_offset-= sizeof(buf)-1; while(fseek(m_file, show_offset, SEEK_END) != 0 && show_offset < 0) { found_bof= true; @@ -622,13 +630,17 @@ public: show_offset++; } - if ((bytes= fread(buf, 1, sizeof(buf), m_file)) <= 0) + if ((bytes= fread(buf, 1, sizeof(buf)-1, m_file)) <= 0) { - fprintf(stderr, "Failed to read from '%s', errno: %d\n", - m_file_name, errno); + // ferror=0 will happen here if no queries executed yet + if (ferror(m_file)) + fprintf(stderr, + "Failed to read from '%s', errno: %d, feof:%d, ferror:%d\n", + m_file_name, errno, feof(m_file), ferror(m_file)); DBUG_VOID_RETURN; } + IF_DBUG(buf[bytes]= '\0';) DBUG_PRINT("info", ("Read %lu bytes from file, buf: %s", (unsigned long)bytes, buf)); @@ -673,8 +685,8 @@ public: } } - while ((bytes= fread(buf, 1, sizeof(buf), m_file)) > 0) - if (fwrite(buf, 1, bytes, stderr)) + while ((bytes= fread(buf, 1, sizeof(buf)-1, m_file)) > 0) + if (bytes != fwrite(buf, 1, bytes, stderr)) die("Failed to write to '%s', errno: %d", m_file_name, errno); @@ -717,6 +729,10 @@ void handle_no_error(struct st_command*); #ifdef EMBEDDED_LIBRARY +/* workaround for MySQL BUG#57491 */ +#undef MY_WME +#define MY_WME 0 + /* attributes of the query thread */ pthread_attr_t cn_thd_attrib; @@ -746,8 +762,6 @@ pthread_handler_t send_one_query(void *arg) static int do_send_query(struct st_connection *cn, const char *q, int q_len, int flags) { - pthread_t tid; - if (flags & QUERY_REAP_FLAG) return mysql_send_query(&cn->mysql, q, q_len); @@ -758,9 +772,10 @@ static int do_send_query(struct st_connection *cn, const char *q, int q_len, cn->cur_query= q; cn->cur_query_len= q_len; cn->query_done= 0; - if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn)) + if (pthread_create(&cn->tid, &cn_thd_attrib, send_one_query, (void*)cn)) die("Cannot start new thread for query"); + cn->has_thread= TRUE; return 0; } @@ -773,6 +788,14 @@ static void wait_query_thread_end(struct st_connection *con) pthread_cond_wait(&con->cond, &con->mutex); pthread_mutex_unlock(&con->mutex); } + if (con->has_thread) + { +#ifndef __WIN__ + /* May hang on Windows, but the problem it solves is not seen there */ + pthread_join(con->tid, NULL); +#endif + con->has_thread= FALSE; + } } #else /*EMBEDDED_LIBRARY*/ @@ -1079,7 +1102,8 @@ void check_command_args(struct st_command *command, DBUG_VOID_RETURN; } -void handle_command_error(struct st_command *command, uint error) +void handle_command_error(struct st_command *command, uint error, + int sys_errno) { DBUG_ENTER("handle_command_error"); DBUG_PRINT("enter", ("error: %d", error)); @@ -1095,12 +1119,14 @@ void handle_command_error(struct st_command *command, uint error) if (i >= 0) { - DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d", - command->first_word_len, command->query, error)); + DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %u, errno: %d", + command->first_word_len, command->query, error, + sys_errno)); DBUG_VOID_RETURN; } - die("command \"%.*s\" failed with wrong error: %d", - command->first_word_len, command->query, error); + if (command->expected_errors.count > 0) + die("command \"%.*s\" failed with wrong error: %u, errno: %d", + command->first_word_len, command->query, error, sys_errno); } else if (command->expected_errors.err[0].type == ERR_ERRNO && command->expected_errors.err[0].code.errnum != 0) @@ -1241,15 +1267,6 @@ void die(const char *fmt, ...) DBUG_ENTER("die"); DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); - /* - Protect against dying twice - first time 'die' is called, try to write log files - second time, just exit - */ - if (dying) - cleanup_and_exit(1); - dying= 1; - /* Print the error message */ fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -1268,6 +1285,15 @@ void die(const char *fmt, ...) fprintf(stderr, "\n"); fflush(stderr); + /* + Protect against dying twice + first time 'die' is called, try to write log files + second time, just exit + */ + if (dying) + cleanup_and_exit(1); + dying= 1; + log_file.show_tail(opt_tail_lines); /* @@ -1371,14 +1397,14 @@ void log_msg(const char *fmt, ...) */ -void cat_file(DYNAMIC_STRING* ds, const char* filename) +int cat_file(DYNAMIC_STRING* ds, const char* filename) { int fd; size_t len; char buff[512]; if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0) - die("Failed to open file '%s'", filename); + return 1; while((len= my_read(fd, (uchar*)&buff, sizeof(buff), MYF(0))) > 0) { @@ -1402,6 +1428,7 @@ void cat_file(DYNAMIC_STRING* ds, const char* filename) dynstr_append_mem(ds, start, p-start); } my_close(fd, MYF(0)); + return 0; } @@ -1809,7 +1836,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) { my_close(fd, MYF(0)); /* Remove the temporary file */ - my_delete(temp_file_path, MYF(0)); + my_delete(temp_file_path, MYF(MY_WME)); die("Failed to write file '%s'", temp_file_path); } @@ -1817,7 +1844,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) my_close(fd, MYF(0)); /* Remove the temporary file */ - my_delete(temp_file_path, MYF(0)); + my_delete(temp_file_path, MYF(MY_WME)); DBUG_RETURN(error); } @@ -1861,7 +1888,7 @@ void check_result() if (access(reject_file, W_OK) == 0) { /* Result file directory is writable, save reject file there */ - fn_format(reject_file, result_file_name, NULL, + fn_format(reject_file, result_file_name, "", ".reject", MY_REPLACE_EXT); } else @@ -2208,8 +2235,14 @@ void var_query_set(VAR *var, const char *query, const char** query_end) DBUG_ENTER("var_query_set"); LINT_INIT(res); + /* Only white space or ) allowed past ending ` */ while (end > query && *end != '`') + { + if (*end && (*end != ' ' && *end != '\t' && *end != '\n' && *end != ')')) + die("Spurious text after `query` expression"); --end; + } + if (query == end) die("Syntax error in query, missing '`'"); ++query; @@ -2416,6 +2449,9 @@ void eval_expr(VAR *v, const char *p, const char **p_end) if ((vp= var_get(p, p_end, 0, 0))) var_copy(v, vp); + /* Apparently it is not safe to assume null-terminated string */ + v->str_val[v->str_val_len]= 0; + /* Make sure there was just a $variable and nothing else */ const char* end= *p_end + 1; if (end < expected_end) @@ -2762,8 +2798,9 @@ void do_exec(struct st_command *command) else { dynstr_free(&ds_cmd); - die("command \"%s\" failed with wrong error: %d", - command->first_argument, status); + if (command->expected_errors.count > 0) + die("command \"%s\" failed with wrong error: %d", + command->first_argument, status); } } else if (command->expected_errors.err[0].type == ERR_ERRNO && @@ -2909,6 +2946,41 @@ void do_system(struct st_command *command) /* SYNOPSIS + set_wild_chars + set true to set * etc. as wild char, false to reset + + DESCRIPTION + Auxiliary function to set "our" wild chars before calling wild_compare + This is needed because the default values are changed to SQL syntax + in mysqltest_embedded. +*/ + +void set_wild_chars (my_bool set) +{ + static char old_many= 0, old_one, old_prefix; + + if (set) + { + if (wild_many == '*') return; // No need + old_many= wild_many; + old_one= wild_one; + old_prefix= wild_prefix; + wild_many= '*'; + wild_one= '?'; + wild_prefix= 0; + } + else + { + if (! old_many) return; // Was not set + wild_many= old_many; + wild_one= old_one; + wild_prefix= old_prefix; + } +} + + +/* + SYNOPSIS do_remove_file command called command @@ -2931,8 +3003,8 @@ void do_remove_file(struct st_command *command) ' '); DBUG_PRINT("info", ("removing file: %s", ds_filename.str)); - error= my_delete(ds_filename.str, MYF(0)) != 0; - handle_command_error(command, error); + error= my_delete(ds_filename.str, MYF(disable_warnings ? 0 : MY_WME)) != 0; + handle_command_error(command, error, my_errno); dynstr_free(&ds_filename); DBUG_VOID_RETURN; } @@ -2950,7 +3022,7 @@ void do_remove_file(struct st_command *command) void do_remove_files_wildcard(struct st_command *command) { - int error= 0; + int error= 0, sys_errno= 0; uint i; MY_DIR *dir_info; FILEINFO *file; @@ -2974,15 +3046,20 @@ void do_remove_files_wildcard(struct st_command *command) DBUG_PRINT("info", ("listing directory: %s", dirname)); /* Note that my_dir sorts the list if not given any flags */ - if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT)))) + if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT | MY_WME)))) { error= 1; + sys_errno= my_errno; goto end; } init_dynamic_string(&ds_file_to_remove, dirname, 1024, 1024); dir_separator[0]= FN_LIBCHAR; dir_separator[1]= 0; dynstr_append(&ds_file_to_remove, dir_separator); + + /* Set default wild chars for wild_compare, is changed in embedded mode */ + set_wild_chars(1); + for (i= 0; i < (uint) dir_info->number_off_files; i++) { file= dir_info->dir_entry + i; @@ -2998,14 +3075,16 @@ void do_remove_files_wildcard(struct st_command *command) ds_file_to_remove.str[ds_directory.length + 1]= 0; dynstr_append(&ds_file_to_remove, file->name); DBUG_PRINT("info", ("removing file: %s", ds_file_to_remove.str)); - error= my_delete(ds_file_to_remove.str, MYF(0)) != 0; + if ((error= (my_delete(ds_file_to_remove.str, MYF(MY_WME)) != 0))) + sys_errno= my_errno; if (error) break; } + set_wild_chars(0); my_dirend(dir_info); end: - handle_command_error(command, error); + handle_command_error(command, error, sys_errno); dynstr_free(&ds_directory); dynstr_free(&ds_wild); dynstr_free(&ds_file_to_remove); @@ -3043,8 +3122,8 @@ void do_copy_file(struct st_command *command) DBUG_PRINT("info", ("Copy %s to %s", ds_from_file.str, ds_to_file.str)); error= (my_copy(ds_from_file.str, ds_to_file.str, - MYF(MY_DONT_OVERWRITE_FILE)) != 0); - handle_command_error(command, error); + MYF(MY_DONT_OVERWRITE_FILE | MY_WME)) != 0); + handle_command_error(command, error, my_errno); dynstr_free(&ds_from_file); dynstr_free(&ds_to_file); DBUG_VOID_RETURN; @@ -3079,8 +3158,8 @@ void do_move_file(struct st_command *command) DBUG_PRINT("info", ("Move %s to %s", ds_from_file.str, ds_to_file.str)); error= (my_rename(ds_from_file.str, ds_to_file.str, - MYF(0)) != 0); - handle_command_error(command, error); + MYF(disable_warnings ? 0 : MY_WME)) != 0); + handle_command_error(command, error, my_errno); dynstr_free(&ds_from_file); dynstr_free(&ds_to_file); DBUG_VOID_RETURN; @@ -3100,6 +3179,7 @@ void do_move_file(struct st_command *command) void do_chmod_file(struct st_command *command) { + int error; long mode= 0; static DYNAMIC_STRING ds_mode; static DYNAMIC_STRING ds_file; @@ -3120,7 +3200,10 @@ void do_chmod_file(struct st_command *command) die("You must write a 4 digit octal number for mode"); DBUG_PRINT("info", ("chmod %o %s", (uint)mode, ds_file.str)); - handle_command_error(command, chmod(ds_file.str, mode)); + error= 0; + if (chmod(ds_file.str, mode)) + error= 1; + handle_command_error(command, error, errno); dynstr_free(&ds_mode); dynstr_free(&ds_file); DBUG_VOID_RETURN; @@ -3153,7 +3236,7 @@ void do_file_exist(struct st_command *command) DBUG_PRINT("info", ("Checking for existence of file: %s", ds_filename.str)); error= (access(ds_filename.str, F_OK) != 0); - handle_command_error(command, error); + handle_command_error(command, error, errno); dynstr_free(&ds_filename); DBUG_VOID_RETURN; } @@ -3183,8 +3266,8 @@ void do_mkdir(struct st_command *command) ' '); DBUG_PRINT("info", ("creating directory: %s", ds_dirname.str)); - error= my_mkdir(ds_dirname.str, 0777, MYF(0)) != 0; - handle_command_error(command, error); + error= my_mkdir(ds_dirname.str, 0777, MYF(MY_WME)) != 0; + handle_command_error(command, error, my_errno); dynstr_free(&ds_dirname); DBUG_VOID_RETURN; } @@ -3214,7 +3297,7 @@ void do_rmdir(struct st_command *command) DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str)); error= rmdir(ds_dirname.str) != 0; - handle_command_error(command, error); + handle_command_error(command, error, errno); dynstr_free(&ds_dirname); DBUG_VOID_RETURN; } @@ -3243,6 +3326,7 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname, /* Note that my_dir sorts the list if not given any flags */ if (!(dir_info= my_dir(ds_dirname->str, MYF(0)))) DBUG_RETURN(1); + set_wild_chars(1); for (i= 0; i < (uint) dir_info->number_off_files; i++) { file= dir_info->dir_entry + i; @@ -3256,6 +3340,7 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname, dynstr_append(ds, file->name); dynstr_append(ds, "\n"); } + set_wild_chars(0); my_dirend(dir_info); DBUG_RETURN(0); } @@ -3288,7 +3373,7 @@ static void do_list_files(struct st_command *command) sizeof(list_files_args)/sizeof(struct command_arg), ' '); error= get_list_files(&ds_res, &ds_dirname, &ds_wild); - handle_command_error(command, error); + handle_command_error(command, error, my_errno); dynstr_free(&ds_dirname); dynstr_free(&ds_wild); DBUG_VOID_RETURN; @@ -3330,7 +3415,7 @@ static void do_list_files_write_file_command(struct st_command *command, init_dynamic_string(&ds_content, "", 1024, 1024); error= get_list_files(&ds_content, &ds_dirname, &ds_wild); - handle_command_error(command, error); + handle_command_error(command, error, my_errno); str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append); dynstr_free(&ds_content); dynstr_free(&ds_filename); @@ -3538,6 +3623,7 @@ void do_append_file(struct st_command *command) void do_cat_file(struct st_command *command) { + int error; static DYNAMIC_STRING ds_filename; const struct command_arg cat_file_args[] = { { "filename", ARG_STRING, TRUE, &ds_filename, "File to read from" } @@ -3552,8 +3638,8 @@ void do_cat_file(struct st_command *command) DBUG_PRINT("info", ("Reading from, file: %s", ds_filename.str)); - cat_file(&ds_res, ds_filename.str); - + error= cat_file(&ds_res, ds_filename.str); + handle_command_error(command, error, my_errno); dynstr_free(&ds_filename); DBUG_VOID_RETURN; } @@ -3612,7 +3698,7 @@ void do_diff_files(struct st_command *command) dynstr_free(&ds_filename); dynstr_free(&ds_filename2); - handle_command_error(command, error); + handle_command_error(command, error, -1); DBUG_VOID_RETURN; } @@ -3817,10 +3903,22 @@ void do_perl(struct st_command *command) } error= pclose(res_file); - /* Remove the temporary file */ - my_delete(temp_file_path, MYF(0)); + /* Remove the temporary file, but keep it if perl failed */ + if (!error) + my_delete(temp_file_path, MYF(MY_WME)); - handle_command_error(command, WEXITSTATUS(error)); + /* Check for error code that indicates perl could not be started */ + int exstat= WEXITSTATUS(error); +#ifdef __WIN__ + if (exstat == 1) + /* Text must begin 'perl not found' as mtr looks for it */ + abort_not_supported_test("perl not found in path or did not start"); +#else + if (exstat == 127) + abort_not_supported_test("perl not found in path"); +#endif + else + handle_command_error(command, WEXITSTATUS(error), my_errno); } dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; @@ -4764,6 +4862,16 @@ void select_connection_name(const char *name) set_current_connection(con); + /* Connection logging if enabled */ + if (!disable_connect_log && !disable_query_log) + { + DYNAMIC_STRING *ds= &ds_res; + + dynstr_append_mem(ds, "connection ", 11); + replace_dynstr_append(ds, name); + dynstr_append_mem(ds, ";\n", 2); + } + DBUG_VOID_RETURN; } @@ -4850,6 +4958,17 @@ void do_close_connection(struct st_command *command) var_set_int("$mysql_get_server_version", 0xFFFFFFFF); var_set_string("$CURRENT_CONNECTION", con->name); } + + /* Connection logging if enabled */ + if (!disable_connect_log && !disable_query_log) + { + DYNAMIC_STRING *ds= &ds_res; + + dynstr_append_mem(ds, "disconnect ", 11); + replace_dynstr_append(ds, ds_connection.str); + dynstr_append_mem(ds, ";\n", 2); + } + dynstr_free(&ds_connection); DBUG_VOID_RETURN; } @@ -4961,7 +5080,7 @@ int connect_n_handle_errors(struct st_command *command, ds= &ds_res; /* Only log if an error is expected */ - if (!command->abort_on_error && + if (command->expected_errors.count > 0 && !disable_query_log) { /* @@ -4985,6 +5104,13 @@ int connect_n_handle_errors(struct st_command *command, dynstr_append_mem(ds, delimiter, delimiter_length); dynstr_append_mem(ds, "\n", 1); } + /* Simlified logging if enabled */ + if (!disable_connect_log && !disable_query_log) + { + replace_dynstr_append(ds, command->query); + dynstr_append_mem(ds, ";\n", 2); + } + while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0, CLIENT_MULTI_STATEMENTS)) { @@ -5175,6 +5301,7 @@ void do_connect(struct st_command *command) #ifdef EMBEDDED_LIBRARY con_slot->query_done= 1; + con_slot->has_thread= FALSE; #endif if (!mysql_init(&con_slot->mysql)) die("Failed on mysql_init()"); @@ -5207,11 +5334,13 @@ void do_connect(struct st_command *command) #ifdef __WIN__ if (con_pipe) { - uint protocol= MYSQL_PROTOCOL_PIPE; - mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol); + opt_protocol= MYSQL_PROTOCOL_PIPE; } #endif + if (opt_protocol) + mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); + #ifdef HAVE_SMEM if (con_shm) { @@ -5382,8 +5511,20 @@ void do_block(enum block_cmd cmd, struct st_command* command) /* Define inner block */ cur_block++; cur_block->cmd= cmd; - cur_block->ok= (v.int_val ? TRUE : FALSE); + if (v.int_val) + { + cur_block->ok= TRUE; + } else + /* Any non-empty string which does not begin with 0 is also TRUE */ + { + p= v.str_val; + /* First skip any leading white space or unary -+ */ + while (*p && ((my_isspace(charset_info, *p) || *p == '-' || *p == '+'))) + p++; + cur_block->ok= (*p && *p != '0') ? TRUE : FALSE; + } + if (not_expr) cur_block->ok = !cur_block->ok; @@ -5483,6 +5624,8 @@ int read_line(char *buf, int size) char c, UNINIT_VAR(last_quote); char *p= buf, *buf_end= buf + size - 1; int skip_char= 0; + my_bool have_slash= FALSE; + enum {R_NORMAL, R_Q, R_SLASH_IN_Q, R_COMMENT, R_LINE_START} state= R_LINE_START; DBUG_ENTER("read_line"); @@ -5554,9 +5697,13 @@ int read_line(char *buf, int size) } else if (c == '\'' || c == '"' || c == '`') { - last_quote= c; - state= R_Q; + if (! have_slash) + { + last_quote= c; + state= R_Q; + } } + have_slash= (c == '\\'); break; case R_COMMENT: @@ -5932,6 +6079,8 @@ static struct my_option my_long_options[] = GET_INT, REQUIRED_ARG, 128, 8, 5120, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " "order of preference, my.cnf, $MYSQL_TCP_PORT, " #if MYSQL_PORT_DEFAULT == 0 @@ -6071,7 +6220,7 @@ void read_embedded_server_arguments(const char *name) static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__((unused)), +get_one_option(int optid, const struct my_option *opt, char *argument) { switch(optid) { @@ -6160,6 +6309,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'V': print_version(); exit(0); + case OPT_MYSQL_PROTOCOL: +#ifndef EMBEDDED_LIBRARY + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); +#endif + break; case '?': usage(); exit(0); @@ -7292,11 +7447,13 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) (flags & QUERY_REAP_FLAG)); DBUG_ENTER("run_query"); - init_dynamic_string(&ds_warnings, NULL, 0, 256); - if (cn->pending && (flags & QUERY_SEND_FLAG)) die ("Cannot run query on connection between send and reap"); + if (!(flags & QUERY_SEND_FLAG) && !cn->pending) + die ("Cannot reap on a connection without pending send"); + + init_dynamic_string(&ds_warnings, NULL, 0, 256); /* Evaluate query if this is an eval command */ @@ -7638,9 +7795,6 @@ void get_command_type(struct st_command* command) sizeof(saved_expected_errors)); DBUG_PRINT("info", ("There are %d expected errors", command->expected_errors.count)); - command->abort_on_error= (command->expected_errors.count == 0 && - abort_on_error); - DBUG_VOID_RETURN; } @@ -7927,6 +8081,9 @@ int main(int argc, char **argv) mysql_options(&con->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); + if (opt_protocol) + mysql_options(&con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); + #ifdef HAVE_OPENSSL if (opt_use_ssl) @@ -7986,6 +8143,10 @@ int main(int argc, char **argv) command->type= Q_COMMENT; } + /* (Re-)set abort_on_error for this command */ + command->abort_on_error= (command->expected_errors.count == 0 && + abort_on_error); + /* delimiter needs to be executed so we can continue to parse */ ok_to_do= cur_block->ok || command->type == Q_DELIMITER; /* @@ -8033,6 +8194,8 @@ int main(int argc, char **argv) case Q_DISABLE_ABORT_ON_ERROR: abort_on_error=0; break; case Q_ENABLE_RESULT_LOG: disable_result_log=0; break; case Q_DISABLE_RESULT_LOG: disable_result_log=1; break; + case Q_ENABLE_CONNECT_LOG: disable_connect_log=0; break; + case Q_DISABLE_CONNECT_LOG: disable_connect_log=1; break; case Q_ENABLE_WARNINGS: disable_warnings=0; break; case Q_DISABLE_WARNINGS: disable_warnings=1; break; case Q_ENABLE_PREPARE_WARNINGS: prepare_warnings_enabled=1; break; @@ -8199,12 +8362,12 @@ int main(int argc, char **argv) command->last_argument= command->end; break; case Q_PING: - handle_command_error(command, mysql_ping(&cur_con->mysql)); + handle_command_error(command, mysql_ping(&cur_con->mysql), -1); break; case Q_SEND_SHUTDOWN: handle_command_error(command, mysql_shutdown(&cur_con->mysql, - SHUTDOWN_DEFAULT)); + SHUTDOWN_DEFAULT), -1); break; case Q_SHUTDOWN_SERVER: do_shutdown_server(command); @@ -8363,16 +8526,6 @@ int main(int argc, char **argv) check_result(); } } - else - { - /* - No result_file_name specified, the result - has been printed to stdout, exit with error - unless script has called "exit" to indicate success - */ - if (abort_flag == 0) - die("Exit with failure! Call 'exit' in script to return with sucess"); - } } else { diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4 index 1b7df75d6f7..24be31395f2 100644 --- a/config/ac-macros/maintainer.m4 +++ b/config/ac-macros/maintainer.m4 @@ -16,7 +16,7 @@ AC_DEFUN([MY_MAINTAINER_MODE], [ AC_DEFUN([MY_MAINTAINER_MODE_WARNINGS], [ # Setup GCC warning options. AS_IF([test "$GCC" = "yes"], [ - C_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Werror" + C_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Werror" CXX_WARNINGS="${C_WARNINGS} -Wno-unused-parameter" ]) diff --git a/config/ac-macros/plugins.m4 b/config/ac-macros/plugins.m4 index e05bbc48d0e..8af9cacbb6d 100644 --- a/config/ac-macros/plugins.m4 +++ b/config/ac-macros/plugins.m4 @@ -26,7 +26,7 @@ AC_DEFUN([MYSQL_PLUGIN],[ [__MYSQL_PLUGIN_]AS_TR_CPP([$1])[__], m4_default([$2], [$1 plugin]), m4_default([$3], [plugin for $1]), - m4_default([$4], []), + m4_default([[$4]], []), ) ]) @@ -60,7 +60,7 @@ dnl dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_STORAGE_ENGINE],[ - MYSQL_PLUGIN([$1], [$3], [$4], [[$5]]) + MYSQL_PLUGIN([$1], [$3], [$4], [$5]) MYSQL_PLUGIN_DEFINE([$1], [WITH_]AS_TR_CPP([$1])[_STORAGE_ENGINE]) ifelse([$2],[no],[],[ _MYSQL_LEGACY_STORAGE_ENGINE( @@ -115,18 +115,32 @@ dnl --------------------------------------------------------------------------- dnl Macro: MYSQL_PLUGIN_STATIC dnl dnl SYNOPSIS -dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a]) +dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a],[libmyplugin_embedded.a]) dnl dnl DESCRIPTION -dnl Declare the name for the static library +dnl Declare the name for the static library +dnl +dnl Third argument is optional, only needed for special plugins that depend +dnl on server internals and have source files that must be compiled specially +dnl with -DEMBEDDED_LIBRARY for embedded server. If specified, the third +dnl argument is used to link embedded server instead of the second. dnl dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_PLUGIN_STATIC],[ MYSQL_REQUIRE_PLUGIN([$1]) m4_define([MYSQL_PLUGIN_STATIC_]AS_TR_CPP([$1]), [$2]) + ifelse($#, 3, [ + m4_define([MYSQL_PLUGIN_EMBEDDED_]AS_TR_CPP([$1]), [$3]) + ]) ]) +dnl --------------------------------------------------------------------------- +dnl Substitution variable to use to compile source files specially for +dnl embedded server. +dnl To be used by plugins that have sources that depend on server internals. +dnl --------------------------------------------------------------------------- +AC_SUBST([plugin_embedded_defs], ["-DEMBEDDED_LIBRARY -DMYSQL_SERVER"]) dnl --------------------------------------------------------------------------- dnl Macro: MYSQL_PLUGIN_DYNAMIC @@ -254,28 +268,6 @@ AC_DEFUN([MYSQL_PLUGIN_ACTIONS],[ ]) dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS -dnl -dnl SYNOPSIS -dnl MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS([name],[file name]) -dnl -dnl DESCRIPTION -dnl Some modules in plugins keep dependance on structures -dnl declared in sql/ (THD class usually) -dnl That has to be fixed in the future, but until then -dnl we have to recompile these modules when we want to -dnl to compile server parts with the different #defines -dnl Normally it happens when we compile the embedded server -dnl Thus one should mark such files in his handler using this macro -dnl -dnl --------------------------------------------------------------------------- - -AC_DEFUN([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS],[ - MYSQL_REQUIRE_PLUGIN([$1]) - m4_define([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]), [$2]) -]) - -dnl --------------------------------------------------------------------------- dnl Macro: MYSQL_CONFIGURE_PLUGINS dnl dnl SYNOPSIS @@ -335,11 +327,25 @@ AC_DEFUN([_MYSQL_EMIT_CHECK_PLUGIN],[ [MYSQL_PLUGIN_DYNAMIC_]AS_TR_CPP([$1]), [MYSQL_PLUGIN_MANDATORY_]AS_TR_CPP([$1]), [MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]), - [MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_EMBEDDED_]AS_TR_CPP([$1]), [MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1]) ) ]) +dnl __MYSQL_EMIT_CHECK_PLUGIN arguments: +dnl +dnl 1 - plugin identifying name +dnl 2 - plugin identifying name, with `-' replaced by `_' +dnl 3 - plugin long name +dnl 4 - plugin description +dnl 5 - mysql_plugin_define (eg. WITH_xxx_STORAGE_ENGINE) +dnl 6 - directory +dnl 7 - static target (if supports static build) +dnl 8 - dynamic target (if supports dynamic build) +dnl 9 - mandatory flag +dnl 10 - disabled flag +dnl 11 - static target for libmysqld (if different from $7) +dnl 12 - actions AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ m4_ifdef([$5],[ AH_TEMPLATE($5, [Include ]$4[ into mysqld]) @@ -390,6 +396,14 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ fi ;; esac + # Similarly, disable shared plugins when configured with --disable-shared + # as libtool will not be able to produce them + if test "X[$enable_shared]" = Xno; then + if test "X[$mysql_plugin_]$2" != Xyes -a \ + "X[$with_plugin_]$2" != Xyes; then + [with_plugin_]$2=no + fi + fi ]) @@ -406,6 +420,7 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ ]) AC_SUBST([plugin_]$2[_shared_target], "$8") AC_SUBST([plugin_]$2[_static_target], [""]) + AC_SUBST([plugin_]$2[_embedded_static_target], [""]) [with_plugin_]$2=yes AC_MSG_RESULT([plugin]) m4_ifdef([$6],[ @@ -420,32 +435,47 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ ]) else m4_ifdef([$7],[ - ifelse(m4_bregexp($7, [^lib[^.]+\.a$]), -2, [ -dnl change above "-2" to "0" to enable this section -dnl Although this is "pretty", it breaks libmysqld build - m4_ifdef([$6],[ - mysql_use_plugin_dir="$6" - mysql_plugin_libs="$mysql_plugin_libs -L[\$(top_builddir)]/$6" - ]) - mysql_plugin_libs="$mysql_plugin_libs dnl -[-l]m4_bregexp($7, [^lib\([^.]+\)], [\1])" - ], m4_bregexp($7, [^\\\$]), 0, [ + ifelse(m4_bregexp($7, [^\\\$]), 0, [ m4_ifdef([$6],[ mysql_use_plugin_dir="$6" ]) mysql_plugin_libs="$mysql_plugin_libs $7" + m4_ifdef([$11],[ + mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $11" + ],[ + mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $7" + ]) ], [ m4_ifdef([$6],[ mysql_use_plugin_dir="$6" mysql_plugin_libs="$mysql_plugin_libs \$(top_builddir)/$6/$7" + m4_ifdef([$11],[ + mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs \$(top_builddir)/$6/$11" + ],[ + mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs \$(top_builddir)/$6/$7" + ]) ],[ mysql_plugin_libs="$mysql_plugin_libs $7" + m4_ifdef([$11],[ + mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $11" + ],[ + mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $7" + ]) ]) ]) m4_ifdef([$5],[ AC_DEFINE($5) ]) AC_SUBST([plugin_]$2[_static_target], "$7") + m4_ifdef([$11], [ + if test "$with_embedded_server" = "yes"; then + AC_SUBST([plugin_]$2[_embedded_static_target], "$11") + else + AC_SUBST([plugin_]$2[_embedded_static_target], [""]) + fi + ], [ + AC_SUBST([plugin_]$2[_embedded_static_target], [""]) + ]) AC_SUBST([plugin_]$2[_shared_target], [""]) ],[ m4_ifdef([$6],[ @@ -462,14 +492,6 @@ dnl Although this is "pretty", it breaks libmysqld build mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]" [with_plugin_]$2=yes AC_MSG_RESULT([yes]) - m4_ifdef([$11], [ - m4_foreach([plugin], [$11], [ - condition_dependent_plugin_modules="$condition_dependent_plugin_modules m4_bregexp(plugin, [[^/]+$], [\&])" - condition_dependent_plugin_objects="$condition_dependent_plugin_objects m4_bregexp(plugin, [[^/]+\.], [\&o])" - condition_dependent_plugin_links="$condition_dependent_plugin_links $6/plugin" - condition_dependent_plugin_includes="$condition_dependent_plugin_includes -I[\$(top_srcdir)]/$6/m4_bregexp(plugin, [^.+[/$]], [\&])" - ]) - ]) fi fi diff --git a/configure.in b/configure.in index ee70d42ac94..5c882fcdcc6 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MariaDB Server], [5.1.50-MariaDB], [], [mysql]) +AC_INIT([MariaDB Server], [5.1.52-MariaDB], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM @@ -250,7 +250,7 @@ AC_PROG_LIBTOOL # Ensure that we have --preserve-dup-deps defines, otherwise we get link # problems of 'mysql' with CXX=g++ -LIBTOOL="$LIBTOOL --preserve-dup-deps" +#LIBTOOL="$LIBTOOL --preserve-dup-deps" AC_SUBST(LIBTOOL)dnl AC_SUBST(NM)dnl @@ -2521,9 +2521,8 @@ MYSQL_CHECK_LIBEVENT MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine], [Traditional non-transactional MySQL tables]) MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam]) -MYSQL_PLUGIN_STATIC(myisam, [libmyisam.a]) +MYSQL_PLUGIN_STATIC(myisam, [libmyisam_s.la], [libmyisam_embedded.la]) MYSQL_PLUGIN_MANDATORY(myisam) dnl Default -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisam, [ha_myisam.cc]) MYSQL_STORAGE_ENGINE(partition, partition, [Partition Support], [MySQL Partitioning Support], [max,max-no-ndb]) @@ -2846,9 +2845,6 @@ if test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no" then AC_DEFINE([THREAD], [1], [Define if you want to have threaded code. This may be undef on client code]) - # Avoid _PROGRAMS names - THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o mf_keycaches.o waiting_threads.o" - AC_SUBST(THREAD_LOBJECTS) fi AM_CONDITIONAL(NEED_THREAD, test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no") @@ -2877,6 +2873,7 @@ AC_SUBST(server_scripts) AC_SUBST(mysql_plugin_dirs) AC_SUBST(mysql_plugin_libs) +AC_SUBST(mysql_embedded_plugin_libs) AC_SUBST(mysql_plugin_defs) diff --git a/dbug/Makefile.am b/dbug/Makefile.am index 528a6a02fbf..e8acb0ca2c0 100644 --- a/dbug/Makefile.am +++ b/dbug/Makefile.am @@ -16,10 +16,11 @@ # MA 02111-1307, USA INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -LDADD = libdbug.a ../mysys/libmysys.a ../strings/libmystrings.a +LDADD = libdbug.a $(top_builddir)/mysys/libmysys.a $(top_builddir)/strings/libmystrings.a pkglib_LIBRARIES = libdbug.a +noinst_LTLIBRARIES = libdbug.la noinst_HEADERS = dbug_long.h -libdbug_a_SOURCES = dbug.c sanity.c +libdbug_la_SOURCES = dbug.c sanity.c EXTRA_DIST = CMakeLists.txt example1.c example2.c example3.c \ user.r monty.doc dbug_add_tags.pl \ my_main.c main.c factorial.c dbug_analyze.c \ @@ -65,3 +66,7 @@ output5.r: factorial # a hack to have executable in builddir, not in srcdir tests-t: tests-t.pl cp -f $(srcdir)/tests-t.pl ./tests-t + +libdbug_a_SOURCES= +libdbug.a: libdbug.la + $(CP) .libs/libdbug.a $@ diff --git a/dbug/dbug.c b/dbug/dbug.c index cad7fbb3030..e653013e09a 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -286,7 +286,7 @@ typedef struct _db_code_state_ { #define ListDel(A,B,C) ListAddDel(A,B,C,EXCLUDE) static struct link *ListAddDel(struct link *, const char *, const char *, int); static struct link *ListCopy(struct link *); -static int InList(struct link *linkp,const char *cp); +static int InList(struct link *linkp,const char *cp, int exact_match); static uint ListFlags(struct link *linkp); static void FreeList(struct link *linkp); @@ -982,7 +982,7 @@ void _db_pop_() } while (0) #define str_to_buf(S) do { \ char_to_buf(','); \ - buf=strnmov(buf, (S), len+1); \ + buf=strnmov(buf, (S), (uint) (end-buf)); \ if (buf >= end) goto overflow; \ } while (0) #define list_to_buf(l, f) do { \ @@ -1581,13 +1581,13 @@ static struct link *ListCopy(struct link *orig) * */ -static int InList(struct link *linkp, const char *cp) +static int InList(struct link *linkp, const char *cp, int exact_match) { int result; for (result=MATCHED; linkp != NULL; linkp= linkp->next_link) { - if (!fnmatch(linkp->str, cp, 0)) + if (!(exact_match ? strcmp(linkp->str,cp) : fnmatch(linkp->str, cp, 0))) return linkp->flags; if (!(linkp->flags & EXCLUDE)) result=NOT_MATCHED; @@ -1637,8 +1637,8 @@ static void PushState(CODE_STATE *cs) struct settings *new_malloc; new_malloc= (struct settings *) DbugMalloc(sizeof(struct settings)); + bzero(new_malloc, sizeof(struct settings)); new_malloc->next= cs->stack; - new_malloc->out_file= NULL; cs->stack= new_malloc; } @@ -1752,8 +1752,8 @@ void _db_end_() static int DoTrace(CODE_STATE *cs) { if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) && - InList(cs->stack->processes, cs->process) & (MATCHED|INCLUDE)) - switch(InList(cs->stack->functions, cs->func)) { + InList(cs->stack->processes, cs->process, 0) & (MATCHED|INCLUDE)) + switch(InList(cs->stack->functions, cs->func, 0)) { case INCLUDE|SUBDIR: return ENABLE_TRACE; case INCLUDE: return DO_TRACE; case MATCHED|SUBDIR: @@ -1790,10 +1790,10 @@ static int DoTrace(CODE_STATE *cs) #ifndef THREAD static BOOLEAN DoProfile(CODE_STATE *cs) { - return PROFILING && - cs->level <= cs->stack->maxdepth && - InList(cs->stack->p_functions, cs->func) & (INCLUDE|MATCHED) && - InList(cs->stack->processes, cs->process) & (INCLUDE|MATCHED); + return (PROFILING && + cs->level <= cs->stack->maxdepth && + InList(cs->stack->p_functions, cs->func, 0) & (INCLUDE|MATCHED) && + InList(cs->stack->processes, cs->process, 0) & (INCLUDE|MATCHED)); } #endif @@ -1826,11 +1826,11 @@ FILE *_db_fp_(void) BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict) { + int match= strict ? INCLUDE : INCLUDE|MATCHED; get_code_state_if_not_set_or_return FALSE; - strict=strict ? INCLUDE : INCLUDE|MATCHED; - return DEBUGGING && DoTrace(cs) & DO_TRACE && - InList(cs->stack->keywords, keyword) & strict; + return (DEBUGGING && DoTrace(cs) & DO_TRACE && + InList(cs->stack->keywords, keyword, strict) & match); } /* @@ -2121,7 +2121,7 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name) static void DBUGCloseFile(CODE_STATE *cs, FILE *fp) { - if (fp != stderr && fp != stdout && fclose(fp) == EOF) + if (fp != NULL && fp != stderr && fp != stdout && fclose(fp) == EOF) { if (!cs->locked) pthread_mutex_lock(&THR_LOCK_dbug); diff --git a/dbug/remove_function_from_trace.pl b/dbug/remove_function_from_trace.pl index 1da9e25f9ba..380df168caf 100755 --- a/dbug/remove_function_from_trace.pl +++ b/dbug/remove_function_from_trace.pl @@ -1,6 +1,5 @@ #!/usr/bin/perl - die <<EEE unless @ARGV; Usage: $0 func1 [func2 [ ...] ] @@ -11,16 +10,16 @@ DBUG_ENTER() and DBUG_POP(); right before DBUG_RETURN in every such a function. EEE $re=join('|', @ARGV); -$skip=''; while(<STDIN>) { - print unless $skip; + ($thd) = /^(T@\d+)/; + print unless $skip{$thd}; next unless /^(?:.*: )*((?:\| )*)([<>])($re)\n/o; if ($2 eq '>') { - $skip=$1.$3 unless $skip; + $skip{$thd}=$1.$3 unless $skip{$thd}; next; } - next if $skip ne $1.$3; - $skip=''; + next if $skip{$thd} ne $1.$3; + delete $skip{$thd}; print; } diff --git a/extra/Makefile.am b/extra/Makefile.am index 8d6d18f0031..9c66cedc013 100644 --- a/extra/Makefile.am +++ b/extra/Makefile.am @@ -15,8 +15,10 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_srcdir)/sql -LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \ - ../dbug/libdbug.a ../strings/libmystrings.a \ +LDADD = @CLIENT_EXTRA_LDFLAGS@ \ + $(top_builddir)/mysys/libmysys.a \ + $(top_builddir)/strings/libmystrings.a \ + $(top_builddir)/dbug/libdbug.a \ $(ZLIB_LIBS) BUILT_SOURCES= $(top_builddir)/include/mysqld_error.h \ $(top_builddir)/include/sql_state.h \ diff --git a/extra/replace.c b/extra/replace.c index 40bddf6d8fb..47993857a43 100644 --- a/extra/replace.c +++ b/extra/replace.c @@ -1085,7 +1085,7 @@ static int convert_file(REPLACE *rep, char * name) my_fclose(in,MYF(0)); my_fclose(out,MYF(0)); if (updated && ! error) - my_redel(org_name,tempname,MYF(MY_WME | MY_LINK_WARNING)); + my_redel(org_name, tempname, 0, MYF(MY_WME | MY_LINK_WARNING)); else my_delete(tempname,MYF(MY_WME)); if (!silent && ! error) diff --git a/include/Makefile.am b/include/Makefile.am index ff0eff4668c..659adff848e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -26,7 +26,8 @@ pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \ decimal.h errmsg.h my_global.h my_valgrind.h my_net.h \ my_getopt.h sslopt-longopts.h my_dir.h \ sslopt-vars.h sslopt-case.h sql_common.h keycache.h \ - m_ctype.h my_attribute.h $(HEADERS_GEN_CONFIGURE) \ + m_ctype.h my_attribute.h my_compiler.h \ + $(HEADERS_GEN_CONFIGURE) \ $(HEADERS_GEN_MAKE) noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ @@ -40,7 +41,7 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \ atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \ - wqueue.h waiting_threads.h my_compiler.h + wqueue.h waiting_threads.h EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp diff --git a/include/maria.h b/include/maria.h index 106aa61ddbb..fb09116a24c 100644 --- a/include/maria.h +++ b/include/maria.h @@ -430,7 +430,8 @@ int maria_repair_by_sort(HA_CHECK *param, MARIA_HA *info, int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, const char *name, my_bool rep_quick); int maria_change_to_newfile(const char *filename, const char *old_ext, - const char *new_ext, myf myflags); + const char *new_ext, time_t backup_time, + myf myflags); void maria_lock_memory(HA_CHECK *param); int maria_update_state_info(HA_CHECK *param, MARIA_HA *info, uint update); void maria_update_key_parts(MARIA_KEYDEF *keyinfo, double *rec_per_key_part, diff --git a/include/my_base.h b/include/my_base.h index 00a13f28f57..d8b4d8b39b3 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -50,6 +50,7 @@ #define HA_OPEN_COPY 256 /* Open copy (for repair) */ /* Internal temp table, used for temporary results */ #define HA_OPEN_INTERNAL_TABLE 512 +#define HA_OPEN_MERGE_TABLE 1024 /* The following is parameter to ha_rkey() how to use key */ @@ -196,6 +197,7 @@ enum ha_extra_function { */ HA_EXTRA_ATTACH_CHILDREN, HA_EXTRA_DETACH_CHILDREN, + HA_EXTRA_DETACH_CHILD, /* Inform handler we will force a close as part of flush */ HA_EXTRA_PREPARE_FOR_FORCED_CLOSE }; diff --git a/include/my_bitmap.h b/include/my_bitmap.h index 994c5cb4299..39ee1d2f7fc 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -25,8 +25,6 @@ typedef uint32 my_bitmap_map; typedef struct st_bitmap { my_bitmap_map *bitmap; - uint n_bits; /* number of bits occupied by the above */ - my_bitmap_map last_word_mask; my_bitmap_map *last_word_ptr; /* mutex will be acquired for the duration of each bitmap operation if @@ -36,6 +34,8 @@ typedef struct st_bitmap #ifdef THREAD pthread_mutex_t *mutex; #endif + my_bitmap_map last_word_mask; + uint32 n_bits; /* number of bits occupied by the above */ } MY_BITMAP; #ifdef __cplusplus diff --git a/include/my_global.h b/include/my_global.h index 38cc87bb42d..5f917cc110e 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -568,44 +568,34 @@ int __void__; #endif /* DONT_DEFINE_VOID */ /* - Try to suppress warning for not initialized variables. + Deprecated workaround for false-positive uninitialized variables + warnings. Those should be silenced using tool-specific heuristics. - With gcc when using C, we suppress the uninitialized variable warning - without generating code. We can't do this with C++ - for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772). + Enabled by default for g++ due to the bug referenced below. */ - -#if defined(FORCE_INIT_OF_VARS) +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || \ + (defined(__GNUC__) && defined(__cplusplus)) #define LINT_INIT(var) var= 0 -#if defined(__cplusplus) || !defined(__GNUC__) -#define UNINIT_VAR(x) x= 0 #else -/* GCC specific self-initialization which inhibits the warning. */ -#define UNINIT_VAR(x) x= x -#endif -#else /* !FORCE_INIT_OF_VARS */ #define LINT_INIT(var) -#if !defined(__cplusplus) && !defined(__GNUC__) -/* GCC specific self-initialization which inhibits the warning. */ -#define UNINIT_VAR(x) x= x -#else -#define UNINIT_VAR(x) x #endif -#endif /* FORCE_INIT_OF_VARS */ - -#include <my_valgrind.h> /* - The following is to force some unitialized variables to 0 if we are - running valgrind. This is needed when the compiler may access the variable - even if the value of it is never used. + Suppress uninitialized variable warning without generating code. + + The _cplusplus is a temporary workaround for C++ code pending a fix + for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772). */ -#if defined(HAVE_valgrind) -#define VALGRIND_OR_LINT_INIT(var) var=0 +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || \ + defined(__cplusplus) || !defined(__GNUC__) +#define UNINIT_VAR(x) x= 0 #else -#define VALGRIND_OR_LINT_INIT(var) LINT_INIT(var) +/* GCC specific self-initialization which inhibits the warning. */ +#define UNINIT_VAR(x) x= x #endif +#include <my_valgrind.h> + /* Define some useful general macros */ #if !defined(max) #define max(a, b) ((a) > (b) ? (a) : (b)) @@ -621,7 +611,7 @@ typedef unsigned short ushort; #define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1) #define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0) -#define swap_variables(t, a, b) { t swap_dummy; swap_dummy= a; a= b; b= swap_dummy; } +#define swap_variables(t, a, b) { t dummy; dummy= a; a= b; b= dummy; } #define test(a) ((a) ? 1 : 0) #define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0) #define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0) diff --git a/include/my_sys.h b/include/my_sys.h index 2f8a44fedc0..6f5e0328fe9 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -135,6 +135,9 @@ extern int NEAR my_errno; /* Last error in mysys */ #define GETDATE_GMT 8 #define GETDATE_FIXEDLENGTH 16 +/* Extra length needed for filename if one calls my_create_backup_name */ +#define MY_BACKUP_NAME_EXTRA_LENGTH 17 + /* defines when allocating data */ #ifdef SAFEMALLOC #define my_malloc(SZ,FLAG) _mymalloc((SZ), __FILE__, __LINE__, FLAG ) @@ -685,7 +688,10 @@ extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags); extern int my_message_curses(uint my_err, const char *str,myf MyFlags); extern my_bool my_init(void); extern void my_end(int infoflag); -extern int my_redel(const char *from, const char *to, int MyFlags); +extern int my_redel(const char *from, const char *to, time_t backup_time_stamp, + myf MyFlags); +void my_create_backup_name(char *to, const char *from, + time_t backup_time_stamp); extern int my_copystat(const char *from, const char *to, int MyFlags); extern char * my_filename(File fd); diff --git a/include/myisam.h b/include/myisam.h index 8413b7936e3..bf31a96b792 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -295,6 +295,8 @@ extern int mi_is_changed(struct st_myisam_info *info); extern int mi_delete_all_rows(struct st_myisam_info *info); extern ulong _mi_calc_blob_length(uint length , const uchar *pos); extern uint mi_get_pointer_length(ulonglong file_length, uint def); +extern int mi_make_backup_of_index(struct st_myisam_info *info, + time_t backup_time, myf flags); #define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for mmap file */ /* this is used to pass to mysql_myisamchk_table */ @@ -390,7 +392,8 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info, const char * name, int rep_quick); int change_to_newfile(const char * filename, const char * old_ext, - const char * new_ext, uint raid_chunks, + const char * new_ext, time_t backup_time, + uint raid_chunks, myf myflags); int lock_file(HA_CHECK *param, File file, my_off_t start, int lock_type, const char *filetype, const char *filename); diff --git a/include/myisamchk.h b/include/myisamchk.h index 057c06652a1..7d7100bdd71 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -74,7 +74,7 @@ #define TT_USEFRM 1 #define TT_FOR_UPGRADE 2 -#define O_NEW_INDEX 1 /* Bits set in out_flag */ +/* Bits set in out_flag */ #define O_NEW_DATA 2 #define O_DATA_LOST 4 @@ -141,6 +141,7 @@ typedef struct st_handler_check_param ulonglong use_buffers; /* Used as param to getopt() */ size_t read_buffer_length, write_buffer_length; size_t sort_buffer_length, sort_key_blocks; + time_t backup_time; /* To sign backup files */ ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY]; double new_rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY]; uint out_flag, warning_printed, error_printed, verbose; diff --git a/include/mysql.h b/include/mysql.h index 0a3c3241168..d1552443383 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -224,7 +224,8 @@ struct st_mysql_options { enum mysql_status { - MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT + MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT, + MYSQL_STATUS_STATEMENT_GET_RESULT }; enum mysql_protocol_type diff --git a/include/mysql.h.pp b/include/mysql.h.pp index c3d10e5a7b9..86ca04fe766 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -292,7 +292,8 @@ struct st_mysql_options { }; enum mysql_status { - MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT + MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT, + MYSQL_STATUS_STATEMENT_GET_RESULT }; enum mysql_protocol_type { diff --git a/include/sha1.h b/include/sha1.h index e476456a9bd..787896e7476 100644 --- a/include/sha1.h +++ b/include/sha1.h @@ -6,12 +6,13 @@ 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 + 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 */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ /* This is the header file for code which implements the Secure @@ -25,6 +26,38 @@ Please read the file sha1.c for more information. Modified 2002 by Peter Zaitsev to better follow MySQL standards + + Original Source from: http://www.faqs.org/rfcs/rfc3174.html + + Copyright (C) The Internet Society (2001). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + Acknowledgement + Funding for the RFC Editor function is currently provided by the + Internet Society. */ diff --git a/include/thr_lock.h b/include/thr_lock.h index 14d93a47e5a..08cc8bd5408 100644 --- a/include/thr_lock.h +++ b/include/thr_lock.h @@ -82,6 +82,12 @@ enum enum_thr_lock_result { THR_LOCK_SUCCESS= 0, THR_LOCK_ABORTED= 1, THR_LOCK_WAIT_TIMEOUT= 2, THR_LOCK_DEADLOCK= 3 }; +/* Priority for locks */ +#define THR_LOCK_LATE_PRIV 1 /* For locks to be merged with org lock */ +#define THR_LOCK_MERGE_PRIV 2 /* For merge tables */ + +#define THR_UNLOCK_UPDATE_STATUS 1 + extern ulong max_write_lock_count; extern ulong table_lock_wait_timeout; extern my_bool thr_lock_inited; @@ -116,9 +122,10 @@ typedef struct st_thr_lock_data { struct st_thr_lock_data *next,**prev; struct st_thr_lock *lock; pthread_cond_t *cond; - enum thr_lock_type type; void *status_param; /* Param to status functions */ void *debug_print_param; + enum thr_lock_type type; + uint priority; } THR_LOCK_DATA; struct st_lock_list { @@ -138,8 +145,10 @@ typedef struct st_thr_lock { void (*get_status)(void*, my_bool); /* When one gets a lock */ void (*copy_status)(void*,void*); void (*update_status)(void*); /* Before release of write */ - void (*restore_status)(void*); /* Before release of read */ + void (*restore_status)(void*); /* Before release of read */ + my_bool (*start_trans)(void*); /* When all locks are taken */ my_bool (*check_status)(void *); + void (*fix_status)(void *, void *);/* For thr_merge_locks() */ my_bool allow_multiple_concurrent_insert; } THR_LOCK; @@ -154,13 +163,11 @@ void thr_lock_init(THR_LOCK *lock); void thr_lock_delete(THR_LOCK *lock); void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *status_param); -enum enum_thr_lock_result thr_lock(THR_LOCK_DATA *data, - THR_LOCK_OWNER *owner, - enum thr_lock_type lock_type); -void thr_unlock(THR_LOCK_DATA *data); +void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags); enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner); -void thr_multi_unlock(THR_LOCK_DATA **data,uint count); +void thr_multi_unlock(THR_LOCK_DATA **data,uint count, uint unlock_flags); +void thr_merge_locks(THR_LOCK_DATA **data, uint org_count, uint new_count); void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock); my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread); void thr_print_locks(void); /* For debugging */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 222916bfa06..7f2b6fc137f 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2516,6 +2516,8 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length) set_stmt_errmsg(stmt, net); DBUG_RETURN(1); } + else if (mysql->status == MYSQL_STATUS_GET_RESULT) + stmt->mysql->status= MYSQL_STATUS_STATEMENT_GET_RESULT; DBUG_RETURN(0); } @@ -2654,7 +2656,7 @@ static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row) set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL); return 1; } - if (mysql->status != MYSQL_STATUS_GET_RESULT) + if (mysql->status != MYSQL_STATUS_STATEMENT_GET_RESULT) { set_stmt_error(stmt, stmt->unbuffered_fetch_cancelled ? CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC, @@ -4860,7 +4862,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) DBUG_RETURN(1); } } - else if (mysql->status != MYSQL_STATUS_GET_RESULT) + else if (mysql->status != MYSQL_STATUS_STATEMENT_GET_RESULT) { set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL); DBUG_RETURN(1); diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 83af96c7b89..fdde891c81d 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -34,10 +34,10 @@ INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_srcdir)/sql/examples \ -I$(top_srcdir)/regex \ $(openssl_includes) @ZLIB_INCLUDES@ \ - @condition_dependent_plugin_includes@ + @condition_dependent_plugin_includes@ \ + @ndbcluster_includes@ -noinst_LIBRARIES = libmysqld_int.a -pkglib_LIBRARIES = libmysqld.a +pkglib_LTLIBRARIES = libmysqld.la SUBDIRS = . examples libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \ @@ -79,104 +79,28 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ rpl_injector.cc my_user.c partition_info.cc \ sql_servers.cc event_parse_data.cc opt_table_elimination.cc -libmysqld_int_a_SOURCES= $(libmysqld_sources) -nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources) -libmysqld_a_SOURCES= - -sqlstoragesources = $(EXTRA_libmysqld_a_SOURCES) -storagesources = @condition_dependent_plugin_modules@ -storageobjects = @condition_dependent_plugin_objects@ -storagesourceslinks = @condition_dependent_plugin_links@ - # automake misses these sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy # The following libraries should be included in libmysqld.a -INC_LIB= $(top_builddir)/regex/libregex.a \ - $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a \ - $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/vio/libvio.a \ - @NDB_SCI_LIBS@ \ - @mysql_plugin_libs@ \ +INC_LIB= $(top_builddir)/regex/libregex.la \ + $(top_builddir)/mysys/libmysys.la \ + $(top_builddir)/strings/libmystrings.la \ + $(top_builddir)/dbug/libdbug.la \ + $(top_builddir)/vio/libvio.la \ + @ndbcluster_libs@ @NDB_SCI_LIBS@ \ + @mysql_embedded_plugin_libs@ \ $(libevent_inc_libs) \ $(yassl_inc_libs) if HAVE_YASSL -yassl_inc_libs= $(top_builddir)/extra/yassl/src/.libs/libyassl.a \ - $(top_builddir)/extra/yassl/taocrypt/src/.libs/libtaocrypt.a +yassl_inc_libs= $(top_builddir)/extra/yassl/src/libyassl.la \ + $(top_builddir)/extra/yassl/taocrypt/src/libtaocrypt.la endif -# Storage engine specific compilation options -ha_ndbcluster.o:ha_ndbcluster.cc - $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< - -ha_ndbcluster_cond.o:ha_ndbcluster_cond.cc - $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< - -ha_ndbcluster_binlog.o: ha_ndbcluster_binlog.cc - $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< - -# Until we can remove dependency on ha_ndbcluster.h -handler.o: handler.cc - $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< - -# We need rules to compile these as no good way -# found to append fileslists that collected by configure -# to the sources list - -ha_federatedx.o:ha_federatedx.cc - $(CXXCOMPILE) $(LM_CFLAGS) -c $< - -ha_heap.o:ha_heap.cc - $(CXXCOMPILE) $(LM_CFLAGS) -c $< - -ha_innodb.o:ha_innodb.cc - $(CXXCOMPILE) $(LM_CFLAGS) -c $< - -ha_myisam.o:ha_myisam.cc - $(CXXCOMPILE) $(LM_CFLAGS) -c $< - -ha_myisammrg.o:ha_myisammrg.cc - $(CXXCOMPILE) $(LM_CFLAGS) -c $< - -# -# To make it easy for the end user to use the embedded library we -# generate a total libmysqld.a from all library files, - -# note - InnoDB libraries have circular dependencies, so in INC_LIB -# few libraries are present two times. Metrowerks linker doesn't like -# it at all. Traditional ar has no problems with it, but still there's no -# need to add the same file twice to the library, so 'sort -u' save us -# some time and spares unnecessary work. - -libmysqld.a: libmysqld_int.a $(INC_LIB) $(libmysqld_a_DEPENDENCIES) $(storageobjects) -if DARWIN_MWCC - mwld -lib -o $@ libmysqld_int.a `echo $(INC_LIB) | sort -u` $(storageobjects) -else - -rm -f libmysqld.a - if test "$(host_os)" = "netware" ; \ - then \ - $(libmysqld_a_AR) libmysqld.a $(INC_LIB) libmysqld_int.a $(storageobjects); \ - else \ - current_dir=`pwd`; \ - rm -rf tmp; mkdir tmp; \ - (for arc in $(INC_LIB) ./libmysqld_int.a; do \ - arpath=`echo $$arc|sed 's|[^/]*$$||'|sed 's|\.libs/$$||'`; \ - artmp=`echo $$arc|sed 's|^.*/|tmp/lib-|'`; \ - for F in `$(AR) t $$arc | grep -v SYMDEF`; do \ - if test -e "$$arpath/$$F" ; then echo "$$arpath/$$F"; else \ - mkdir $$artmp; cd $$artmp > /dev/null; \ - $(AR) x ../../$$arc; \ - cd $$current_dir > /dev/null; \ - ls $$artmp/* | grep -v SYMDEF; \ - continue 2; fi; done; \ - done; echo $(libmysqld_a_DEPENDENCIES) ) | sort -u | xargs $(AR) cq libmysqld.a ; \ - $(AR) r libmysqld.a $(storageobjects); \ - $(RANLIB) libmysqld.a ; \ - rm -rf tmp; \ - fi -endif +libmysqld_la_SOURCES= $(libmysqld_sources) +nodist_libmysqld_la_SOURCES= $(libmysqlsources) $(sqlsources) +libmysqld_la_LIBADD = $(INC_LIB) ## XXX: any time the client interface changes, we'll need to bump ## the version info for libmysqld; however, it's possible for the @@ -184,7 +108,7 @@ endif ## libmysqlclient interface. Should we make a separate version ## string for the two? #libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@ -#CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la +#CLEANFILES = libmysqld.la BUILT_SOURCES = link_sources @@ -209,20 +133,6 @@ link_sources: @LN_CP_F@ $(top_builddir)/libmysql/$$f $$f; \ fi ; \ done; \ - if test -n "$(sqlstoragesources)" ; \ - then \ - for f in "$(sqlstoragesources)"; do \ - rm -f "$$f"; \ - @LN_CP_F@ `find $(srcdir)/../sql -name "$$f"` "$$f"; \ - done; \ - fi; \ - if test -n "$(storagesources)" ; \ - then \ - rm -f $(storagesources); \ - for f in $(storagesourceslinks); do \ - @LN_CP_F@ $(top_srcdir)/$$f . ; \ - done; \ - fi; \ rm -f client_settings.h; \ @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h \ client_settings.h; \ @@ -230,5 +140,5 @@ link_sources: clean-local: - rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) $(storagesources) | sed "s;\.lo;.c;g"`; \ + rm -f `echo $(sqlsources) $(libmysqlsources) | sed "s;\.lo;.c;g"`; \ rm -f client_settings.h diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index fd37f362960..1ef216b286d 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -37,12 +37,13 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir) \ -I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \ $(openssl_includes) LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs) -LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @LIBDL@ $(CXXLDFLAGS) \ - @NDB_SCI_LIBS@ +LDADD = @CLIENT_EXTRA_LDFLAGS@ \ + $(top_builddir)/libmysqld/libmysqld.la @LIBDL@ $(CXXLDFLAGS) \ + @ndbcluster_libs@ @NDB_SCI_LIBS@ mysqltest_embedded_LINK = $(CXXLINK) nodist_mysqltest_embedded_SOURCES = mysqltest.cc -mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a \ +mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.la \ @MYSQLD_EXTRA_LDFLAGS@ nodist_mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \ diff --git a/mysql-test/README.suites b/mysql-test/README.suites index 076fc216a0e..de49bef2715 100644 --- a/mysql-test/README.suites +++ b/mysql-test/README.suites @@ -32,6 +32,16 @@ files cannot. Special options are --timezone, --plugin-load, --result-file, --config-file-template, --default-time-zone, --force-restart +In particular, all --plugin-load instances on the command line (on the +combined command line, assembled from different .opt and combinations +files) are merged into one. That is, if, say, test-master.opt file contains +--plugin-load=aaa.so and suite.opt has --plugin-load=bbb.so that mysqld +will get --plugin-load=aaa.so:bbb.so. Also, empty --plugin-load options are +removed from the command line. Which means that one can safely specify +--plugin-load=$AAA_SO and if aaa.so was not built (perhaps, the plugin was +statically linked into the server), the .opt file will not result in the +invalid command line option that can cause the server to refuse to start. + ========================== A suite can have suite.pm file in the suitedir. It must declare a package that inherits from My::Suite. diff --git a/mysql-test/collections/default.daily b/mysql-test/collections/default.daily index c71297878f7..0503bd49f73 100644 --- a/mysql-test/collections/default.daily +++ b/mysql-test/collections/default.daily @@ -1,5 +1,3 @@ -perl mysql-test-run.pl --timer --force --comment=rpl_ndb_row --vardir=var-rpl_ndb_row --suite=rpl_ndb,ndb --mysqld=--binlog-format=row --experimental=collections/default.experimental - perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index f84337660ea..91dada3ee05 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -12,9 +12,10 @@ funcs_1.ndb* # joro : NDB tests marked as experiment funcs_2.ndb_charset # joro : NDB tests marked as experimental as agreed with bochklin +innodb_plugin.* @solaris # Bug#56063 InnoDB Plugin mysql-tests fail on Solaris + main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists main.func_str @solaris # joro: Bug#40928 -main.plugin_load @solaris # Bug#42144 main.sp @solaris # joro : Bug#54138 main.outfile_loaddata @solaris # joro : Bug #46895 @@ -44,3 +45,6 @@ parts.partition_syntax_ndb # joro : NDB tests marked as experiment parts.partition_value_ndb # joro : NDB tests marked as experimental as agreed with bochklin main.mysqlhotcopy_myisam # horst: due to bug#54129 main.mysqlhotcopy_archive # horst: due to bug#54129 +main.gis-rtree # svoj: due to BUG#38965 +main.type_float # svoj: due to BUG#38965 +main.type_newdecimal # svoj: due to BUG#38965 diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 1ae17398596..a3c7d032c32 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -1,5 +1,5 @@ # Requires statement logging --- source include/have_binlog_format_mixed_or_statement.inc +-- source include/have_binlog_format_statement.inc # See if replication of a "LOAD DATA in an autoincrement column" # Honours autoincrement values diff --git a/mysql-test/extra/rpl_tests/rpl_stm_create_if_not_exists.test b/mysql-test/extra/rpl_tests/rpl_stm_create_if_not_exists.test new file mode 100644 index 00000000000..65d2483dc4b --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_stm_create_if_not_exists.test @@ -0,0 +1,235 @@ +--echo +--echo +connection master; + +if ($is_temporary) +{ + --let $_temporary=TEMPORARY +} + +CREATE TABLE t2(c1 INT, c2 char(10)); +INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc'); + +--echo +--echo # The original query should be binlogged if the table does not exist. +--echo # ------------------------------------------------------------------ +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY) + SELECT 'abc' AS c3, 1 AS c4; +source include/show_binlog_events.inc; + +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} + +--echo +--echo # The statement should be binlogged as two events. one is +--echo # 'CREATE $_temporary TABLE IF NOT EXISTS ..', another one is +--echo # 'INSERT ... SELECT'. +--echo # ------------------------------------------------------------------ +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + SELECT 'abc', 2; +source include/show_binlog_events.inc; + +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} + +--echo +--echo # Verify if it can be binlogged with right database name when the table +--echo # is not in the default database +--echo +--disable_warnings +DROP DATABASE IF EXISTS db1; +--enable_warnings +CREATE DATABASE db1; +USE db1; + +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS test.t1 + SELECT 'abc', 20; +source include/show_binlog_events.inc; + +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} +USE test; +DROP DATABASE db1; + +--echo +--echo # It should be binlogged as 'REPLACE ... SELECT' +--echo # if the original statement has option REPLACE +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + REPLACE SELECT '123', 2; +source include/show_binlog_events.inc; + +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} + +--echo +--echo # It should be binlogged as 'INSERT IGNORE... SELECT' +--echo # if the original statement has option IGNORE +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + IGNORE SELECT '123', 2; +source include/show_binlog_events.inc; + +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} + +--echo +--echo # Nothing should be binlogged if error happens and no any row is inserted +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +--error ER_DUP_ENTRY +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + SELECT '123', 2; +source include/show_binlog_events.inc; +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} + +--echo +--echo # Verify it can binlog well when there are some braces('(') +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + (SELECT '123', 3) UNION (SELECT '123', 4); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + IGNORE (SELECT '123', 3) UNION (SELECT '123', 4); +source include/show_binlog_events.inc; + +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} + +if (!$is_temporary) +{ + --echo + --echo # Throw a warning that table already exists and don't insert anything + --echo + CREATE VIEW t3 AS SELECT * FROM t2; + let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + + CREATE TABLE IF NOT EXISTS t3 + SELECT '123', 2; + source include/show_binlog_events.inc; + DROP VIEW t3; +} + +--echo +--echo # The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER +--echo + +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +--enable_warnings +eval CREATE PROCEDURE p1(IN a INT) + CREATE $_temporary TABLE IF NOT EXISTS t1 SELECT '123', a; + +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +call p1(500); +call p1(600); +source include/show_binlog_events.inc; +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} +DROP PROCEDURE p1; + +--echo +--echo # The statement can be binlogged correctly when it is in a prepared statement +--echo +eval PREPARE stm FROM "CREATE $_temporary TABLE IF NOT EXISTS t1 SELECT '123', ?"; + +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +SET @a= 700; +EXECUTE stm USING @a; +SET @a= 800; +EXECUTE stm USING @a; +source include/show_binlog_events.inc; +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} + +--echo +--echo # The statement can be binlogged correctly when it is in a conditional comment +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo # The whole statement in a conditional comment +eval /*!CREATE $_temporary TABLE IF NOT EXISTS t1 + SELECT 'abc', 900*/; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # There is an long comment before SELECT +eval /*!CREATE $_temporary /*blabla*/ TABLE IF NOT EXISTS t1 + SELECT 'abc', 901*/; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Conditional comment starts just from SELECT +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + /*!SELECT 'abc',*/ 902; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Only SELECT keyword is in the conditional comment +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + /*!SELECT*/ /*!'abc',*/ 904; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Conditional comment is after SELECT keyword +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + SELECT /*!'abc',*/ 903; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Conditional comment ends just before SELECT keyword +eval /*!CREATE $_temporary TABLE IF NOT EXISTS t1 + */SELECT 'abc', 905; +source include/show_binlog_events.inc; + +if (!$is_temporary) +{ + let $diff_table= test.t1; + source include/rpl_diff_tables.inc; +} + +DROP TABLE t2; +eval DROP $_temporary TABLE t1; + diff --git a/mysql-test/include/cleanup_fake_relay_log.inc b/mysql-test/include/cleanup_fake_relay_log.inc index 43aa46cb657..c55e2937242 100644 --- a/mysql-test/include/cleanup_fake_relay_log.inc +++ b/mysql-test/include/cleanup_fake_relay_log.inc @@ -9,8 +9,10 @@ --echo Cleaning up after setup_fake_relay_log.inc # Remove files. +--disable_warnings remove_file $_fake_relay_log; remove_file $_fake_relay_index; +--enable_warnings --disable_query_log eval SET @@global.relay_log_purge= $_fake_relay_log_purge; --enable_query_log diff --git a/mysql-test/include/diff_tables.inc b/mysql-test/include/diff_tables.inc index 81362e8643b..8a463686fdb 100644 --- a/mysql-test/include/diff_tables.inc +++ b/mysql-test/include/diff_tables.inc @@ -54,11 +54,12 @@ --echo Comparing tables $diff_table_1 and $diff_table_2 disable_query_log; - +disable_warnings; --error 0,1 --remove_file $MYSQLTEST_VARDIR/tmp/diff_table_1 --error 0,1 --remove_file $MYSQLTEST_VARDIR/tmp/diff_table_2 +enable_warnings; let $_diff_table=$diff_table_2; let $_diff_i=2; diff --git a/mysql-test/include/index_merge_ror_cpk.inc b/mysql-test/include/index_merge_ror_cpk.inc index cfc2ed3885e..3912aa34026 100644 --- a/mysql-test/include/index_merge_ror_cpk.inc +++ b/mysql-test/include/index_merge_ror_cpk.inc @@ -126,3 +126,19 @@ WHERE drop table t1; +--echo # +--echo # Bug#50402 Optimizer producing wrong results when using Index Merge on InnoDB +--echo # +CREATE TABLE t1 (f1 INT, PRIMARY KEY (f1)); +INSERT INTO t1 VALUES (2); +CREATE TABLE t2 (f1 INT, f2 INT, f3 char(1), + PRIMARY KEY (f1), KEY (f2), KEY (f3) ); +INSERT INTO t2 VALUES (1, 1, 'h'), (2, 3, 'h'), (3, 2, ''), (4, 2, ''); + +SELECT t1.f1 FROM t1 +WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; + +EXPLAIN SELECT t1.f1 FROM t1 +WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; + +DROP TABLE t1,t2; diff --git a/mysql-test/include/maria_empty_logs.inc b/mysql-test/include/maria_empty_logs.inc index cc93e214348..e8b6a423953 100644 --- a/mysql-test/include/maria_empty_logs.inc +++ b/mysql-test/include/maria_empty_logs.inc @@ -24,6 +24,7 @@ EOF --source include/mysqladmin_shutdown.inc +--disable_warnings if (!$mel_keep_control_file) { --error 0,1 @@ -73,6 +74,7 @@ remove_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log.00000020; -- error 0,1 remove_file $MYSQLD_DATADIR/maria_recovery.trace; +--enable_warnings append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; restart-maria_empty_logs.inc diff --git a/mysql-test/include/maria_make_snapshot.inc b/mysql-test/include/maria_make_snapshot.inc index 2f480ac1a45..8f45f6b63a9 100644 --- a/mysql-test/include/maria_make_snapshot.inc +++ b/mysql-test/include/maria_make_snapshot.inc @@ -26,12 +26,16 @@ if ($mms_copy) if ($mms_reverse_copy) { # do not call this without flushing target table first! + --disable_warnings --echo * copied $mms_tname$mms_table_to_use back for $mms_purpose -- error 0,1 remove_file $MYSQLD_DATADIR/mysqltest/$mms_tname$mms_table_to_use.MAD; + --enable_warnings copy_file $MYSQLD_DATADIR/mysqltest_for_$mms_purpose/$mms_tname$mms_table_to_use.MAD $MYSQLD_DATADIR/mysqltest/$mms_tname$mms_table_to_use.MAD; + --disable_warnings -- error 0,1 remove_file $MYSQLD_DATADIR/mysqltest/$mms_tname$mms_table_to_use.MAI; + --enable_warnings copy_file $MYSQLD_DATADIR/mysqltest_for_$mms_purpose/$mms_tname$mms_table_to_use.MAI $MYSQLD_DATADIR/mysqltest/$mms_tname$mms_table_to_use.MAI; } diff --git a/mysql-test/include/maria_make_snapshot_for_feeding_recovery.inc b/mysql-test/include/maria_make_snapshot_for_feeding_recovery.inc index 62f5250cab4..c204409de4d 100644 --- a/mysql-test/include/maria_make_snapshot_for_feeding_recovery.inc +++ b/mysql-test/include/maria_make_snapshot_for_feeding_recovery.inc @@ -31,8 +31,10 @@ while ($mms_table_to_use) let $mms_copy=0; let $MYSQLD_DATADIR= `SELECT @@datadir`; +--disable_warnings -- error 0,1 remove_file $MYSQLTEST_VARDIR/tmp/mms_for_$mms_purpose.maria_log_control; +--enable_warnings copy_file $MYSQLD_DATADIR/$MARIA_LOG/maria_log_control $MYSQLTEST_VARDIR/tmp/mms_for_$mms_purpose.maria_log_control; connection default; diff --git a/mysql-test/include/mix2.inc b/mysql-test/include/mix2.inc index 24e958e810f..ba11937dfb9 100644 --- a/mysql-test/include/mix2.inc +++ b/mysql-test/include/mix2.inc @@ -1910,7 +1910,7 @@ select hex(s1) from t4; drop table t1,t2,t3,t4; } -if (test_foreign_keys) +if ($test_foreign_keys) { eval create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=$engine_type; eval create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=$engine_type; @@ -2405,7 +2405,7 @@ drop table t1, t2, t3, t5, t6, t8, t9; } # End transactional tests -if (test_foreign_keys) +if ($test_foreign_keys) { # bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID" --error 1005 diff --git a/mysql-test/include/mysqlhotcopy.inc b/mysql-test/include/mysqlhotcopy.inc index b3fd5e47179..2596994b59a 100644 --- a/mysql-test/include/mysqlhotcopy.inc +++ b/mysql-test/include/mysqlhotcopy.inc @@ -75,7 +75,9 @@ USE hotcopy_test; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --list_files $MYSQLTEST_VARDIR/tmp/hotcopy_test #--exec rm -rf $MYSQLTEST_VARDIR/tmp/hotcopy_test +--disable_warnings --remove_files_wildcard $MYSQLTEST_VARDIR/tmp/hotcopy_test * +--enable_warnings --rmdir $MYSQLTEST_VARDIR/tmp/hotcopy_test # backup without full index files diff --git a/mysql-test/include/ndb_backup.inc b/mysql-test/include/ndb_backup.inc index 5262f1231a2..eef3bf2bd1e 100644 --- a/mysql-test/include/ndb_backup.inc +++ b/mysql-test/include/ndb_backup.inc @@ -18,8 +18,10 @@ CREATE TABLE helper1(c1 VARCHAR(20)); # dump raw data to file let $ndb_backup_file1= $MYSQLTEST_VARDIR/ndb_backup_tmp.dat; let $ndb_backup_file2= $MYSQLTEST_VARDIR/tmp.dat; +--disable_warnings --error 0,1 --remove_file $ndb_backup_file1 +--enable_warnings --exec $NDB_TOOLS_DIR/ndb_select_all --ndb-connectstring="$NDB_CONNECTSTRING" -d sys --delimiter=',' SYSTAB_0 > $ndb_backup_file1 # load the table from the raw data file eval LOAD DATA INFILE '$ndb_backup_file1' INTO TABLE helper1; diff --git a/mysql-test/include/ndb_backup_print.inc b/mysql-test/include/ndb_backup_print.inc index 7527f125686..69faa8f421b 100644 --- a/mysql-test/include/ndb_backup_print.inc +++ b/mysql-test/include/ndb_backup_print.inc @@ -1,7 +1,9 @@ --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults $ndb_restore_opts -b $the_backup_id -n 1 $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id $ndb_restore_filter > $MYSQLTEST_VARDIR/tmp/tmp.dat --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults $ndb_restore_opts -b $the_backup_id -n 2 $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id $ndb_restore_filter >> $MYSQLTEST_VARDIR/tmp/tmp.dat --exec sort $MYSQLTEST_VARDIR/tmp/tmp.dat +--disable_warnings --error 0,1 --remove_file $MYSQLTEST_VARDIR/tmp/tmp.dat +--enable_warnings --let ndb_restore_opts= --let ndb_restore_filter= diff --git a/mysql-test/include/not_blackhole.inc b/mysql-test/include/not_blackhole.inc new file mode 100644 index 00000000000..078927ec4ca --- /dev/null +++ b/mysql-test/include/not_blackhole.inc @@ -0,0 +1,5 @@ +if (`SELECT count(*) FROM information_schema.engines WHERE + (support = 'YES' OR support = 'DEFAULT') AND + engine = 'blackhole'`){ + skip Blackhole engine enabled; +} diff --git a/mysql-test/include/percona_query_response_time_show.inc b/mysql-test/include/percona_query_response_time_show.inc index 761b2c6f0df..709abf9872e 100644 --- a/mysql-test/include/percona_query_response_time_show.inc +++ b/mysql-test/include/percona_query_response_time_show.inc @@ -1,7 +1,8 @@ -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; diff --git a/mysql-test/include/rpl_diff_tables.inc b/mysql-test/include/rpl_diff_tables.inc index c3a45578a79..7fc68422c40 100644 --- a/mysql-test/include/rpl_diff_tables.inc +++ b/mysql-test/include/rpl_diff_tables.inc @@ -33,3 +33,4 @@ while (`SELECT "XX$_servers" <> "XX"`) --source include/diff_tables.inc connection $_slave; } +connection $_master; diff --git a/mysql-test/include/setup_fake_relay_log.inc b/mysql-test/include/setup_fake_relay_log.inc index 5b9e7f72fdd..fb035941a29 100644 --- a/mysql-test/include/setup_fake_relay_log.inc +++ b/mysql-test/include/setup_fake_relay_log.inc @@ -72,7 +72,7 @@ copy_file $fake_relay_log $_fake_relay_log; if (`SELECT LENGTH(@@secure_file_priv) > 0`) { - -- let $_file_priv_dir= `SELECT @@secure_file_priv`; + -- let $_file_priv_dir= `SELECT @@secure_file_priv` -- let $_suffix= `SELECT UUID()` -- let $_tmp_file= $_file_priv_dir/fake-index.$_suffix diff --git a/mysql-test/lib/My/Config.pm b/mysql-test/lib/My/Config.pm index 0955c1bb190..bf6629754a1 100644 --- a/mysql-test/lib/My/Config.pm +++ b/mysql-test/lib/My/Config.pm @@ -246,6 +246,8 @@ sub new { while ( my $line= <$F> ) { chomp($line); + # Remove any trailing CR from Windows edited files + $line=~ s/\cM$//; # [group] if ( $line =~ /^\[(.*)\]/ ) { diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm index 7725b025dd8..9f8de3e5830 100644 --- a/mysql-test/lib/My/ConfigFactory.pm +++ b/mysql-test/lib/My/ConfigFactory.pm @@ -30,6 +30,13 @@ sub get_basedir { return $basedir; } +sub get_testdir { + my ($self, $group)= @_; + my $testdir= $group->if_exist('testdir') || + $self->{ARGS}->{testdir}; + return $testdir; +} + sub fix_charset_dir { my ($self, $config, $group_name, $group)= @_; @@ -138,7 +145,9 @@ sub fix_secure_file_priv { sub fix_std_data { my ($self, $config, $group_name, $group)= @_; - return "$::opt_vardir/std_data"; + #return "$::opt_vardir/std_data"; + my $testdir= $self->get_testdir($group); + return "$testdir/std_data"; } sub ssl_supported { diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index 084ef408d5b..bdd6c7352ae 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -60,11 +60,12 @@ use My::Platform; my %running; my $_verbose= 0; +my $start_exit= 0; END { # Kill any children still running for my $proc (values %running){ - if ( $proc->is_child($$) ){ + if ( $proc->is_child($$) and ! $start_exit){ #print "Killing: $proc\n"; if ($proc->wait_one(0)){ $proc->kill(); @@ -149,6 +150,11 @@ sub new { push(@safe_args, "--"); push(@safe_args, $path); # The program safe_process should execute + + if ($start_exit) { # Bypass safe_process instead, start program directly + @safe_args= (); + $safe_path= $path; + } push(@safe_args, @$$args); print "### safe_path: ", $safe_path, " ", join(" ", @safe_args), "\n" @@ -534,6 +540,13 @@ sub wait_all { } } +# +# Set global flag to tell all safe_process to exit after starting child +# + +sub start_exit { + $start_exit= 1; +} # # Check if any process has exited, but don't wait. diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 5536a1003ce..3ed2f072e9e 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -252,15 +252,11 @@ sub collect_one_suite } else { - $suitedir= my_find_dir($::basedir, - ["mysql-test/suite", - "mysql-test", - "share/mysql-test/suite", - "share/mysql-test", - "share/mysql/mysql-test/suite", - "share/mysql/mysql-test", + $suitedir= my_find_dir($suitedir, + ["suite", + ".", # Look in storage engine specific suite dirs - "storage/*/mysql-test-suites" + "../storage/*/mysql-test-suites" ], [$suite]); } @@ -573,7 +569,7 @@ sub optimize_cases { # Check that engine selected by # --default-storage-engine=<engine> is supported # ======================================================= - my %builtin_engines = ('myisam' => 1, 'memory' => 1); + my %builtin_engines = ('myisam' => 1, 'memory' => 1, 'csv' => 1); foreach my $opt ( @{$tinfo->{master_opt}} ) { my $default_engine= @@ -682,6 +678,13 @@ sub process_opts { next; } + $value= mtr_match_prefix($opt, "--testcase-timeout="); + if ( defined $value ) { + # Overrides test case timeout for this test + $tinfo->{'case-timeout'}= $value; + next; + } + # Ok, this was a real option, add it push(@{$tinfo->{$opt_name}}, $opt); } @@ -692,6 +695,7 @@ sub process_opts { } } + ############################################################################## # # Collect information about a single test case @@ -904,7 +908,7 @@ sub collect_one_test_case { { # Ndb is not supported, skip it $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No ndbcluster support"; + $tinfo->{'comment'}= "No ndbcluster support or ndb tests not enabled"; return $tinfo; } elsif ( $::opt_skip_ndbcluster ) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index c13e6a93319..a90c367178d 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -120,7 +120,7 @@ sub mtr_report_test ($) { my $timest = format_time(); my $fail = "fail"; - if ( $::opt_experimental ) + if ( @$::experimental_test_cases ) { # Find out if this test case is an experimental one, so we can treat # the failure as an expected failure instead of a regression. diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index eb1fad0bbb2..1557170f3cf 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -111,12 +111,24 @@ my $path_vardir_trace; # unix formatted opt_vardir for trace files my $opt_tmpdir; # Path to use for tmp/ dir my $opt_tmpdir_pid; +my $opt_start; +my $opt_start_dirty; +my $opt_start_exit; +my $start_only; + END { if ( defined $opt_tmpdir_pid and $opt_tmpdir_pid == $$ ) { - # Remove the tempdir this process has created - mtr_verbose("Removing tmpdir '$opt_tmpdir"); - rmtree($opt_tmpdir); + if (!$opt_start_exit) + { + # Remove the tempdir this process has created + mtr_verbose("Removing tmpdir $opt_tmpdir"); + rmtree($opt_tmpdir); + } + else + { + mtr_warning("tmpdir $opt_tmpdir should be removed after the server has finished"); + } } } @@ -191,8 +203,8 @@ our $opt_client_debugger; my $config; # The currently running config my $current_config_name; # The currently running config file template -our $opt_experimental; -our $experimental_test_cases; +our @opt_experimentals; +our $experimental_test_cases= []; my $baseport; # $opt_build_thread may later be set from $opt_port_base @@ -216,18 +228,16 @@ my $opt_suite_timeout = $ENV{MTR_SUITE_TIMEOUT} || 360; # minutes my $opt_shutdown_timeout= $ENV{MTR_SHUTDOWN_TIMEOUT} || 10; # seconds my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds -sub testcase_timeout { return $opt_testcase_timeout * 60; }; sub suite_timeout { return $opt_suite_timeout * 60; }; sub check_timeout { return $opt_testcase_timeout * 6; }; -my $opt_start; -my $opt_start_dirty; -my $start_only; my $opt_wait_all; +my $opt_user_args; my $opt_repeat= 1; my $opt_retry= 1; my $opt_retry_failure= env_or_val(MTR_RETRY_FAILURE => 2); my $opt_reorder= 1; +my $opt_force_restart= 0; my $opt_strace_client; @@ -245,9 +255,21 @@ my $opt_callgrind; my %mysqld_logs; my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions. +sub testcase_timeout ($) { + my ($tinfo)= @_; + if (exists $tinfo->{'case-timeout'}) { + # Return test specific timeout if *longer* that the general timeout + my $test_to= $tinfo->{'case-timeout'}; + $test_to*= 10 if $opt_valgrind; + return $test_to * 60 if $test_to > $opt_testcase_timeout; + } + return $opt_testcase_timeout * 60; +} + our $opt_warnings= 1; -our $opt_skip_ndbcluster= 0; +our $opt_include_ndbcluster= 0; +our $opt_skip_ndbcluster= 1; my $exe_ndbd; my $exe_ndb_mgmd; @@ -375,6 +397,12 @@ sub main { mtr_report("Using parallel: $opt_parallel"); } + if ($opt_parallel > 1 && $opt_start_exit) { + mtr_warning("Parallel and --start-and-exit cannot be combined\n" . + "Setting parallel to 1"); + $opt_parallel= 1; + } + # Create server socket on any free port my $server = new IO::Socket::INET ( @@ -415,6 +443,8 @@ sub main { my ($prefix, $fail, $completed, $extra_warnings)= run_test_server($server, $tests, $opt_parallel); + exit(0) if $opt_start_exit; + # Send Ctrl-C to any children still running kill("INT", keys(%children)); @@ -893,6 +923,7 @@ sub command_line_setup { # Control what test suites or cases to run 'force' => \$opt_force, 'with-ndbcluster-only' => \&collect_option, + 'include-ndbcluster' => \$opt_include_ndbcluster, 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster, 'suite|suites=s' => \$opt_suites, 'skip-rpl' => \&collect_option, @@ -902,7 +933,7 @@ sub command_line_setup { 'big-test' => \$opt_big_test, 'combination=s' => \@opt_combinations, 'skip-combinations' => \&collect_option, - 'experimental=s' => \$opt_experimental, + 'experimental=s' => \@opt_experimentals, 'skip-im' => \&ignore_option, 'staging-run' => \$opt_staging_run, @@ -976,13 +1007,16 @@ sub command_line_setup { 'report-features' => \$opt_report_features, 'comment=s' => \$opt_comment, 'fast' => \$opt_fast, + 'force-restart' => \$opt_force_restart, 'reorder!' => \$opt_reorder, 'enable-disabled' => \&collect_option, 'verbose+' => \$opt_verbose, 'verbose-restart' => \&report_option, 'sleep=i' => \$opt_sleep, 'start-dirty' => \$opt_start_dirty, + 'start-and-exit' => \$opt_start_exit, 'start' => \$opt_start, + 'user-args' => \$opt_user_args, 'wait-all' => \$opt_wait_all, 'print-testcases' => \&collect_option, 'repeat=i' => \$opt_repeat, @@ -1088,43 +1122,47 @@ sub command_line_setup { mtr_print_thick_line('#'); } - if ( $opt_experimental ) + if ( @opt_experimentals ) { # $^O on Windows considered not generic enough my $plat= (IS_WINDOWS) ? 'windows' : $^O; - # read the list of experimental test cases from the file specified on + # read the list of experimental test cases from the files specified on # the command line - open(FILE, "<", $opt_experimental) or mtr_error("Can't read experimental file: $opt_experimental"); - mtr_report("Using experimental file: $opt_experimental"); $experimental_test_cases = []; - while(<FILE>) { - chomp; - # remove comments (# foo) at the beginning of the line, or after a - # blank at the end of the line - s/( +|^)#.*$//; - # If @ platform specifier given, use this entry only if it contains - # @<platform> or @!<xxx> where xxx != platform - if (/\@.*/) - { - next if (/\@!$plat/); - next unless (/\@$plat/ or /\@!/); - # Then remove @ and everything after it - s/\@.*$//; - } - # remove whitespace - s/^ +//; - s/ +$//; - # if nothing left, don't need to remember this line - if ( $_ eq "" ) { - next; + foreach my $exp_file (@opt_experimentals) + { + open(FILE, "<", $exp_file) + or mtr_error("Can't read experimental file: $exp_file"); + mtr_report("Using experimental file: $exp_file"); + while(<FILE>) { + chomp; + # remove comments (# foo) at the beginning of the line, or after a + # blank at the end of the line + s/( +|^)#.*$//; + # If @ platform specifier given, use this entry only if it contains + # @<platform> or @!<xxx> where xxx != platform + if (/\@.*/) + { + next if (/\@!$plat/); + next unless (/\@$plat/ or /\@!/); + # Then remove @ and everything after it + s/\@.*$//; + } + # remove whitespace + s/^ +//; + s/ +$//; + # if nothing left, don't need to remember this line + if ( $_ eq "" ) { + next; + } + # remember what is left as the name of another test case that should be + # treated as experimental + print " - $_\n"; + push @$experimental_test_cases, $_; } - # remember what is left as the name of another test case that should be - # treated as experimental - print " - $_\n"; - push @$experimental_test_cases, $_; + close FILE; } - close FILE; } foreach my $arg ( @ARGV ) @@ -1398,7 +1436,7 @@ sub command_line_setup { # -------------------------------------------------------------------------- # Modified behavior with --start options # -------------------------------------------------------------------------- - if ($opt_start or $opt_start_dirty) { + if ($opt_start or $opt_start_dirty or $opt_start_exit) { collect_option ('quick-collect', 1); $start_only= 1; } @@ -1411,12 +1449,23 @@ sub command_line_setup { } # -------------------------------------------------------------------------- + # Check use of user-args + # -------------------------------------------------------------------------- + + if ($opt_user_args) { + mtr_error("--user-args only valid with --start options") + unless $start_only; + mtr_error("--user-args cannot be combined with named suites or tests") + if $opt_suites || @opt_cases; + } + + # -------------------------------------------------------------------------- # Check use of wait-all # -------------------------------------------------------------------------- if ($opt_wait_all && ! $start_only) { - mtr_error("--wait-all can only be used with --start or --start-dirty"); + mtr_error("--wait-all can only be used with --start options"); } # -------------------------------------------------------------------------- @@ -2154,6 +2203,12 @@ sub environment_setup { # Create an environment variable to make it possible # to detect that valgrind is being used from test cases $ENV{'VALGRIND_TEST'}= $opt_valgrind; + + # Add dir of this perl to aid mysqltest in finding perl + my $perldir= dirname($^X); + my $pathsep= ":"; + $pathsep= ";" if IS_WINDOWS && ! IS_CYGWIN; + $ENV{'PATH'}= "$ENV{'PATH'}".$pathsep.$perldir; } @@ -2478,6 +2533,11 @@ sub fix_vs_config_dir () { sub check_ndbcluster_support ($) { my $mysqld_variables= shift; + if ($opt_include_ndbcluster) + { + $opt_skip_ndbcluster= 0; + } + if ($opt_skip_ndbcluster) { mtr_report(" - skipping ndbcluster"); @@ -2987,6 +3047,7 @@ sub default_mysqld { my $config= My::ConfigFactory->new_config ( { basedir => $basedir, + testdir => $glob_mysql_test_dir, template_path => "include/default_my.cnf", vardir => $opt_vardir, tmpdir => $opt_tmpdir, @@ -3262,7 +3323,8 @@ sub check_testcase($$) my %started; foreach my $mysqld ( mysqlds() ) { - if ( defined $mysqld->{'proc'} ) + # Skip if server has been restarted with additional options + if ( defined $mysqld->{'proc'} && ! exists $mysqld->{'restart_opts'} ) { my $proc= start_check_testcase($tinfo, $mode, $mysqld); $started{$proc->pid()}= $proc; @@ -3712,6 +3774,7 @@ sub run_testcase ($$) { $config= My::ConfigFactory->new_config ( { basedir => $basedir, + testdir => $glob_mysql_test_dir, template_path => $tinfo->{template_path}, extra_template_path => $tinfo->{extra_template_path}, vardir => $opt_vardir, @@ -3755,6 +3818,11 @@ sub run_testcase ($$) { # Write start of testcase to log mark_log($path_current_testlog, $tinfo); + # Make sure the safe_process also exits from now on + if ($opt_start_exit) { + My::SafeProcess->start_exit(); + } + if (start_servers($tinfo)) { report_failure_and_restart($tinfo); @@ -3779,6 +3847,18 @@ sub run_testcase ($$) { mtr_print ($mysqld->name() . " " . $mysqld->value('port') . " " . $mysqld->value('socket')); } + if ( $opt_start_exit ) + { + mtr_print("Server(s) started, not waiting for them to finish"); + if (IS_WINDOWS) + { + POSIX::_exit(0); # exit hangs here in ActiveState Perl + } + else + { + exit(0); + } + } mtr_print("Waiting for server(s) to exit..."); if ( $opt_wait_all ) { My::SafeProcess->wait_all(); @@ -3797,7 +3877,7 @@ sub run_testcase ($$) { } } - my $test_timeout= start_timer(testcase_timeout()); + my $test_timeout= start_timer(testcase_timeout($tinfo)); do_before_run_mysqltest($tinfo); @@ -3902,6 +3982,9 @@ sub run_testcase ($$) { # Try to get reason from test log file find_testcase_skipped_reason($tinfo); mtr_report_test_skipped($tinfo); + # Restart if skipped due to missing perl, it may have had side effects + stop_all_servers($opt_shutdown_timeout) + if ($tinfo->{'comment'} =~ /^perl not found/); } elsif ( $res == 65 ) { @@ -4008,7 +4091,7 @@ sub run_testcase ($$) { { my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log"; $tinfo->{comment}= - "Test case timeout after ".testcase_timeout(). + "Test case timeout after ".testcase_timeout($tinfo). " seconds\n\n"; # Add 20 last executed commands from test case log file if (-e $log_file_name) @@ -4017,7 +4100,7 @@ sub run_testcase ($$) { "== $log_file_name == \n". mtr_lastlinesfromfile($log_file_name, 20)."\n"; } - $tinfo->{'timeout'}= testcase_timeout(); # Mark as timeout + $tinfo->{'timeout'}= testcase_timeout($tinfo); # Mark as timeout run_on_all($tinfo, 'analyze-timeout'); report_failure_and_restart($tinfo); @@ -4035,7 +4118,7 @@ sub run_testcase ($$) { sub _preserve_error_log_names { my ($mysqld)= @_; my $error_log_file= $mysqld->if_exist('#log-error'); - return unless $error_log_file and -r $error_log_file; + return (undef, undef) unless $error_log_file; my $error_log_dir= dirname($error_log_file); my $save_name= $error_log_dir ."/../". $mysqld->name() .".error.log"; return ($error_log_file, $save_name); @@ -4237,6 +4320,7 @@ sub extract_warning_lines ($) { qr/Slave SQL thread retried transaction/, qr/Slave \(additional info\)/, qr/Incorrect information in file/, + qr/Incorrect key file for table .*crashed.*/, qr/Slave I\/O: Get master SERVER_ID failed with error:.*/, qr/Slave I\/O: Get master clock failed with error:.*/, qr/Slave I\/O: Get master COLLATION_SERVER failed with error:.*/, @@ -4250,7 +4334,8 @@ sub extract_warning_lines ($) { qr/Slave: Operation DROP USER failed for 'create_rout_db'/, qr|Checking table: '\./mtr/test_suppressions'|, qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|, - qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired| + qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired|, + qr|InnoDB: Error: table 'test/bug39438'|, ); my $matched_lines= []; @@ -4496,6 +4581,16 @@ sub check_expected_crash_and_restart { next; } + # If last line begins "restart:", the rest of the line is read as + # extra command line options to add to the restarted mysqld. + # Anything other than 'wait' or 'restart:' (with a colon) will + # result in a restart with original mysqld options. + if ($last_line =~ /restart:(.+)/) { + my @rest_opt= split(' ', $1); + $mysqld->{'restart_opts'}= \@rest_opt; + } else { + delete $mysqld->{'restart_opts'}; + } unlink($expect_file); # Start server with same settings as last time @@ -4734,7 +4829,7 @@ sub mysqld_arguments ($$$) { mtr_add_arg($args, "%s--disable-sync-frm"); - if (!using_extern() and $mysql_version_id >= 50106 ) + if (!using_extern() and $mysql_version_id >= 50106 && !$opt_user_args) { # Turn on logging to file and tables mtr_add_arg($args, "%s--log-output=table,file"); @@ -4772,7 +4867,7 @@ sub mysqld_arguments ($$$) { } } $opt_skip_core = $found_skip_core; - if ( !$found_skip_core ) + if ( !$found_skip_core && !$opt_user_args ) { mtr_add_arg($args, "%s", "--core-file"); } @@ -4780,7 +4875,7 @@ sub mysqld_arguments ($$$) { # Enable the debug sync facility, set default wait timeout. # Facility stays disabled if timeout value is zero. mtr_add_arg($args, "--loose-debug-sync-timeout=%s", - $opt_debug_sync_timeout); + $opt_debug_sync_timeout) unless $opt_user_args; return $args; } @@ -4812,7 +4907,13 @@ sub mysqld_start ($$) { } mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld')); - mysqld_arguments($args,$mysqld,$extra_opts); + + # Add any additional options from an in-test restart + my @all_opts= @$extra_opts; + if (exists $mysqld->{'restart_opts'}) { + push (@all_opts, @{$mysqld->{'restart_opts'}}); + } + mysqld_arguments($args,$mysqld,\@all_opts); if ( $opt_debug ) { @@ -4955,6 +5056,11 @@ sub server_need_restart { return 1; } + if ( $opt_force_restart ) { + mtr_verbose_restart($server, "forced restart turned on"); + return 1; + } + if ( $tinfo->{template_path} ne $current_config_name) { mtr_verbose_restart($server, "using different config file"); @@ -5005,7 +5111,10 @@ sub server_need_restart { my $extra_opts= get_extra_opts($server, $tinfo); my $started_opts= $server->{'started_opts'}; - if (!My::Options::same($started_opts, $extra_opts) ) + # Also, always restart if server had been restarted with additional + # options within test. + if (!My::Options::same($started_opts, $extra_opts) || + exists $server->{'restart_opts'}) { my $use_dynamic_option_switch= 0; if (!$use_dynamic_option_switch) @@ -5074,6 +5183,9 @@ sub stopped { return grep(!defined $_, map($_->{proc}, @_)); } sub get_extra_opts { + # No extra options if --user-args + return \@opt_extra_mysqld_opt if $opt_user_args; + my ($mysqld, $tinfo)= @_; my $opts= @@ -5655,7 +5767,8 @@ Options to control what test suites or cases to run force Continue to run the suite after failure with-ndbcluster-only Run only tests that include "ndb" in the filename - skip-ndb[cluster] Skip all tests that need cluster + skip-ndb[cluster] Skip all tests that need cluster. Default. + include-ndb[cluster] Enable all tests that need cluster do-test=PREFIX or REGEX Run test cases which name are prefixed with PREFIX or fulfills REGEX @@ -5768,13 +5881,19 @@ Misc options startup settings for the first specified test case Example: $0 --start alias & + start-and-exit Same as --start, but mysql-test-run terminates and + leaves just the server running start-dirty Only start the servers (without initialization) for the first specified test case + user-args In combination with start* and no test name, drops + arguments to mysqld except those speficied with + --mysqld (if any) wait-all If --start or --start-dirty option is used, wait for all servers to exit before finishing the process fast Run as fast as possible, dont't wait for servers to shutdown etc. - parallel=N Run tests in N parallel threads (default 1) + force-restart Always restart servers between tests + parallel=N Run tests in N parallel threads (default=1) Use parallel=auto for auto-setting of N repeat=N Run each test N number of times retry=N Retry tests that fail up to N times (default $opt_retry). diff --git a/mysql-test/r/alter_table_trans.result b/mysql-test/r/alter_table_trans.result new file mode 100644 index 00000000000..3dd5c00d3d8 --- /dev/null +++ b/mysql-test/r/alter_table_trans.result @@ -0,0 +1,6 @@ +drop table if exists t1,t2; +CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb; +ALTER TABLE t1 RENAME TO t2, DISABLE KEYS; +Warnings: +Note 1031 Table storage engine for 't1' doesn't have this option +DROP TABLE t2; diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index e2eebdfc992..1cff420e34e 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5138,7 +5138,7 @@ insert t1 values (1),(2),(3),(4),(5); truncate table t1; affected rows: 0 drop table t1; -create table t1 (v varchar(32) not null); +create table t1 (v varchar(32) not null) engine=csv; insert into t1 values ('def'),('abc'),('hij'),('3r4f'); select * from t1; v @@ -5146,14 +5146,14 @@ def abc hij 3r4f -alter table t1 change v v2 varchar(32); +alter table t1 change v v2 varchar(32) not null; select * from t1; v2 def abc hij 3r4f -alter table t1 change v2 v varchar(64); +alter table t1 change v2 v varchar(64) not null; select * from t1; v def @@ -5163,35 +5163,34 @@ hij update t1 set v = 'lmn' where v = 'hij'; select * from t1; v +lmn def abc -lmn 3r4f -alter table t1 add i int auto_increment not null primary key first; +alter table t1 add i int not null first; select * from t1; i v -1 def -2 abc -3 lmn -4 3r4f -update t1 set i=5 where i=3; +0 lmn +0 def +0 abc +0 3r4f +update t1 set i=3 where v = 'abc'; select * from t1; i v -1 def -2 abc -5 lmn -4 3r4f -alter table t1 change i i bigint; +3 abc +0 lmn +0 def +0 3r4f +alter table t1 change i i bigint not null; select * from t1; i v -1 def -2 abc -5 lmn -4 3r4f -alter table t1 add unique key (i, v); -select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn'); +3 abc +0 lmn +0 def +0 3r4f +select * from t1 where i between 2 and 4 and v in ('def','3r4f','abc'); i v -4 3r4f +3 abc drop table t1; create table bug15205 (val int(11) not null) engine=csv; create table bug15205_2 (val int(11) not null) engine=csv; diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 36025cbfb35..7d6fc30be67 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -358,4 +358,13 @@ INDEX(a), INDEX(b), INDEX(c)); INSERT INTO t1 VALUES (1,2,3), (4,5,6), (7,8,9); DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1; DROP TABLE t1; +# +# Bug #53034: Multiple-table DELETE statements not accepting +# "Access compatibility" syntax +# +CREATE TABLE t1 (id INT); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; +DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a; +DROP TABLE t1, t2, t3; End of 5.1 tests diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index b36f561578b..606f879b47f 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1713,4 +1713,15 @@ f1 f2 f3 f4 f1 = f2 NULL NULL NULL NULL NULL drop table t1; # +# Bug #54465: assert: field_types == 0 || field_types[field_pos] == +# MYSQL_TYPE_LONGLONG +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2); +SELECT MAX((SELECT 1 FROM t1 ORDER BY @var LIMIT 1)) m FROM t1 t2, t1 +ORDER BY t1.a; +m +1 +DROP TABLE t1; +# End of 5.1 tests diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index bbc5390895b..87b88692a34 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -194,7 +194,7 @@ date("1997-12-31 23:59:59.000001") as f8, time("1997-12-31 23:59:59.000001") as f9; describe t1; Field Type Null Key Default Extra -f1 date NO 0000-00-00 +f1 date YES NULL f2 datetime YES NULL f3 time YES NULL f4 time YES NULL diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 8b96a60b79c..5500eefda4c 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1335,4 +1335,12 @@ date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND) select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND); date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND) 0168-12-31 23:59:59 +CREATE TABLE t1(a DOUBLE NOT NULL); +INSERT INTO t1 VALUES (0),(9.216e-096); +# should not crash +SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a); +1 +1 +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 3e28227d542..3b18ee61336 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -707,10 +707,7 @@ numgeometries(b) IS NULL, numinteriorrings(b) IS NULL, numpoints(b) IS NULL, area(b) IS NULL, glength(b) IS NULL, srid(b) IS NULL, x(b) IS NULL, y(b) IS NULL from t1; -geometryfromtext(b) IS NULL geometryfromwkb(b) IS NULL astext(b) IS NULL aswkb(b) IS NULL geometrytype(b) IS NULL centroid(b) IS NULL envelope(b) IS NULL startpoint(b) IS NULL endpoint(b) IS NULL exteriorring(b) IS NULL pointn(b, 1) IS NULL geometryn(b, 1) IS NULL interiorringn(b, 1) IS NULL multipoint(b) IS NULL isempty(b) IS NULL issimple(b) IS NULL isclosed(b) IS NULL dimension(b) IS NULL numgeometries(b) IS NULL numinteriorrings(b) IS NULL numpoints(b) IS NULL area(b) IS NULL glength(b) IS NULL srid(b) IS NULL x(b) IS NULL y(b) IS NULL -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +ERROR 22007: Illegal non geometric '`test`.`t1`.`b`' value found during parsing select within(b, b) IS NULL, contains(b, b) IS NULL, overlaps(b, b) IS NULL, equals(b, b) IS NULL, disjoint(b, b) IS NULL, touches(b, b) IS NULL, @@ -725,10 +722,7 @@ point(b, b) IS NULL, linestring(b) IS NULL, polygon(b) IS NULL, multipoint(b) IS multilinestring(b) IS NULL, multipolygon(b) IS NULL, geometrycollection(b) IS NULL from t1; -point(b, b) IS NULL linestring(b) IS NULL polygon(b) IS NULL multipoint(b) IS NULL multilinestring(b) IS NULL multipolygon(b) IS NULL geometrycollection(b) IS NULL -0 1 1 1 1 1 1 -1 1 1 1 1 1 1 -0 1 1 1 1 1 1 +ERROR 22007: Illegal non geometric '`test`.`t1`.`b`' value found during parsing drop table t1; CREATE TABLE t1(a POINT) ENGINE=MyISAM; INSERT INTO t1 VALUES (NULL); @@ -1010,51 +1004,14 @@ f5 datetime YES NULL drop view v1; drop table t1; SELECT MultiPoint(12345,''); -MultiPoint(12345,'') -NULL -SELECT MultiPoint(123451,''); -MultiPoint(123451,'') -NULL -SELECT MultiPoint(1234512,''); -MultiPoint(1234512,'') -NULL -SELECT MultiPoint(12345123,''); -MultiPoint(12345123,'') -NULL -SELECT MultiLineString(12345,''); -MultiLineString(12345,'') -NULL -SELECT MultiLineString(123451,''); -MultiLineString(123451,'') -NULL -SELECT MultiLineString(1234512,''); -MultiLineString(1234512,'') -NULL -SELECT MultiLineString(12345123,''); -MultiLineString(12345123,'') -NULL -SELECT LineString(12345,''); -LineString(12345,'') -NULL -SELECT LineString(123451,''); -LineString(123451,'') -NULL -SELECT LineString(1234512,''); -LineString(1234512,'') -NULL -SELECT LineString(12345123,''); -LineString(12345123,'') -NULL -SELECT Polygon(12345,''); -Polygon(12345,'') -NULL -SELECT Polygon(123451,''); -Polygon(123451,'') -NULL -SELECT Polygon(1234512,''); -Polygon(1234512,'') -NULL -SELECT Polygon(12345123,''); -Polygon(12345123,'') -NULL +ERROR 22007: Illegal non geometric '12345' value found during parsing +SELECT 1 FROM (SELECT GREATEST(1,GEOMETRYCOLLECTION('00000','00000')) b FROM DUAL) AS d WHERE (LINESTRING(d.b)); +ERROR 22007: Illegal non geometric ''00000'' value found during parsing +# +# BUG#51875: crash when loading data into geometry function polyfromwkb +# +SET @a=0x00000000030000000100000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440; +SET @a=POLYFROMWKB(@a); +SET @a=0x00000000030000000000000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440; +SET @a=POLYFROMWKB(@a); End of 5.1 tests diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index cd1b4ae0218..c7850b7ce03 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -470,9 +470,10 @@ WHERE table2.f1 = 2 GROUP BY table1.f1, table2.f2 HAVING (table2.f2 = 8 AND table1.f1 >= 6); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables +1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort +1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where Warnings: -Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having 0 +Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having (('7' = 8) and (`test`.`table1`.`f1` >= 6)) EXPLAIN EXTENDED SELECT table1.f1, table2.f2 FROM t1 AS table1 @@ -481,9 +482,10 @@ WHERE table2.f1 = 2 GROUP BY table1.f1, table2.f2 HAVING (table2.f2 = 8); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables +1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort +1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where Warnings: -Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having 0 +Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having ('7' = 8) DROP TABLE t1; # # Bug#52336 Segfault / crash in 5.1 copy_fields (param=0x9872980) at sql_select.cc:15355 diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index ff00654aed8..6f1eca6f94b 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -581,3 +581,76 @@ WHERE `RUNID`= '' AND `SUBMITNR`= '' AND `ORDERNR`='' AND `PROGRAMM`='' AND `TESTID`='' AND `UCCHECK`=''; drop table t1; +# +# Bug#50402 Optimizer producing wrong results when using Index Merge on InnoDB +# +CREATE TABLE t1 (f1 INT, PRIMARY KEY (f1)); +INSERT INTO t1 VALUES (2); +CREATE TABLE t2 (f1 INT, f2 INT, f3 char(1), +PRIMARY KEY (f1), KEY (f2), KEY (f3) ); +INSERT INTO t2 VALUES (1, 1, 'h'), (2, 3, 'h'), (3, 2, ''), (4, 2, ''); +SELECT t1.f1 FROM t1 +WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; +f1 +2 +EXPLAIN SELECT t1.f1 FROM t1 +WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index +2 DEPENDENT SUBQUERY t2 index_merge f2,f3 f3,f2 2,5 NULL 1 Using intersect(f3,f2); Using where; Using index +DROP TABLE t1,t2; +# +# BUG#56862/640419: Wrong result with sort_union index merge when one +# of the merged index scans is the primary key scan +# +CREATE TABLE t1 ( +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +a int, +b int, +INDEX idx(a)) +ENGINE=INNODB; +INSERT INTO t1(a,b) VALUES +(11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500), +(3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800), +(6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700), +(13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000); +INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1; +INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1; +INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1 VALUES (1000000, 0, 0); +SET SESSION sort_buffer_size = 1024*36; +EXPLAIN +SELECT COUNT(*) FROM +(SELECT * FROM t1 +WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 11419 Using sort_union(idx,PRIMARY); Using where +SELECT COUNT(*) FROM +(SELECT * FROM t1 +WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; +COUNT(*) +6145 +EXPLAIN +SELECT COUNT(*) FROM +(SELECT * FROM t1 IGNORE INDEX(idx) +WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL # Select tables optimized away +2 DERIVED t1 ALL PRIMARY NULL NULL NULL # Using where +SELECT COUNT(*) FROM +(SELECT * FROM t1 IGNORE INDEX(idx) +WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; +COUNT(*) +6145 +DROP TABLE t1; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index 182455f8c06..a4dae5f556d 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1416,6 +1416,24 @@ WHERE `TESTID`='' AND `UCCHECK`=''; drop table t1; # +# Bug#50402 Optimizer producing wrong results when using Index Merge on InnoDB +# +CREATE TABLE t1 (f1 INT, PRIMARY KEY (f1)); +INSERT INTO t1 VALUES (2); +CREATE TABLE t2 (f1 INT, f2 INT, f3 char(1), +PRIMARY KEY (f1), KEY (f2), KEY (f3) ); +INSERT INTO t2 VALUES (1, 1, 'h'), (2, 3, 'h'), (3, 2, ''), (4, 2, ''); +SELECT t1.f1 FROM t1 +WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; +f1 +2 +EXPLAIN SELECT t1.f1 FROM t1 +WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 +2 DEPENDENT SUBQUERY t2 ref f2,f3 f2 5 1 Using where +DROP TABLE t1,t2; +# # Generic @@optimizer_switch tests (move those into a separate file if # we get another @@optimizer_switch user) # diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 4ed56bf3c56..df4c579ea1c 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -639,3 +639,18 @@ CREATE TABLE t2(f1 CHAR(1)); INSERT INTO t2 SELECT f1 FROM t1; DROP TABLE t1, t2; End of 5.0 tests. +# +# Bug#54106 assert in Protocol::end_statement, +# INSERT IGNORE ... SELECT ... UNION SELECT ... +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 (a, a) VALUES (1, 1); +ERROR 42000: Column 'a' specified twice +INSERT IGNORE t1 (a, a) VALUES (1, 1); +ERROR 42000: Column 'a' specified twice +INSERT IGNORE t1 (a, a) SELECT 1,1; +ERROR 42000: Column 'a' specified twice +INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2; +ERROR 42000: Column 'a' specified twice +DROP TABLE t1; diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index c60c6bfb3c8..96504df4b1e 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -1184,4 +1184,40 @@ NULL NULL 1 DROP TABLE t1, t2, mm1; +# +# Bug #54468: crash after item's print() function when ordering/grouping +# by subquery +# +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (), (); +SELECT 1 FROM t1 +GROUP BY +GREATEST(t1.a, +(SELECT 1 FROM +(SELECT t1.b FROM t1,t1 t2 +ORDER BY t1.a, t1.a LIMIT 1) AS d) +); +1 +1 +DROP TABLE t1; +# +# Bug #53544: Server hangs during JOIN query in stored procedure called +# twice in a row +# +CREATE TABLE t1(c INT); +INSERT INTO t1 VALUES (1), (2); +PREPARE stmt FROM "SELECT t2.c AS f1 FROM t1 LEFT JOIN + t1 t2 ON t1.c=t2.c RIGHT JOIN + t1 t3 ON t1.c=t3.c + GROUP BY f1;"; +EXECUTE stmt; +f1 +1 +2 +EXECUTE stmt; +f1 +1 +2 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index 2bdac08e7fd..7965e287da2 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -232,7 +232,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Warnings: -Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10))) where 1 +Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`))) where 1 SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM (t6, t7) LEFT JOIN @@ -553,7 +553,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`))) SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM t0,t1 @@ -649,7 +649,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) SELECT t9.a,t9.b FROM t9; a b @@ -840,7 +840,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) where (`test`.`t1`.`a` <= 2) +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) where (`test`.`t1`.`a` <= 2) CREATE INDEX idx_b ON t2(b); EXPLAIN EXTENDED SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b @@ -854,7 +854,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Warnings: -Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t3`.`a` = 1) and (`test`.`t3`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) where 1 +Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t3`.`a` = 1) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`)))) where 1 SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b FROM (t3,t4) LEFT JOIN @@ -916,7 +916,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) CREATE INDEX idx_b ON t4(b); CREATE INDEX idx_b ON t5(b); EXPLAIN EXTENDED @@ -966,7 +966,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) CREATE INDEX idx_b ON t8(b); EXPLAIN EXTENDED SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, @@ -1015,7 +1015,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) CREATE INDEX idx_b ON t1(b); CREATE INDEX idx_a ON t0(a); EXPLAIN EXTENDED @@ -1065,7 +1065,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b FROM t0,t1 @@ -1463,9 +1463,9 @@ join t5 on t5.a=t3.b) on t3.a=t2.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL X 1 SIMPLE t3 ref a a 5 test.t2.b X -1 SIMPLE t4 ref a a 5 test.t3.b X -1 SIMPLE t6 ref a a 5 test.t4.b X 1 SIMPLE t5 ref a a 5 test.t3.b X +1 SIMPLE t4 ref a a 5 test.t5.a X +1 SIMPLE t6 ref a a 5 test.t4.b X drop table t0, t1, t2, t3, t4, t5, t6, t7; create table t1 (a int); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -1479,7 +1479,7 @@ on (t1.a = t2.a); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 1 SIMPLE t2 ref a a 5 test.t1.a 1 -1 SIMPLE t3 ref a a 5 test.t2.a 1 +1 SIMPLE t3 ref a a 5 test.t1.a 1 drop table t1, t2, t3; CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, type varchar(10)); CREATE TABLE t2 (pid int NOT NULL PRIMARY KEY, type varchar(10)); @@ -1743,4 +1743,62 @@ ON t4.carrier = t1.carrier; COUNT(*) 6 DROP TABLE t1,t2,t3,t4,t5; +CREATE TABLE t1 ( +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +a int DEFAULT NULL, +KEY idx(a) +); +CREATE TABLE t2 ( +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +a int DEFAULT NULL, +KEY idx(a) +); +CREATE TABLE t3 ( +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +a int DEFAULT NULL, +KEY idx(a) +); +INSERT INTO t1 VALUES +(1,2), (2,7), (3,5), (4,7), (5,5), (6,NULL), (7,NULL), (8,9); +INSERT INTO t2 VALUES +(1,NULL), (4,2), (5,2), (3,4), (2,8); +INSERT INTO t3 VALUES +(1,9), (2,2), (3,5), (4,2), (5,7), (6,0), (7,5); +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a +FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a; +pk a pk a pk a +1 2 4 2 2 2 +1 2 4 2 4 2 +1 2 5 2 2 2 +1 2 5 2 4 2 +2 7 NULL NULL NULL NULL +3 5 NULL NULL NULL NULL +4 7 NULL NULL NULL NULL +5 5 NULL NULL NULL NULL +6 NULL NULL NULL NULL NULL +7 NULL NULL NULL NULL NULL +8 9 NULL NULL NULL NULL +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a +FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a +WHERE t2.pk IS NULL; +pk a pk a pk a +2 7 NULL NULL NULL NULL +3 5 NULL NULL NULL NULL +4 7 NULL NULL NULL NULL +5 5 NULL NULL NULL NULL +6 NULL NULL NULL NULL NULL +7 NULL NULL NULL NULL NULL +8 9 NULL NULL NULL NULL +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a +FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a +WHERE t3.pk IS NULL; +pk a pk a pk a +2 7 NULL NULL NULL NULL +3 5 NULL NULL NULL NULL +4 7 NULL NULL NULL NULL +5 5 NULL NULL NULL NULL +6 NULL NULL NULL NULL NULL +7 NULL NULL NULL NULL NULL +8 9 NULL NULL NULL NULL +DROP TABLE t1, t2, t3; End of 5.0 tests diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 8e438934b23..f9fb545bd0e 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1397,4 +1397,115 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1 DROP TABLE t1; +# +# Bug#49600: outer join of two single-row tables with joining attributes +# evaluated to nulls +create table t1 (a int, b int); +create table t2 (a int, b int); +insert into t1 values (1, NULL); +insert into t2 values (2, NULL); +select * from t1 left join t2 on t1.b=t2.b; +a b a b +1 NULL NULL NULL +select * from t1 left join t2 on t1.b=t2.b where 1=1; +a b a b +1 NULL NULL NULL +drop table t1,t2; +# +# Bug#53161: outer join in the derived table is erroneously converted +# into an inner join for a query with a group by clause +# +create table t1 (pk int not null primary key, a int not null); +create table t2 like t1; +create table t3 like t1; +create table t4 (pk int not null primary key); +insert into t1 values (1000, 1), (1001, 1); +insert into t2 values (2000, 2), (2001, 2); +insert into t3 values (3000, 3), (3001, 2); +insert into t4 values (4000), (4001); +explain extended +select t2.pk, +(select t3.pk+if(isnull(t4.pk),0,t4.pk) +from t3 left join t4 on t4.pk=t3.pk +where t3.pk=t2.pk+1000 limit 1 ) as t +from t1,t2 +where t2.pk=t1.pk+1000 and t1.pk>1000 +group by t2.pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using temporary; Using filesort +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 Using where; Using index +Warnings: +Note 1276 Field or reference 'test.t2.pk' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `test`.`t2`.`pk` AS `pk`,(select (`test`.`t3`.`pk` + if(isnull(`test`.`t4`.`pk`),0,`test`.`t4`.`pk`)) from `test`.`t3` left join `test`.`t4` on((`test`.`t4`.`pk` = `test`.`t3`.`pk`)) where (`test`.`t3`.`pk` = (`test`.`t2`.`pk` + 1000)) limit 1) AS `t` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`pk` = (`test`.`t1`.`pk` + 1000)) and (`test`.`t1`.`pk` > 1000)) group by `test`.`t2`.`pk` +select t2.pk, +(select t3.pk+if(isnull(t4.pk),0,t4.pk) +from t3 left join t4 on t4.pk=t3.pk +where t3.pk=t2.pk+1000 limit 1 ) as t +from t1,t2 +where t2.pk=t1.pk+1000 and t1.pk>1000 +group by t2.pk; +pk t +2001 3001 +drop table t1,t2,t3,t4; +# +# Bug#57024: Poor performance when conjunctive condition over the outer +# table is used in the on condition of an outer join +# +create table t1 (a int); +insert into t1 values (NULL), (NULL), (NULL), (NULL); +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 values (4), (2), (1), (3); +create table t2 like t1; +insert into t2 select if(t1.a is null, 10, t1.a) from t1; +create table t3 (a int, b int, index idx(a)); +insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101); +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK +flush status; +select sum(t3.b) from t1 left join t3 on t3.a=t1.a and t1.a is not null; +sum(t3.b) +1006 +show status like "handler_read%"; +Variable_name Value +Handler_read_first 0 +Handler_read_key 4 +Handler_read_next 5 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 1048581 +flush status; +select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10; +sum(t3.b) +1006 +show status like "handler_read%"; +Variable_name Value +Handler_read_first 0 +Handler_read_key 4 +Handler_read_next 5 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 1048581 +drop table t1,t2,t3; End of 5.1 tests diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 83dae077312..717437a0532 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -1574,7 +1574,7 @@ UNLOCK TABLES; # # Trigger on parent DELETE FROM t4 WHERE c1 = 4; -CREATE TRIGGER t4_ai AFTER INSERT ON t4 FOR EACH ROW SET @a=1; +CREATE TRIGGER t4_ai1 AFTER INSERT ON t4 FOR EACH ROW SET @a=1; SET @a=0; INSERT INTO t4 VALUES (4); SELECT @a; @@ -1586,10 +1586,13 @@ c1 2 3 4 -DROP TRIGGER t4_ai; +DROP TRIGGER t4_ai1; +CHECK TABLE t3; +Table Op Msg_type Msg_text +test.t3 check status OK # Trigger on parent under LOCK TABLES LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; -CREATE TRIGGER t4_ai AFTER INSERT ON t4 FOR EACH ROW SET @a=1; +CREATE TRIGGER t4_ai2 AFTER INSERT ON t4 FOR EACH ROW SET @a=1; SET @a=0; INSERT INTO t4 VALUES (4); SELECT @a; @@ -1602,12 +1605,15 @@ c1 3 4 4 -DROP TRIGGER t4_ai; +DROP TRIGGER t4_ai2; UNLOCK TABLES; +CHECK TABLE t3; +Table Op Msg_type Msg_text +test.t3 check status OK # # Trigger on child DELETE FROM t4 WHERE c1 = 4; -CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW SET @a=1; +CREATE TRIGGER t3_ai3 AFTER INSERT ON t3 FOR EACH ROW SET @a=1; SET @a=0; INSERT INTO t4 VALUES (4); SELECT @a; @@ -1624,10 +1630,13 @@ c1 3 4 33 -DROP TRIGGER t3_ai; +DROP TRIGGER t3_ai3; +CHECK TABLE t3; +Table Op Msg_type Msg_text +test.t3 check status OK # Trigger on child under LOCK TABLES LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; -CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW SET @a=1; +CREATE TRIGGER t3_ai4 AFTER INSERT ON t3 FOR EACH ROW SET @a=1; SET @a=0; INSERT INTO t4 VALUES (4); SELECT @a; @@ -1647,11 +1656,17 @@ c1 33 33 DELETE FROM t4 WHERE c1 = 33; -DROP TRIGGER t3_ai; +DROP TRIGGER t3_ai4; +CHECK TABLE t3; +Table Op Msg_type Msg_text +test.t3 check status OK # # Trigger with table use on child DELETE FROM t4 WHERE c1 = 4; -CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); +CREATE TRIGGER t3_ai5 AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); +SELECT COUNT(*) FROM t2; +COUNT(*) +1 INSERT INTO t4 VALUES (4); SELECT * FROM t4 ORDER BY c1; c1 @@ -1670,10 +1685,15 @@ c1 33 DELETE FROM t4 WHERE c1 = 22; DELETE FROM t4 WHERE c1 = 33; -DROP TRIGGER t3_ai; +DROP TRIGGER t3_ai5; +UNLOCK TABLES; +CHECK TABLE t2,t3; +Table Op Msg_type Msg_text +test.t2 check status OK +test.t3 check status OK # Trigger with table use on child under LOCK TABLES LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; -CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); +CREATE TRIGGER t3_ai6 AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); INSERT INTO t4 VALUES (4); SELECT * FROM t4 ORDER BY c1; c1 @@ -1692,10 +1712,44 @@ c1 4 22 33 -DROP TRIGGER t3_ai; +DROP TRIGGER t3_ai6; +UNLOCK TABLES; +check table t2,t3,t4; +Table Op Msg_type Msg_text +test.t2 check status OK +test.t3 check status OK +test.t4 check status OK DELETE FROM t4 WHERE c1 = 22; DELETE FROM t4 WHERE c1 = 33; +# Trigger with table use on child under different LOCK TABLES +DELETE FROM t4 WHERE c1 = 4; +LOCK TABLES t4 WRITE,t3 WRITE, t2 WRITE, t1 WRITE; +CREATE TRIGGER t3_ai7 AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); +INSERT INTO t4 VALUES (4); +SELECT * FROM t4 ORDER BY c1; +c1 +1 +2 +3 +4 +INSERT INTO t3 VALUES (33); +SELECT * FROM t4 ORDER BY c1; +c1 +1 +2 +3 +4 +22 +33 +DROP TRIGGER t3_ai7; UNLOCK TABLES; +check table t2,t3,t4; +Table Op Msg_type Msg_text +test.t2 check status OK +test.t3 check status OK +test.t4 check status OK +DELETE FROM t4 WHERE c1 = 22; +DELETE FROM t4 WHERE c1 = 33; # # Repair # @@ -1711,7 +1765,6 @@ c1 2 3 4 -4 LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; REPAIR TABLE t4; Table Op Msg_type Msg_text @@ -1725,7 +1778,6 @@ c1 2 3 4 -4 UNLOCK TABLES; # # Optimize @@ -1742,7 +1794,6 @@ c1 2 3 4 -4 LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; OPTIMIZE TABLE t4; Table Op Msg_type Msg_text @@ -1756,14 +1807,13 @@ c1 2 3 4 -4 UNLOCK TABLES; # # Checksum # CHECKSUM TABLE t4; Table Checksum -test.t4 46622073 +test.t4 149057747 CHECKSUM TABLE t2; Table Checksum test.t2 3700403066 @@ -1773,11 +1823,10 @@ c1 2 3 4 -4 LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; CHECKSUM TABLE t4; Table Checksum -test.t4 46622073 +test.t4 149057747 CHECKSUM TABLE t2; Table Checksum test.t2 3700403066 @@ -1787,7 +1836,6 @@ c1 2 3 4 -4 UNLOCK TABLES; # # Insert delayed @@ -1801,7 +1849,6 @@ c1 2 3 4 -4 33 LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; INSERT DELAYED INTO t4 VALUES(444); @@ -1814,7 +1861,6 @@ c1 2 3 4 -4 33 UNLOCK TABLES; DROP TABLE t1, t2, t3, t4; @@ -2250,4 +2296,45 @@ t2 WHERE b SOUNDS LIKE e AND d = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables DROP TABLE t2, t1; +# +# Bug#46339 - crash on REPAIR TABLE merge table USE_FRM +# +DROP TABLE IF EXISTS m1, t1; +CREATE TABLE t1 (c1 INT) ENGINE=MYISAM; +CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1) INSERT_METHOD=LAST; +LOCK TABLE m1 READ; +REPAIR TABLE m1 USE_FRM; +Table Op Msg_type Msg_text +test.m1 repair note The storage engine for the table doesn't support repair +UNLOCK TABLES; +REPAIR TABLE m1 USE_FRM; +Table Op Msg_type Msg_text +test.m1 repair note The storage engine for the table doesn't support repair +DROP TABLE m1,t1; +CREATE TABLE m1 (f1 BIGINT) ENGINE=MRG_MyISAM UNION(t1); +REPAIR TABLE m1 USE_FRM; +Table Op Msg_type Msg_text +test.m1 repair Error Can't open table +test.m1 repair error Corrupt +CREATE TABLE t1 (f1 BIGINT) ENGINE = MyISAM; +REPAIR TABLE m1 USE_FRM; +Table Op Msg_type Msg_text +test.m1 repair note The storage engine for the table doesn't support repair +REPAIR TABLE m1; +Table Op Msg_type Msg_text +test.m1 repair note The storage engine for the table doesn't support repair +DROP TABLE m1, t1; +CREATE TEMPORARY TABLE m1 (f1 BIGINT) ENGINE=MRG_MyISAM UNION(t1); +REPAIR TABLE m1 USE_FRM; +Table Op Msg_type Msg_text +test.m1 repair Error Table 'test.m1' doesn't exist +test.m1 repair error Corrupt +CREATE TEMPORARY TABLE t1 (f1 BIGINT) ENGINE=MyISAM; +REPAIR TABLE m1 USE_FRM; +Table Op Msg_type Msg_text +m1 repair error Cannot repair temporary table from .frm file +REPAIR TABLE m1; +Table Op Msg_type Msg_text +test.m1 repair note The storage engine for the table doesn't support repair +DROP TABLE m1, t1; End of 5.1 tests diff --git a/mysql-test/r/merge_debug.result b/mysql-test/r/merge_debug.result new file mode 100644 index 00000000000..b857ff597f2 --- /dev/null +++ b/mysql-test/r/merge_debug.result @@ -0,0 +1,24 @@ +set global storage_engine=myisam; +set session storage_engine=myisam; +drop table if exists crashed,t2,t3,t4; +SET @orig_debug=@@debug; +CREATE TABLE crashed (c1 INT); +CREATE TABLE t2 (c1 INT); +CREATE TABLE t3 (c1 INT); +CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(crashed,t2,t3) INSERT_METHOD=LAST; +INSERT INTO crashed VALUES (10); +INSERT INTO t2 VALUES (20); +INSERT INTO t3 VALUES (30); +LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, crashed WRITE; +SET GLOBAL debug="+d,*,myisam_pretend_crashed_table_on_open"; +CREATE TRIGGER t1_ai AFTER INSERT ON crashed FOR EACH ROW INSERT INTO t2 VALUES(29); +SET GLOBAL debug=@orig_debug; +INSERT INTO t4 VALUES (39); +ERROR HY000: Table 't4' was not locked with LOCK TABLES +INSERT INTO crashed VALUES (11); +ERROR HY000: Table 'crashed' was not locked with LOCK TABLES +INSERT INTO t2 VALUES (21); +INSERT INTO t3 VALUES (31); +UNLOCK TABLES; +DROP TRIGGER t1_ai; +DROP TABLE t4,crashed,t2,t3; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index ae72f416c79..d77ad1d2953 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -639,4 +639,24 @@ SET SESSION sql_safe_updates = 1; UPDATE IGNORE t1, t1 t1a SET t1.a = 1 WHERE t1a.a = 1; ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column DROP TABLE t1; +# +# Bug#54543: update ignore with incorrect subquery leads to assertion +# failure: inited==INDEX +# +SET SESSION sql_safe_updates = 0; +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1), (2); +CREATE TABLE t2 ( a INT ); +INSERT INTO t2 VALUES (1), (2); +CREATE TABLE t3 ( a INT ); +INSERT INTO t3 VALUES (1), (2); +# Should not crash +UPDATE IGNORE +( SELECT ( SELECT COUNT(*) FROM t1 GROUP BY a, @v ) a FROM t2 ) x, t3 +SET t3.a = 0; +Warnings: +Error 1242 Subquery returns more than 1 row +Error 1242 Subquery returns more than 1 row +DROP TABLE t1, t2, t3; +SET SESSION sql_safe_updates = DEFAULT; end of tests diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index ccf60ae5fd9..2b041aee05a 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); # Bug#37938 Test "mysqldump" lacks various insert statements # Turn off concurrent inserts to avoid random errors # NOTE: We reset the variable back to saved value at the end of test diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 4c711c5a977..edb1ec72070 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -178,6 +178,9 @@ mysqltest: At line 1: End of line junk detected: "disconnect default # comment " mysqltest: At line 1: Extra delimiter ";" found mysqltest: At line 1: Extra delimiter ";" found +mysqltest: At line 1: Spurious text after `query` expression +mysqltest: At line 1: Spurious text after `query` expression +mysqltest: At line 2: Spurious text after `query` expression mysqltest: At line 1: Missing argument(s) to 'error' mysqltest: At line 1: Missing argument(s) to 'error' mysqltest: At line 1: The sqlstate definition must start with an uppercase S @@ -263,6 +266,9 @@ a long \$where variable content banana = banana Not a banana: ba\$cat\$cat +with\`some"escaped\'quotes +with\`some"escaped\'quotes +single'tick`backtick mysqltest: At line 1: Missing arguments to let mysqltest: At line 1: Missing variable name in let mysqltest: At line 1: Missing assignment operator in let @@ -326,6 +332,7 @@ outer=2 ifval=0 outer=1 ifval=1 here is the sourced script ERROR 42S02: Table 'test.nowhere' doesn't exist +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'else' at line 1 In loop here is the sourced script @@ -393,6 +400,9 @@ true-inner again true-outer Counter is greater than 0, (counter=10) Counter is not 0, (counter=0) +Counter is true, (counter=alpha) +Beta is true +while with string, only once 1 Testing while with not mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest_while.inc": At line 64: Nesting too deeply @@ -443,13 +453,16 @@ mysqltest: At line 1: Missing required argument 'host' to command 'connect' mysqltest: At line 1: query 'connect con2,localhost,root,,illegal_db' failed: 1049: Unknown database 'illegal_db' mysqltest: At line 1: Illegal argument for port: 'illegal_port' mysqltest: At line 1: Illegal option to connect: SMTP -OK -mysqltest: The test didn't produce any output +200 connects succeeded mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 3: connection 'test_con1' not found in connection pool mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 2: Connection test_con1 already exists -connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); show tables; ERROR 3D000: No database selected +connect con1,localhost,root,,; +connection default; +connection con1; +disconnect con1; +connection default; Output from mysqltest-x.inc Output from mysqltest-x.inc Output from mysqltest-x.inc @@ -573,7 +586,7 @@ if things work as expected Some data for cat_file command of mysqltest -mysqltest: At line 1: Failed to open file 'non_existing_file' +mysqltest: At line 1: command "cat_file" failed with error 1 mysqltest: At line 1: Missing required argument 'filename' to command 'file_exists' mysqltest: At line 1: Missing required argument 'from_file' to command 'copy_file' mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file' diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 6827fd0bc76..ba639fa9763 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1617,4 +1617,25 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort 1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer DROP TABLE t1, t2; +# +# Bug #50394: Regression in EXPLAIN with index scan, LIMIT, GROUP BY and +# ORDER BY computed col +# +CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL, KEY( a, b ) ); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); +INSERT INTO t1 SELECT a + 5, b + 5 FROM t1; +CREATE TABLE t2( a INT PRIMARY KEY, b INT ); +INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); +INSERT INTO t2 SELECT a + 5, b + 5 FROM t2; +EXPLAIN +SELECT count(*) AS c, t1.a +FROM t1 JOIN t2 ON t1.b = t2.a +WHERE t2.b = 1 +GROUP BY t1.a +ORDER by c +LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 8 NULL 10 Using index; Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where +DROP TABLE t1, t2; End of 5.1 tests diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 23a485dc5ed..8e65557d690 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1,4 +1,44 @@ drop table if exists t1, t2; +# +# Bug#57113: ha_partition::extra(ha_extra_function): +# Assertion `m_extra_cache' failed +CREATE TABLE t1 +(id INT NOT NULL PRIMARY KEY, +name VARCHAR(16) NOT NULL, +year YEAR, +INDEX name (name(8)) +) +PARTITION BY HASH(id) PARTITIONS 2; +INSERT INTO t1 VALUES ( 1, 'FooBar', '1924' ); +CREATE TABLE t2 (id INT); +INSERT INTO t2 VALUES (1),(2); +UPDATE t1, t2 SET t1.year = '1955' WHERE t1.name = 'FooBar'; +DROP TABLE t1, t2; +# +# Bug#55458: Partitioned MyISAM table gets crashed by multi-table update +# +CREATE TABLE t1 ( +`id` int NOT NULL, +`user_num` int DEFAULT NULL, +PRIMARY KEY (`id`) +) ENGINE=MyISAM CHARSET=latin1; +INSERT INTO t1 VALUES (1,8601); +INSERT INTO t1 VALUES (2,8601); +INSERT INTO t1 VALUES (3,8601); +INSERT INTO t1 VALUES (4,8601); +CREATE TABLE t2 ( +`id` int(11) NOT NULL, +`user_num` int DEFAULT NULL, +`name` varchar(64) NOT NULL, +PRIMARY KEY (`id`) +) ENGINE=MyISAM CHARSET=latin1 +PARTITION BY HASH (id) +PARTITIONS 2; +INSERT INTO t2 VALUES (1,8601,'John'); +INSERT INTO t2 VALUES (2,8601,'JS'); +INSERT INTO t2 VALUES (3,8601,'John S'); +UPDATE t1, t2 SET t2.name = 'John Smith' WHERE t1.user_num = t2.user_num; +DROP TABLE t1, t2; CREATE TABLE t1 (a INT, b INT) PARTITION BY LIST (a) SUBPARTITION BY HASH (b) @@ -1382,7 +1422,7 @@ NULL 2 explain partitions select * from t1 where a is null or a < 0 or a > 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pn,p2 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 pn,p2 ALL NULL NULL NULL NULL 2 Using where drop table t1; CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, name VARCHAR(20)) ENGINE=MyISAM DEFAULT CHARSET=latin1 diff --git a/mysql-test/r/partition_binlog_stmt.result b/mysql-test/r/partition_binlog_stmt.result new file mode 100644 index 00000000000..9be23636ca6 --- /dev/null +++ b/mysql-test/r/partition_binlog_stmt.result @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS t1; +# +# Bug#51851: Server with SBR locks mutex twice on LOAD DATA into +# partitioned MyISAM table +CREATE TABLE t1 +(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +name TINYBLOB NOT NULL, +modified TIMESTAMP DEFAULT '0000-00-00 00:00:00', +INDEX namelocs (name(255))) ENGINE = MyISAM +PARTITION BY HASH(id) PARTITIONS 2; +LOAD DATA LOCAL INFILE 'init_file.txt' +INTO TABLE t1 (name); +DROP TABLE t1; diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 16428fba4d9..ea74f476ceb 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -1008,4 +1008,14 @@ PARTITION p VALUES LESS THAN (1219089600), PARTITION pmax VALUES LESS THAN MAXVALUE); ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed DROP TABLE old; +# +# Bug #56709: Memory leaks at running the 5.1 test suite +# +CREATE TABLE t1 (a TIMESTAMP NOT NULL PRIMARY KEY); +ALTER TABLE t1 +PARTITION BY RANGE (EXTRACT(DAY FROM a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/partition_hash.result b/mysql-test/r/partition_hash.result index 19da70db5a0..94fefe77a77 100644 --- a/mysql-test/r/partition_hash.result +++ b/mysql-test/r/partition_hash.result @@ -69,25 +69,25 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where explain partitions select * from t1 where a is null or (a >= 5 and a <= 7); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p2,p3 ALL NULL NULL NULL NULL 9 Using where +1 SIMPLE t1 p0,p2,p3 ALL NULL NULL NULL NULL 7 Using where explain partitions select * from t1 where a is null; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 9 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 3 Using where explain partitions select * from t1 where a is not null; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where explain partitions select * from t1 where a >= 1 and a < 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 9 Using where +1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 5 Using where explain partitions select * from t1 where a >= 3 and a <= 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 9 Using where +1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 4 Using where explain partitions select * from t1 where a > 2 and a < 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 9 Using where +1 SIMPLE t1 p1 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a > 3 and a <= 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 9 Using where +1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 4 Using where explain partitions select * from t1 where a > 5; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0,p1,p2,p3 ALL NULL NULL NULL NULL 9 Using where diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index 2a04aafe554..238fbf4662c 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -22,31 +22,31 @@ insert INTO t1 VALUES (110); ERROR HY000: Table has no partition for value 110 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 90; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 90; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 90; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 89; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p90 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p90 ALL NULL NULL NULL NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 89; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p90 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p90 ALL NULL NULL NULL NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 89; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 100; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 100; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 100; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using where DROP TABLE t1; # # Bug#50104: Partitioned table with just 1 partion works with fk diff --git a/mysql-test/r/partition_not_blackhole.result b/mysql-test/r/partition_not_blackhole.result new file mode 100644 index 00000000000..dc0339f8c48 --- /dev/null +++ b/mysql-test/r/partition_not_blackhole.result @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS t1; +# +# Bug#46086: crash when dropping a partitioned table and +# the original engine is disabled +# Copy a .frm and .par file which was created with: +# create table `t1` (`id` int primary key) engine=blackhole +# partition by key () partitions 1; +SHOW TABLES; +Tables_in_test +t1 +SHOW CREATE TABLE t1; +ERROR HY000: Incorrect information in file: './test/t1.frm' +DROP TABLE t1; +ERROR 42S02: Unknown table 't1' +t1.frm +t1.par diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index 568c21b27be..01ae3876fd0 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -1,5 +1,29 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; # +# Bug#53806: Wrong estimates for range query in partitioned MyISAM table +# Bug#46754: 'rows' field doesn't reflect partition pruning +# +CREATE TABLE t1 (a INT PRIMARY KEY) +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (1), +PARTITION p1 VALUES LESS THAN (2), +PARTITION p2 VALUES LESS THAN (3), +PARTITION p3 VALUES LESS THAN (4), +PARTITION p4 VALUES LESS THAN (5), +PARTITION p5 VALUES LESS THAN (6), +PARTITION max VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +# # # # # # # # # 3 # +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; +id select_type table partitions type possible_keys key key_len ref rows Extra +# # # # # # # # # 9 # +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +# # # # # # # # # 3 # +DROP TABLE t1; +# # Bug#49742: Partition Pruning not working correctly for RANGE # CREATE TABLE t1 (a INT PRIMARY KEY) @@ -89,7 +113,7 @@ a 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a <= 2; a -1 @@ -98,7 +122,7 @@ a 2 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index SELECT * FROM t1 WHERE a <= 3; a -1 @@ -108,7 +132,7 @@ a 3 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 5 Using where; Using index SELECT * FROM t1 WHERE a <= 4; a -1 @@ -119,7 +143,7 @@ a 4 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 6 Using where; Using index SELECT * FROM t1 WHERE a <= 5; a -1 @@ -131,7 +155,7 @@ a 5 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 7 Using where; Using index SELECT * FROM t1 WHERE a <= 6; a -1 @@ -213,7 +237,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 8 Using where; Using index SELECT * FROM t1 WHERE a >= 2; a 2 @@ -225,7 +249,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 7 Using where; Using index SELECT * FROM t1 WHERE a >= 3; a 3 @@ -236,7 +260,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 6 Using where; Using index SELECT * FROM t1 WHERE a >= 4; a 4 @@ -246,7 +270,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 5 Using where; Using index SELECT * FROM t1 WHERE a >= 5; a 5 @@ -255,7 +279,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 4 Using where; Using index SELECT * FROM t1 WHERE a >= 6; a 6 @@ -263,14 +287,14 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a >= 7; a 7 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 7; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a > 1; a 2 @@ -282,7 +306,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 7 Using where; Using index SELECT * FROM t1 WHERE a > 2; a 3 @@ -293,7 +317,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 6 Using where; Using index SELECT * FROM t1 WHERE a > 3; a 4 @@ -303,7 +327,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 5 Using where; Using index SELECT * FROM t1 WHERE a > 4; a 5 @@ -312,7 +336,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 4 Using where; Using index SELECT * FROM t1 WHERE a > 5; a 6 @@ -320,20 +344,20 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a > 6; a 7 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a > 7; a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 7; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY) PARTITION BY RANGE (a) ( @@ -408,7 +432,7 @@ a 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a <= 2; a -1 @@ -417,7 +441,7 @@ a 2 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index SELECT * FROM t1 WHERE a <= 3; a -1 @@ -427,7 +451,7 @@ a 3 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 5 Using where; Using index SELECT * FROM t1 WHERE a <= 4; a -1 @@ -438,7 +462,7 @@ a 4 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 6 Using where; Using index SELECT * FROM t1 WHERE a <= 5; a -1 @@ -511,7 +535,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 7 Using where; Using index SELECT * FROM t1 WHERE a >= 2; a 2 @@ -522,7 +546,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 6 Using where; Using index SELECT * FROM t1 WHERE a >= 3; a 3 @@ -532,7 +556,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 5 Using where; Using index SELECT * FROM t1 WHERE a >= 4; a 4 @@ -541,7 +565,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 4 Using where; Using index SELECT * FROM t1 WHERE a >= 5; a 5 @@ -549,14 +573,14 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a >= 6; a 6 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a > 1; a 2 @@ -567,7 +591,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 6 Using where; Using index SELECT * FROM t1 WHERE a > 2; a 3 @@ -577,7 +601,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 5 Using where; Using index SELECT * FROM t1 WHERE a > 3; a 4 @@ -586,7 +610,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 4 Using where; Using index SELECT * FROM t1 WHERE a > 4; a 5 @@ -594,20 +618,20 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a > 5; a 6 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a > 6; a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 3 Using where; Using index DROP TABLE t1; # test of RANGE and index CREATE TABLE t1 (a DATE, KEY(a)) @@ -757,10 +781,10 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p2001-01-01 index a a 4 NULL 7 Using where; Using index +1 SIMPLE t1 pNULL,p2001-01-01 index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p2001-01-01 index a a 4 NULL 7 Using where; Using index +1 SIMPLE t1 pNULL,p2001-01-01 index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using where; Using index @@ -880,34 +904,34 @@ a 1001-01-01 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 4 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1001-01-01 system NULL NULL NULL NULL 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 3 Using where # Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra @@ -917,25 +941,25 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 4 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p2001-01-01 ALL NULL NULL NULL NULL 4 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where DROP TABLE t1; # test of LIST and index CREATE TABLE t1 (a DATE, KEY(a)) @@ -1086,10 +1110,10 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 7 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 7 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using where; Using index @@ -1101,7 +1125,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01 index a a 4 NULL 7 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01 index a a 4 NULL 4 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 Using where; Using index @@ -1209,62 +1233,62 @@ a 1001-01-01 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 4 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1001-01-01 system NULL NULL NULL NULL 1 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 3 Using where # Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 4 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 4 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 pNULL,p1001-01-01 ALL NULL NULL NULL NULL 4 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 5 Using where DROP TABLE t1; # Test with DATETIME column NOT NULL CREATE TABLE t1 ( @@ -1289,25 +1313,25 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 3 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1315,99 +1339,99 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 3 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p20090401,p20090402,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 3 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1440,21 +1464,21 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1462,79 +1486,79 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 2 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1542,19 +1566,19 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090404,p20090405 index NULL PRIMARY 7 NULL 8 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1562,11 +1586,11 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 10 Using where; Using index DROP TABLE t1; # Test with DATETIME column NULL CREATE TABLE t1 ( @@ -1590,25 +1614,25 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 8 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1616,99 +1640,99 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p20090401,p20090402,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where +1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 3 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1740,21 +1764,21 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 7 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1762,79 +1786,79 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 2 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1842,19 +1866,19 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090404,p20090405 ALL NULL NULL NULL NULL 8 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -1862,11 +1886,11 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t1 p20090401,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 10 Using where DROP TABLE t1; # For better code coverage of the patch CREATE TABLE t1 ( @@ -1930,7 +1954,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 3 Using where explain partitions select * from t2 where a=1 and b=1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 3 Using where +1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where create table t3 ( a int ) @@ -1988,25 +2012,25 @@ id select_type table partitions type possible_keys key key_len ref rows Extra explain partitions select * from t5 where (a=10 and b=1) or (a=10 and b=2) or (a=10 and b = 3); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t5 p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t5 p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t5 where (a=10 and b=2) or (a=10 and b=3) or (a=10 and b = 4); id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where explain partitions select * from t5 where (c=1 and d=1); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t5 p0_p0sp0,p1_p1sp0 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t5 p0_p0sp0,p1_p1sp0 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t5 where (c=2 and d=1); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t5 p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t5 p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t5 where (a=10 and b=2 and c=1 and d=1) or (c=2 and d=1); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 3 Using where explain partitions select * from t5 where (a=10 and b=2 and c=1 and d=1) or (b=2 and c=2 and d=1); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t5 p0_p0sp0,p0_p0sp1,p1_p1sp1 ALL NULL NULL NULL NULL 3 Using where create table t6 (a int not null) partition by LIST(a) ( partition p1 values in (1), partition p3 values in (3), @@ -2044,7 +2068,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t6 p5,p7,p9 system NULL NULL NULL NULL 1 explain partitions select * from t6 where a >= 3 and a <= 8; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 3 Using where +1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t6 where a > 3 and a < 5; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables @@ -2086,7 +2110,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t6 p5,p7,p9 system NULL NULL NULL NULL 1 explain partitions select * from t6 where a >= 3 and a <= 8; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 3 Using where +1 SIMPLE t6 p3,p5,p7 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t6 where a > 3 and a < 5; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables @@ -2325,7 +2349,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra explain partitions select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE X p1,p2 ALL a NULL NULL NULL 4 Using where +1 SIMPLE X p1,p2 ALL a NULL NULL NULL 2 Using where 1 SIMPLE Y p1,p2 ref a a 4 test.X.a 2 drop table t1; create table t1 (a int) partition by hash(a) partitions 20; @@ -2338,7 +2362,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1,p2 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a > 1 and a <= 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 3 Using where +1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a >= 1 and a <= 3; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p1,p2,p3 ALL NULL NULL NULL NULL 3 Using where @@ -2428,22 +2452,22 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010 explain partitions select * from t2 where a < 801 and a > 200; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010 Using where +1 SIMPLE t2 p1,p2,p3,p4 ALL NULL NULL NULL NULL 800 Using where explain partitions select * from t2 where a < 801 and a > 800; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 1010 Using where +1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 200 Using where explain partitions select * from t2 where a > 600; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where +1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where explain partitions select * from t2 where a > 600 and b = 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where +1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where explain partitions select * from t2 where a > 600 and b = 4; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where +1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where explain partitions select * from t2 where a > 600 and b = 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 1010 Using where +1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 400 Using where explain partitions select * from t2 where b = 5; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 1010 Using where @@ -2498,19 +2522,19 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 910 explain partitions select * from t2 where a = 101; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 910 Using where +1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 110 Using where explain partitions select * from t2 where a = 550; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 910 Using where +1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 200 Using where explain partitions select * from t2 where a = 833; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 910 Using where +1 SIMPLE t2 p4 ALL NULL NULL NULL NULL 200 Using where explain partitions select * from t2 where (a = 100 OR a = 900); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 910 Using where +1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 310 Using where explain partitions select * from t2 where (a > 100 AND a < 600); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 910 Using where +1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 510 Using where explain partitions select * from t2 where b = 4; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76 Using where @@ -2796,17 +2820,17 @@ id select_type table partitions type possible_keys key key_len ref rows Extra explain partitions select * from t1 where a >= 18446744073709551000-1 and a <= 18446744073709551000+1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p3,p4 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 p3,p4 ALL NULL NULL NULL NULL 3 Using where explain partitions select * from t1 where a between 18446744073709551001 and 18446744073709551002; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a = 18446744073709551000; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a = 18446744073709551613; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a = 18446744073709551614; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables @@ -2833,10 +2857,10 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a=0xFE; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t2 where a=0xFE; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a > 0xFE AND a <= 0xFF; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables @@ -2845,22 +2869,22 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables explain partitions select * from t1 where a >= 0xFE AND a <= 0xFF; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t2 where a >= 0xFE AND a <= 0xFF; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 p2 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a < 64 AND a >= 63; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t2 where a < 64 AND a >= 63; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 p0 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a <= 64 AND a >= 63; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 4 Using where explain partitions select * from t2 where a <= 64 AND a >= 63; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t2 p0,p1 ALL NULL NULL NULL NULL 4 Using where drop table t1; drop table t2; create table t1(a bigint unsigned not null) partition by range(a+0) ( diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result index 731f2478cc9..58945b563dc 100644 --- a/mysql-test/r/partition_range.result +++ b/mysql-test/r/partition_range.result @@ -73,13 +73,13 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pnull system NULL NULL NULL NULL 1 explain partitions select * from t1 where a >= 0; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 3 Using where +1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a < 0; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables explain partitions select * from t1 where a <= 0; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pnull,p0 ALL NULL NULL NULL NULL 3 Using where +1 SIMPLE t1 pnull,p0 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a > 1; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables @@ -112,16 +112,16 @@ select * from t1 where a > 1; a b explain partitions select * from t1 where a is null; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a >= 0; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p1_p1sp0,p1_p1sp1 ALL NULL NULL NULL NULL 4 Using where explain partitions select * from t1 where a < 0; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1 ALL NULL NULL NULL NULL 2 Using where explain partitions select * from t1 where a <= 0; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1,p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 pnull_pnullsp0,pnull_pnullsp1,p0_p0sp0,p0_p0sp1 ALL NULL NULL NULL NULL 4 Using where explain partitions select * from t1 where a > 1; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables @@ -808,3 +808,47 @@ select sum(count) from t2 ch where ch.defid in (50,52) and ch.day between 200703 sum(count) 579 drop table t1, t2; +# +# Bug#50939: Loose Index Scan unduly relies on engine to remember range +# endpoints +# +CREATE TABLE t1 ( +a INT, +b INT, +KEY ( a, b ) +) PARTITION BY HASH (a) PARTITIONS 1; +CREATE TABLE t2 ( +a INT, +b INT, +KEY ( a, b ) +); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); +INSERT INTO t1 SELECT a + 5, b + 5 FROM t1; +INSERT INTO t1 SELECT a + 10, b + 10 FROM t1; +INSERT INTO t1 SELECT a + 20, b + 20 FROM t1; +INSERT INTO t1 SELECT a + 40, b + 40 FROM t1; +INSERT INTO t2 SELECT * FROM t1; +# plans should be identical +EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by +EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by +FLUSH status; +SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a; +a MAX(b) +10 10 +# Should be no more than 4 reads. +SHOW status LIKE 'handler_read_key'; +Variable_name Value +Handler_read_key 4 +FLUSH status; +SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a; +a MAX(b) +10 10 +# Should be no more than 4 reads. +SHOW status LIKE 'handler_read_key'; +Variable_name Value +Handler_read_key 4 +DROP TABLE t1, t2; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f21f1d83acd..84c64a3905a 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -3001,4 +3001,42 @@ EXECUTE stmt; 1 DEALLOCATE PREPARE stmt; DROP TABLE t1; +# +# Bug#54494 crash with explain extended and prepared statements +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2); +PREPARE stmt FROM 'EXPLAIN EXTENDED SELECT 1 FROM t1 RIGHT JOIN t1 t2 ON 1'; +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1 +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +# +# Bug#54488 crash when using explain and prepared statements with subqueries +# +CREATE TABLE t1(f1 INT); +INSERT INTO t1 VALUES (1),(1); +PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))'; +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +DEALLOCATE PREPARE stmt; +DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index ea6494962b6..528e66650cd 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1929,26 +1929,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1976,26 +1976,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2026,26 +2026,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2066,26 +2066,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2114,26 +2114,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2158,26 +2158,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2204,26 +2204,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2242,26 +2242,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index b12728cd76e..9ba5e607b5d 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1912,26 +1912,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1959,26 +1959,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2009,26 +2009,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2049,26 +2049,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2097,26 +2097,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2141,26 +2141,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2187,26 +2187,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2225,26 +2225,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index e9d19aa92e4..e7252473c49 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1913,26 +1913,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 0 31 8 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 0 31 8 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 0 31 8 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 0 31 8 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 0 31 8 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 0 31 8 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 0 31 8 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 0 31 8 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1960,26 +1960,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 0 31 8 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 0 31 8 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 0 31 8 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 0 31 8 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 0 31 8 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 0 31 8 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 0 31 8 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 0 31 8 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2010,26 +2010,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 0 31 8 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 0 31 8 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 0 31 8 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 0 31 8 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 0 31 8 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 0 31 8 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 0 31 8 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 0 31 8 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2050,26 +2050,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 0 31 8 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 0 31 8 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 0 31 8 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 0 31 8 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 0 31 8 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 0 31 8 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 0 31 8 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 0 31 8 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2098,26 +2098,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 0 31 8 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 0 31 8 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 0 31 8 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 0 31 8 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 0 31 8 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 0 31 8 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 0 31 8 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 0 31 8 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2142,26 +2142,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 0 31 8 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 0 31 8 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 0 31 8 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 0 31 8 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 0 31 8 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 0 31 8 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 0 31 8 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 0 31 8 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2188,26 +2188,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 0 31 8 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 0 31 8 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 0 31 8 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 0 31 8 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 0 31 8 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 0 31 8 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 0 31 8 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 0 31 8 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2226,26 +2226,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 0 31 8 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 0 31 8 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 0 31 8 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 0 31 8 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 0 31 8 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 0 31 8 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 0 31 8 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 0 31 8 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 31ca26cffa3..7530b3ebe0b 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1849,26 +1849,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1896,26 +1896,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -1946,26 +1946,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -1986,26 +1986,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2034,26 +2034,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2078,26 +2078,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2124,26 +2124,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2162,26 +2162,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; @@ -4871,26 +4871,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -4918,26 +4918,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -4968,26 +4968,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -5008,26 +5008,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -5056,26 +5056,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -5100,26 +5100,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -5146,26 +5146,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -5184,26 +5184,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index 375f31ef9c4..a5e71e114ca 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -4,6 +4,7 @@ drop procedure if exists p_verify_reprepare_count; drop procedure if exists p1; drop function if exists f1; drop view if exists v1, v2; +TRUNCATE TABLE mysql.general_log; create procedure p_verify_reprepare_count(expected int) begin declare old_reprepare_count int default @reprepare_count; diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 64e00521cd2..d989896514c 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1653,4 +1653,17 @@ a b 0 0 1 1 DROP TABLE t1; +# +# Bug #54802: 'NOT BETWEEN' evaluation is incorrect +# +CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key)); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); +EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL c_key NULL NULL NULL 3 Using where +SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key; +c_key c_notkey +1 1 +3 3 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result index 2962123fcb2..789b9c4f383 100644 --- a/mysql-test/r/row.result +++ b/mysql-test/r/row.result @@ -466,3 +466,26 @@ SELECT 1 FROM t1 WHERE ROW(a, b) >= ROW('1', (SELECT 1 FROM t1 WHERE a > 1234)); 1 DROP TABLE t1; +# +# Bug #54190: Comparison to row subquery produces incorrect result +# +SELECT ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0); +ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0) +NULL +SELECT ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0); +ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0) +NULL +CREATE TABLE t1 (i INT); +INSERT INTO t1 () VALUES (1), (2), (3); +SELECT ROW(1,2) = (SELECT 1,2 FROM t1 WHERE 1 = 0); +ROW(1,2) = (SELECT 1,2 FROM t1 WHERE 1 = 0) +NULL +SELECT ROW(1,2) = (SELECT 1,3 FROM t1 WHERE 1 = 0); +ROW(1,2) = (SELECT 1,3 FROM t1 WHERE 1 = 0) +NULL +SELECT i FROM t1 WHERE ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0); +i +SELECT i FROM t1 WHERE ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0); +i +DROP TABLE t1; +End of 5.1 tests diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index cbb6149a148..c520d21310f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -922,7 +922,7 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a) 1 1 a 2 0 b -NULL 0 NULL +NULL NULL NULL select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2; a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a) 1 0 a @@ -932,7 +932,7 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a) 1 0 a 2 0 b -NULL 0 NULL +NULL NULL NULL drop table t1,t2; create table t1 (a int, b real, c varchar(10)); insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b'); diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 153fbed9622..50c0d14968a 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -81,4 +81,110 @@ col_int_nokey sub 0 NULL 2 11 DROP TABLE t1,t2; -End of 5.1 tests. +# +# Bug#54568: create view cause Assertion failed: 0, +# file .\item_subselect.cc, line 836 +# +EXPLAIN SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1249 Select 2 was reduced during optimization +DESCRIBE SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1249 Select 2 was reduced during optimization +# None of the below should crash +CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); +CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); +DROP VIEW v1, v2; +# +# Bug#51070: Query with a NOT IN subquery predicate returns a wrong +# result set +# +CREATE TABLE t1 ( a INT, b INT ); +INSERT INTO t1 VALUES ( 1, NULL ), ( 2, NULL ); +CREATE TABLE t2 ( c INT, d INT ); +INSERT INTO t2 VALUES ( NULL, 3 ), ( NULL, 4 ); +CREATE TABLE t3 ( e INT, f INT ); +INSERT INTO t3 VALUES ( NULL, NULL ), ( NULL, NULL ); +CREATE TABLE t4 ( a INT ); +INSERT INTO t4 VALUES (1), (2), (3); +CREATE TABLE t5 ( a INT ); +INSERT INTO t5 VALUES (NULL), (2); +EXPLAIN +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ); +id select_type table type possible_keys key key_len ref rows Extra +x PRIMARY x x x x x x x x +x DEPENDENT SUBQUERY x x x x x x x x +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ); +a b +EXPLAIN +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL; +a b +1 NULL +2 NULL +SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) IS NULL; +a b +1 NULL +2 NULL +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS UNKNOWN; +a b +1 NULL +2 NULL +SELECT * FROM t1 WHERE (( a, b ) NOT IN ( SELECT c, d FROM t2 )) IS UNKNOWN; +a b +1 NULL +2 NULL +SELECT * FROM t1 WHERE 1 = 1 AND ( a, b ) NOT IN ( SELECT c, d FROM t2 ); +a b +EXPLAIN +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 ); +id select_type table type possible_keys key key_len ref rows Extra +x PRIMARY x x x x x x x x +x DEPENDENT SUBQUERY x x x x x x x x +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 ); +a b +EXPLAIN +SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 ); +id select_type table type possible_keys key key_len ref rows Extra +x PRIMARY x x x x x x x x +x DEPENDENT SUBQUERY x x x x x x x x +SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 ); +c d +EXPLAIN +SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 ); +id select_type table type possible_keys key key_len ref rows Extra +x PRIMARY x x x x x x x x +x DEPENDENT SUBQUERY x x x x x x x x +SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 ); +e f +EXPLAIN +SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 ); +id select_type table type possible_keys key key_len ref rows Extra +x PRIMARY x x x x x x x x +x DEPENDENT SUBQUERY x x x x x x x x +SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 ); +c d +SELECT * FROM t1 WHERE ( a, b ) NOT IN +( SELECT c, d FROM t2 WHERE c = 1 AND c <> 1 ); +a b +1 NULL +2 NULL +SELECT * FROM t1 WHERE b NOT IN ( SELECT c FROM t2 WHERE c = 1 ); +a b +1 NULL +2 NULL +SELECT * FROM t1 WHERE NULL NOT IN ( SELECT c FROM t2 WHERE c = 1 AND c <> 1 ); +a b +1 NULL +2 NULL +DROP TABLE t1, t2, t3, t4, t5; +# +# End of 5.1 tests. +# diff --git a/mysql-test/r/table_elim.result b/mysql-test/r/table_elim.result index 2cb3b543bb7..395b0be7e34 100644 --- a/mysql-test/r/table_elim.result +++ b/mysql-test/r/table_elim.result @@ -60,7 +60,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 4 100.00 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Warnings: -Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t0` left join (`test`.`t1`) on((`test`.`t0`.`a` = `test`.`t1`.`a`)) where 1 +Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t0` left join (`test`.`t1`) on((`test`.`t1`.`a` = `test`.`t0`.`a`)) where 1 # Elimination with aggregate functions explain select count(*) from t1 left join t2 on t2.a=t1.a; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result index 2948bb8ecec..e2e337628ce 100644 --- a/mysql-test/r/timezone2.result +++ b/mysql-test/r/timezone2.result @@ -296,4 +296,16 @@ CONVERT_TZ(NOW(), 'UTC', 'Europe/Moscow') IS NULL UPDATE t1 SET t = CONVERT_TZ(t, 'UTC', 'Europe/Moscow'); UNLOCK TABLES; DROP TABLE t1; +# +# Bug #55424: convert_tz crashes when fed invalid data +# +CREATE TABLE t1 (a SET('x') NOT NULL); +INSERT INTO t1 VALUES (''); +SELECT CONVERT_TZ(1, a, 1) FROM t1; +CONVERT_TZ(1, a, 1) +NULL +SELECT CONVERT_TZ(1, 1, a) FROM t1; +CONVERT_TZ(1, 1, a) +NULL +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 98208cdfbeb..089845560ed 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1797,11 +1797,8 @@ Note 1050 Table 'v1' already exists set @id=last_insert_id(); select * from t1; id operation -1 CREATE TABLE ... SELECT, inserting a new key select * from t1_op_log; operation -Before INSERT, new=CREATE TABLE ... SELECT, inserting a new key -After INSERT, new=CREATE TABLE ... SELECT, inserting a new key truncate t1_op_log; create table if not exists v1 replace select @id, "CREATE TABLE ... REPLACE SELECT, deleting a duplicate key"; @@ -1809,13 +1806,8 @@ Warnings: Note 1050 Table 'v1' already exists select * from t1; id operation -1 CREATE TABLE ... REPLACE SELECT, deleting a duplicate key select * from t1_op_log; operation -Before INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key -Before DELETE, old=CREATE TABLE ... SELECT, inserting a new key -After DELETE, old=CREATE TABLE ... SELECT, inserting a new key -After INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key truncate t1; truncate t1_op_log; insert into v1 (id, operation) diff --git a/mysql-test/r/trigger_notembedded.result b/mysql-test/r/trigger_notembedded.result index 14c499692a8..6f021c6ec5a 100644 --- a/mysql-test/r/trigger_notembedded.result +++ b/mysql-test/r/trigger_notembedded.result @@ -501,4 +501,25 @@ SHOW CREATE TRIGGER db1.trg; ERROR 42000: Access denied; you need the TRIGGER privilege for this operation DROP USER 'no_rights'@'localhost'; DROP DATABASE db1; +DROP DATABASE IF EXISTS mysqltest_db1; +CREATE DATABASE mysqltest_db1; +USE mysqltest_db1; +GRANT ALL ON mysqltest_db1.* TO mysqltest_u1@localhost; +CREATE TABLE t1 ( +a1 int, +a2 int +); +INSERT INTO t1 VALUES (1, 20); +CREATE TRIGGER mysqltest_db1.upd_t1 +BEFORE UPDATE ON t1 FOR EACH ROW SET new.a2 = 200; +CREATE TABLE t2 ( +a1 int +); +INSERT INTO t2 VALUES (2); +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +UPDATE IGNORE t1, t2 SET t1.a1 = 2, t2.a1 = 3 WHERE t1.a1 = 1 AND t2.a1 = 2; +ERROR 42000: TRIGGER command denied to user 'mysqltest_u1'@'localhost' for table 't1' +DROP DATABASE mysqltest_db1; +DROP USER mysqltest_u1@localhost; +USE test; End of 5.1 tests. diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index e26c2e68775..e88d3462466 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -527,3 +527,24 @@ f1 f2-f3 5 0 DROP TABLE t1; End of 5.0 tests +# +# Bug #55779: select does not work properly in mysql server +# Version "5.1.42 SUSE MySQL RPM" +# +CREATE TABLE t1 (a TIMESTAMP, KEY (a)); +INSERT INTO t1 VALUES ('2000-01-01 00:00:00'), ('2000-01-01 00:00:00'), +('2000-01-01 00:00:01'), ('2000-01-01 00:00:01'); +SELECT a FROM t1 WHERE a >= 20000101000000; +a +2000-01-01 00:00:00 +2000-01-01 00:00:00 +2000-01-01 00:00:01 +2000-01-01 00:00:01 +SELECT a FROM t1 WHERE a >= '20000101000000'; +a +2000-01-01 00:00:00 +2000-01-01 00:00:00 +2000-01-01 00:00:01 +2000-01-01 00:00:01 +DROP TABLE t1; +End of 5.1 tests diff --git a/mysql-test/r/udf_query_cache.result b/mysql-test/r/udf_query_cache.result index 01dac554142..8c25c127012 100644 --- a/mysql-test/r/udf_query_cache.result +++ b/mysql-test/r/udf_query_cache.result @@ -3,6 +3,7 @@ CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; create table t1 (a char); set GLOBAL query_cache_size=1355776; reset query cache; +flush status; select metaphon('MySQL') from t1; metaphon('MySQL') show status like "Qcache_hits"; diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result index bdfac990a9a..f2c8886c915 100644 --- a/mysql-test/r/upgrade.result +++ b/mysql-test/r/upgrade.result @@ -141,10 +141,10 @@ USE `#mysql50#../blablabla`; ERROR 42000: Incorrect database name '#mysql50#../blablabla' show full tables; Tables_in_test Table_type -#mysql50#ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com BASE TABLE -rename table `#mysql50#ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com` to `ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com`; +#mysql50#ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com BASE TABLE +rename table `#mysql50#ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com` to `ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com`; show full tables; Tables_in_test Table_type -ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com BASE TABLE -drop table `ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com`; +ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com BASE TABLE +drop table `ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com`; # End of 5.1 tests diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index be10bd9954b..56266a46e20 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -430,4 +430,21 @@ CREATE TRIGGER t_after_insert AFTER INSERT ON t1 FOR EACH ROW SET @bug42188 = 10 INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1); DROP TABLE t1; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (0),(0); +# BUG#55615 : should not crash +SELECT (@a:=(SELECT @a:=1 FROM t1 LIMIT 1)) AND COUNT(1) FROM t1 GROUP BY @a; +(@a:=(SELECT @a:=1 FROM t1 LIMIT 1)) AND COUNT(1) +1 +1 +# BUG#55564 : should not crash +SELECT IF( +@v:=LEAST((SELECT 1 FROM t1 t2 LEFT JOIN t1 ON (@v) GROUP BY t1.a), a), +count(*), 1) +FROM t1 GROUP BY a LIMIT 1; +IF( +@v:=LEAST((SELECT 1 FROM t1 t2 LEFT JOIN t1 ON (@v) GROUP BY t1.a), a), +count(*), 1) +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/variables_debug.result b/mysql-test/r/variables_debug.result index d578fa957fc..41d77007b26 100644 --- a/mysql-test/r/variables_debug.result +++ b/mysql-test/r/variables_debug.result @@ -24,4 +24,17 @@ SELECT @@global.debug; @@global.debug SET GLOBAL debug=@old_debug; +# +# Bug #56709: Memory leaks at running the 5.1 test suite +# +SET @old_local_debug = @@debug; +SET @@debug='d,foo'; +SELECT @@debug; +@@debug +d,foo +SET @@debug=''; +SELECT @@debug; +@@debug + +SET @@debug = @old_local_debug; End of 5.1 tests diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index ad87dda53fe..b2065ed20d1 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1418,7 +1418,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Warnings: -Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on((`test`.`t1`.`a` = `test`.`t2`.`a`))) on((`test`.`t3`.`a` = `test`.`t1`.`a`)) where 1 +Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on(((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`a`)))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1 create view v1 (a) as select a from t1; create view v2 (a) as select a from t2; create view v4 (a,b) as select v1.a as a, v2.a as b from v1 left join v2 on (v1.a=v2.a); @@ -1433,7 +1433,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Warnings: -Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on((`test`.`t1`.`a` = `test`.`t2`.`a`))) on((`test`.`t3`.`a` = `test`.`t1`.`a`)) where 1 +Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on(((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`a`)))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1 prepare stmt1 from "select * from t3 left join v4 on (t3.a = v4.a);"; execute stmt1; a a b diff --git a/mysql-test/r/warnings_debug.result b/mysql-test/r/warnings_debug.result new file mode 100644 index 00000000000..08908bf0437 --- /dev/null +++ b/mysql-test/r/warnings_debug.result @@ -0,0 +1,10 @@ +drop table if exists t1; +create table t1 (a int primary key) engine=innodb; +SET SESSION debug="+d,warn_during_ha_commit_trans"; +INSERT INTO t1 VALUES (1); +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +SHOW WARNINGS; +Level Code Message +Warning 1196 Some non-transactional changed tables couldn't be rolled back +drop table t1; diff --git a/mysql-test/std_data/parts/t1_blackhole.frm b/mysql-test/std_data/parts/t1_blackhole.frm Binary files differnew file mode 100644 index 00000000000..be77b7a041a --- /dev/null +++ b/mysql-test/std_data/parts/t1_blackhole.frm diff --git a/mysql-test/std_data/parts/t1_blackhole.par b/mysql-test/std_data/parts/t1_blackhole.par Binary files differnew file mode 100644 index 00000000000..6528edf190c --- /dev/null +++ b/mysql-test/std_data/parts/t1_blackhole.par diff --git a/mysql-test/suite/binlog/r/binlog_mixed_load_data.result b/mysql-test/suite/binlog/r/binlog_mixed_load_data.result new file mode 100644 index 00000000000..840257f11ff --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_mixed_load_data.result @@ -0,0 +1,10 @@ +RESET MASTER; +CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=MYISAM; +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1; +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +DROP TABLE t1; diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index 8b42cadf6cb..8ee531c6ce2 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -48,12 +48,12 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # SAVEPOINT my_savepoint +master-bin.000001 # Query # # SAVEPOINT `my_savepoint` master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Table_map # # table_id: # (test.t2) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # ROLLBACK TO my_savepoint +master-bin.000001 # Query # # ROLLBACK TO `my_savepoint` master-bin.000001 # Xid # # COMMIT /* XID */ delete from t1; delete from t2; @@ -77,12 +77,12 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # SAVEPOINT my_savepoint +master-bin.000001 # Query # # SAVEPOINT `my_savepoint` master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Table_map # # table_id: # (test.t2) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # ROLLBACK TO my_savepoint +master-bin.000001 # Query # # ROLLBACK TO `my_savepoint` master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index a26fcc1dc1a..d2f47e56c61 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -44,10 +44,10 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(3) -master-bin.000001 # Query # # SAVEPOINT my_savepoint +master-bin.000001 # Query # # SAVEPOINT `my_savepoint` master-bin.000001 # Query # # use `test`; insert into t1 values(4) master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 -master-bin.000001 # Query # # ROLLBACK TO my_savepoint +master-bin.000001 # Query # # ROLLBACK TO `my_savepoint` master-bin.000001 # Xid # # COMMIT /* XID */ delete from t1; delete from t2; @@ -70,10 +70,10 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(5) -master-bin.000001 # Query # # SAVEPOINT my_savepoint +master-bin.000001 # Query # # SAVEPOINT `my_savepoint` master-bin.000001 # Query # # use `test`; insert into t1 values(6) master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 -master-bin.000001 # Query # # ROLLBACK TO my_savepoint +master-bin.000001 # Query # # ROLLBACK TO `my_savepoint` master-bin.000001 # Query # # use `test`; insert into t1 values(7) master-bin.000001 # Xid # # COMMIT /* XID */ delete from t1; diff --git a/mysql-test/suite/binlog/t/binlog_killed_simulate.test b/mysql-test/suite/binlog/t/binlog_killed_simulate.test index ec61271ae88..b87d47559fe 100644 --- a/mysql-test/suite/binlog/t/binlog_killed_simulate.test +++ b/mysql-test/suite/binlog/t/binlog_killed_simulate.test @@ -1,5 +1,5 @@ -- source include/have_debug.inc --- source include/have_binlog_format_mixed_or_statement.inc +-- source include/have_binlog_format_statement.inc # # bug#27571 asynchronous setting mysql_$query()'s local error and # Query_log_event::error_code diff --git a/mysql-test/suite/binlog/t/binlog_mixed_load_data.test b/mysql-test/suite/binlog/t/binlog_mixed_load_data.test new file mode 100644 index 00000000000..7e7cb973c1b --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_mixed_load_data.test @@ -0,0 +1,15 @@ +# +# Bug #34283 mysqlbinlog leaves tmpfile after termination +# if binlog contains load data infile, so in mixed mode we +# go to row-based for avoiding the problem. +# + +--source include/have_binlog_format_mixed.inc +--source include/have_log_bin.inc + +RESET MASTER; +CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=MYISAM; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1; +--source include/show_binlog_events.inc +DROP TABLE t1; diff --git a/mysql-test/suite/binlog/t/binlog_stm_blackhole.test b/mysql-test/suite/binlog/t/binlog_stm_blackhole.test index 02ba2be095b..6047d8ca2fc 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_blackhole.test +++ b/mysql-test/suite/binlog/t/binlog_stm_blackhole.test @@ -2,5 +2,5 @@ # For both statement and row based bin logs 9/19/2005 [jbm] -- source include/not_embedded.inc --- source include/have_binlog_format_mixed_or_statement.inc +-- source include/have_binlog_format_statement.inc -- source extra/binlog_tests/blackhole.test diff --git a/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result b/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result index 67d9c76ccac..ee1548fe012 100644 --- a/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result @@ -78,7 +78,6 @@ grant all on db_storedproc_1.* to 'user_1'@'localhost'; revoke create routine on db_storedproc_1.* from 'user_1'@'localhost'; flush privileges; DROP PROCEDURE IF EXISTS sp1; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -91,7 +90,6 @@ USE db_storedproc_1; root@localhost db_storedproc_1 GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -112,7 +110,6 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 DROP PROCEDURE IF EXISTS sp3; @@ -149,7 +146,6 @@ CREATE PROCEDURE sp4(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; END// -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -191,7 +187,6 @@ grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; grant SELECT on db_storedproc_1.* to 'user_2'@'localhost'; grant execute on db_storedproc_1.* to 'user_2'@'localhost'; flush privileges; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 CREATE PROCEDURE sp5_s_i () sql security definer @@ -207,7 +202,6 @@ CREATE PROCEDURE sp5_ins () sql security definer BEGIN insert into db_storedproc_1.t3165 values ('inserted', 'from sp5_ins', 1000); END// -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp5_s_i(); @@ -305,7 +299,6 @@ GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc_1.* TO 'user_2'@'localhost'; GRANT EXECUTE ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 CREATE PROCEDURE sp3166_s_i () SQL SECURITY INVOKER @@ -321,7 +314,6 @@ CREATE PROCEDURE sp3166_ins () SQL SECURITY INVOKER BEGIN insert into db_storedproc_1.t3166 values ('inserted from sp3166_ins'); END// -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -340,7 +332,6 @@ c1 inserted outside SP GRANT INSERT ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -361,7 +352,6 @@ inserted from sp3166_s_i inserted from sp3166_ins REVOKE SELECT ON db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -379,7 +369,6 @@ inserted from sp3166_ins root@localhost db_storedproc_1 REVOKE EXECUTE on db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); diff --git a/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result b/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result index 24ebd38e403..6591a138d73 100644 --- a/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result +++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result @@ -81,7 +81,6 @@ create user 'user_2'@'localhost'; GRANT CREATE ROUTINE ON db_storedproc.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_1,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc CREATE PROCEDURE sp31102 () SQL SECURITY INVOKER @@ -94,7 +93,6 @@ DECLARE res INT; SET res = n * n; RETURN res; END// -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); @@ -113,7 +111,6 @@ fn31105( 9 ) 81 GRANT EXECUTE ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); @@ -134,7 +131,6 @@ a` a` 1000-01-01 -5000 a` -5000 SELECT fn31105( 9 ); fn31105( 9 ) 81 -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03.result b/mysql-test/suite/funcs_1/r/innodb_trig_03.result index b02fba0f38d..a7fce94c91d 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_03.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_03.result @@ -85,8 +85,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.3.2: ----------------- @@ -161,8 +159,6 @@ grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT UPDATE, TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_noprivs@localhost @@ -222,8 +218,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT UPDATE ON `priv_db`.* TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -296,8 +290,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT UPDATE ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -351,8 +343,6 @@ grant UPDATE (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs; Grants for test_noprivs@% GRANT TRIGGER ON *.* TO 'test_noprivs'@'%' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -407,8 +397,6 @@ grant TRIGGER, SELECT on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT SELECT, TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_noprivs@localhost @@ -464,8 +452,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.* TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -519,8 +505,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -565,8 +549,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO 'test_noprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -611,7 +593,6 @@ Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t2` TO 'test_yesprivs'@'localhost' GRANT SELECT, UPDATE ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result index 476ccc6ebd8..5b760116801 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result @@ -24,7 +24,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, INSERT ON `priv_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); no trigger privilege on db level for create: -------------------------------------------- @@ -32,7 +31,6 @@ use priv_db; create trigger trg1_1 before INSERT on t1 for each row set new.f1 = 'trig 1_1-no'; ERROR 42000: TRIGGER command denied to user 'test_yesprivs'@'localhost' for table 't1' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv_db; insert into t1 (f1) values ('insert-yes'); select f1 from t1 order by f1; @@ -253,8 +251,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; create User test_noprivs@localhost; set password for test_noprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_noprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); no trigger privilege on table level for create: ----------------------------------------------- @@ -513,8 +509,6 @@ grant SELECT,INSERT on *.* to test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT SELECT, INSERT ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -563,7 +557,6 @@ revoke TRIGGER on *.* from test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -698,7 +691,6 @@ select f1 from t1 order by f1; f1 insert-yes insert-yes -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -767,9 +759,7 @@ Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, INSERT, UPDATE ON `priv1_db`.* TO 'test_noprivs'@'localhost' GRANT SELECT, INSERT ON `priv2_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv1_db; -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv1_db; trigger privilege on one db1 db level, not on db2 @@ -982,7 +972,6 @@ create User test_useprivs@localhost; set password for test_useprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; revoke ALL PRIVILEGES, GRANT OPTION FROM test_useprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1010,7 +999,6 @@ select f1 from t1 order by f1; f1 trig 1_1-yes prepare ins1 from 'insert into t1 (f1) values (''insert2-no'')'; -connect(localhost,test_useprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_useprivs@localhost @@ -1206,7 +1194,6 @@ create table t1 (f1 char(20)) engine= innodb; create User test_yesprivs@localhost; set password for test_yesprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1303,7 +1290,6 @@ create table t1 (f1 char(20)) engine= innodb; create User test_yesprivs@localhost; set password for test_yesprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1375,8 +1361,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, UPDATE ON `priv_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); update only on column: ---------------------- diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_0407.result b/mysql-test/suite/funcs_1/r/innodb_trig_0407.result index 33e58f50ec1..8597f252e54 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_0407.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_0407.result @@ -67,8 +67,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_general@localhost; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; -connect(localhost,test_general,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_super,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.4: --------------- diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_08.result b/mysql-test/suite/funcs_1/r/innodb_trig_08.result index 6ced07cef73..b2b38694680 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_08.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_08.result @@ -67,8 +67,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_general@localhost; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; -connect(localhost,test_general,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_super,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.8.1: (implied in previous tests) --------------------------------------------- diff --git a/mysql-test/suite/funcs_1/r/memory_storedproc_06.result b/mysql-test/suite/funcs_1/r/memory_storedproc_06.result index eb617c68ae9..096cbd1261e 100644 --- a/mysql-test/suite/funcs_1/r/memory_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/memory_storedproc_06.result @@ -79,7 +79,6 @@ grant all on db_storedproc_1.* to 'user_1'@'localhost'; revoke create routine on db_storedproc_1.* from 'user_1'@'localhost'; flush privileges; DROP PROCEDURE IF EXISTS sp1; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -92,7 +91,6 @@ USE db_storedproc_1; root@localhost db_storedproc_1 GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -113,7 +111,6 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 DROP PROCEDURE IF EXISTS sp3; @@ -150,7 +147,6 @@ CREATE PROCEDURE sp4(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; END// -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -192,7 +188,6 @@ grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; grant SELECT on db_storedproc_1.* to 'user_2'@'localhost'; grant execute on db_storedproc_1.* to 'user_2'@'localhost'; flush privileges; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 CREATE PROCEDURE sp5_s_i () sql security definer @@ -208,7 +203,6 @@ CREATE PROCEDURE sp5_ins () sql security definer BEGIN insert into db_storedproc_1.t3165 values ('inserted', 'from sp5_ins', 1000); END// -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp5_s_i(); @@ -306,7 +300,6 @@ GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc_1.* TO 'user_2'@'localhost'; GRANT EXECUTE ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 CREATE PROCEDURE sp3166_s_i () SQL SECURITY INVOKER @@ -322,7 +315,6 @@ CREATE PROCEDURE sp3166_ins () SQL SECURITY INVOKER BEGIN insert into db_storedproc_1.t3166 values ('inserted from sp3166_ins'); END// -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -341,7 +333,6 @@ c1 inserted outside SP GRANT INSERT ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -362,7 +353,6 @@ inserted from sp3166_s_i inserted from sp3166_ins REVOKE SELECT ON db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -380,7 +370,6 @@ inserted from sp3166_ins root@localhost db_storedproc_1 REVOKE EXECUTE on db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); diff --git a/mysql-test/suite/funcs_1/r/memory_storedproc_10.result b/mysql-test/suite/funcs_1/r/memory_storedproc_10.result index f5e34b0063c..4a932ee826b 100644 --- a/mysql-test/suite/funcs_1/r/memory_storedproc_10.result +++ b/mysql-test/suite/funcs_1/r/memory_storedproc_10.result @@ -82,7 +82,6 @@ create user 'user_2'@'localhost'; GRANT CREATE ROUTINE ON db_storedproc.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_1,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc CREATE PROCEDURE sp31102 () SQL SECURITY INVOKER @@ -95,7 +94,6 @@ DECLARE res INT; SET res = n * n; RETURN res; END// -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); @@ -114,7 +112,6 @@ fn31105( 9 ) 81 GRANT EXECUTE ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); @@ -135,7 +132,6 @@ a` a` 1000-01-01 -5000 a` -5000 SELECT fn31105( 9 ); fn31105( 9 ) 81 -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03.result b/mysql-test/suite/funcs_1/r/memory_trig_03.result index 7f38fd1f182..0d622915dca 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_03.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_03.result @@ -86,8 +86,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.3.2: ----------------- @@ -162,8 +160,6 @@ grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT UPDATE, TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_noprivs@localhost @@ -223,8 +219,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT UPDATE ON `priv_db`.* TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -297,8 +291,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT UPDATE ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -352,8 +344,6 @@ grant UPDATE (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs; Grants for test_noprivs@% GRANT TRIGGER ON *.* TO 'test_noprivs'@'%' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -408,8 +398,6 @@ grant TRIGGER, SELECT on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT SELECT, TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_noprivs@localhost @@ -465,8 +453,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.* TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -520,8 +506,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -566,8 +550,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO 'test_noprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -612,7 +594,6 @@ Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t2` TO 'test_yesprivs'@'localhost' GRANT SELECT, UPDATE ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03e.result b/mysql-test/suite/funcs_1/r/memory_trig_03e.result index bbee7d47e7e..95c833b90c3 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_03e.result @@ -25,7 +25,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, INSERT ON `priv_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); no trigger privilege on db level for create: -------------------------------------------- @@ -33,7 +32,6 @@ use priv_db; create trigger trg1_1 before INSERT on t1 for each row set new.f1 = 'trig 1_1-no'; ERROR 42000: TRIGGER command denied to user 'test_yesprivs'@'localhost' for table 't1' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv_db; insert into t1 (f1) values ('insert-yes'); select f1 from t1 order by f1; @@ -254,8 +252,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; create User test_noprivs@localhost; set password for test_noprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_noprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); no trigger privilege on table level for create: ----------------------------------------------- @@ -514,8 +510,6 @@ grant SELECT,INSERT on *.* to test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT SELECT, INSERT ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -564,7 +558,6 @@ revoke TRIGGER on *.* from test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -699,7 +692,6 @@ select f1 from t1 order by f1; f1 insert-yes insert-yes -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -768,9 +760,7 @@ Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, INSERT, UPDATE ON `priv1_db`.* TO 'test_noprivs'@'localhost' GRANT SELECT, INSERT ON `priv2_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv1_db; -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv1_db; trigger privilege on one db1 db level, not on db2 @@ -983,7 +973,6 @@ create User test_useprivs@localhost; set password for test_useprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; revoke ALL PRIVILEGES, GRANT OPTION FROM test_useprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1011,7 +1000,6 @@ select f1 from t1 order by f1; f1 trig 1_1-yes prepare ins1 from 'insert into t1 (f1) values (''insert2-no'')'; -connect(localhost,test_useprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_useprivs@localhost @@ -1207,7 +1195,6 @@ create table t1 (f1 char(20)) engine= memory; create User test_yesprivs@localhost; set password for test_yesprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1319,8 +1306,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, UPDATE ON `priv_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); update only on column: ---------------------- diff --git a/mysql-test/suite/funcs_1/r/memory_trig_0407.result b/mysql-test/suite/funcs_1/r/memory_trig_0407.result index 2f76f5544b9..b8d15b5403b 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_0407.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_0407.result @@ -68,8 +68,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_general@localhost; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; -connect(localhost,test_general,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_super,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.4: --------------- diff --git a/mysql-test/suite/funcs_1/r/memory_trig_08.result b/mysql-test/suite/funcs_1/r/memory_trig_08.result index ab570072087..03505af95c5 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_08.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_08.result @@ -68,8 +68,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_general@localhost; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; -connect(localhost,test_general,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_super,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.8.1: (implied in previous tests) --------------------------------------------- diff --git a/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result b/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result index eb617c68ae9..096cbd1261e 100644 --- a/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result @@ -79,7 +79,6 @@ grant all on db_storedproc_1.* to 'user_1'@'localhost'; revoke create routine on db_storedproc_1.* from 'user_1'@'localhost'; flush privileges; DROP PROCEDURE IF EXISTS sp1; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -92,7 +91,6 @@ USE db_storedproc_1; root@localhost db_storedproc_1 GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -113,7 +111,6 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 DROP PROCEDURE IF EXISTS sp3; @@ -150,7 +147,6 @@ CREATE PROCEDURE sp4(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; END// -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -192,7 +188,6 @@ grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; grant SELECT on db_storedproc_1.* to 'user_2'@'localhost'; grant execute on db_storedproc_1.* to 'user_2'@'localhost'; flush privileges; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 CREATE PROCEDURE sp5_s_i () sql security definer @@ -208,7 +203,6 @@ CREATE PROCEDURE sp5_ins () sql security definer BEGIN insert into db_storedproc_1.t3165 values ('inserted', 'from sp5_ins', 1000); END// -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp5_s_i(); @@ -306,7 +300,6 @@ GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc_1.* TO 'user_2'@'localhost'; GRANT EXECUTE ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 CREATE PROCEDURE sp3166_s_i () SQL SECURITY INVOKER @@ -322,7 +315,6 @@ CREATE PROCEDURE sp3166_ins () SQL SECURITY INVOKER BEGIN insert into db_storedproc_1.t3166 values ('inserted from sp3166_ins'); END// -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -341,7 +333,6 @@ c1 inserted outside SP GRANT INSERT ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -362,7 +353,6 @@ inserted from sp3166_s_i inserted from sp3166_ins REVOKE SELECT ON db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -380,7 +370,6 @@ inserted from sp3166_ins root@localhost db_storedproc_1 REVOKE EXECUTE on db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); diff --git a/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result b/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result index f5e34b0063c..4a932ee826b 100644 --- a/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result +++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result @@ -82,7 +82,6 @@ create user 'user_2'@'localhost'; GRANT CREATE ROUTINE ON db_storedproc.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_1,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc CREATE PROCEDURE sp31102 () SQL SECURITY INVOKER @@ -95,7 +94,6 @@ DECLARE res INT; SET res = n * n; RETURN res; END// -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); @@ -114,7 +112,6 @@ fn31105( 9 ) 81 GRANT EXECUTE ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); @@ -135,7 +132,6 @@ a` a` 1000-01-01 -5000 a` -5000 SELECT fn31105( 9 ); fn31105( 9 ) 81 -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03.result b/mysql-test/suite/funcs_1/r/myisam_trig_03.result index 7f38fd1f182..0d622915dca 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_03.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_03.result @@ -86,8 +86,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.3.2: ----------------- @@ -162,8 +160,6 @@ grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT UPDATE, TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_noprivs@localhost @@ -223,8 +219,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT UPDATE ON `priv_db`.* TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -297,8 +291,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT UPDATE ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -352,8 +344,6 @@ grant UPDATE (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs; Grants for test_noprivs@% GRANT TRIGGER ON *.* TO 'test_noprivs'@'%' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -408,8 +398,6 @@ grant TRIGGER, SELECT on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT SELECT, TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_noprivs@localhost @@ -465,8 +453,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.* TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -520,8 +506,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -566,8 +550,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO 'test_noprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -612,7 +594,6 @@ Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t2` TO 'test_yesprivs'@'localhost' GRANT SELECT, UPDATE ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result index e4dc67098ad..9e0811d29fd 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result @@ -25,7 +25,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, INSERT ON `priv_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); no trigger privilege on db level for create: -------------------------------------------- @@ -33,7 +32,6 @@ use priv_db; create trigger trg1_1 before INSERT on t1 for each row set new.f1 = 'trig 1_1-no'; ERROR 42000: TRIGGER command denied to user 'test_yesprivs'@'localhost' for table 't1' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv_db; insert into t1 (f1) values ('insert-yes'); select f1 from t1 order by f1; @@ -254,8 +252,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; create User test_noprivs@localhost; set password for test_noprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_noprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); no trigger privilege on table level for create: ----------------------------------------------- @@ -514,8 +510,6 @@ grant SELECT,INSERT on *.* to test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT SELECT, INSERT ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -564,7 +558,6 @@ revoke TRIGGER on *.* from test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -699,7 +692,6 @@ select f1 from t1 order by f1; f1 insert-yes insert-yes -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -768,9 +760,7 @@ Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, INSERT, UPDATE ON `priv1_db`.* TO 'test_noprivs'@'localhost' GRANT SELECT, INSERT ON `priv2_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv1_db; -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv1_db; trigger privilege on one db1 db level, not on db2 @@ -983,7 +973,6 @@ create User test_useprivs@localhost; set password for test_useprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; revoke ALL PRIVILEGES, GRANT OPTION FROM test_useprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1011,7 +1000,6 @@ select f1 from t1 order by f1; f1 trig 1_1-yes prepare ins1 from 'insert into t1 (f1) values (''insert2-no'')'; -connect(localhost,test_useprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_useprivs@localhost @@ -1207,7 +1195,6 @@ create table t1 (f1 char(20)) engine= myisam; create User test_yesprivs@localhost; set password for test_yesprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1319,8 +1306,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, UPDATE ON `priv_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); update only on column: ---------------------- diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_0407.result b/mysql-test/suite/funcs_1/r/myisam_trig_0407.result index 2f76f5544b9..b8d15b5403b 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_0407.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_0407.result @@ -68,8 +68,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_general@localhost; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; -connect(localhost,test_general,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_super,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.4: --------------- diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_08.result b/mysql-test/suite/funcs_1/r/myisam_trig_08.result index ab570072087..03505af95c5 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_08.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_08.result @@ -68,8 +68,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_general@localhost; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; -connect(localhost,test_general,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_super,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.8.1: (implied in previous tests) --------------------------------------------- diff --git a/mysql-test/suite/funcs_1/r/ndb_storedproc_06.result b/mysql-test/suite/funcs_1/r/ndb_storedproc_06.result index 67d9c76ccac..ee1548fe012 100644 --- a/mysql-test/suite/funcs_1/r/ndb_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/ndb_storedproc_06.result @@ -78,7 +78,6 @@ grant all on db_storedproc_1.* to 'user_1'@'localhost'; revoke create routine on db_storedproc_1.* from 'user_1'@'localhost'; flush privileges; DROP PROCEDURE IF EXISTS sp1; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -91,7 +90,6 @@ USE db_storedproc_1; root@localhost db_storedproc_1 GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -112,7 +110,6 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 DROP PROCEDURE IF EXISTS sp3; @@ -149,7 +146,6 @@ CREATE PROCEDURE sp4(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; END// -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 USE db_storedproc_1; @@ -191,7 +187,6 @@ grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; grant SELECT on db_storedproc_1.* to 'user_2'@'localhost'; grant execute on db_storedproc_1.* to 'user_2'@'localhost'; flush privileges; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 CREATE PROCEDURE sp5_s_i () sql security definer @@ -207,7 +202,6 @@ CREATE PROCEDURE sp5_ins () sql security definer BEGIN insert into db_storedproc_1.t3165 values ('inserted', 'from sp5_ins', 1000); END// -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp5_s_i(); @@ -305,7 +299,6 @@ GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc_1.* TO 'user_2'@'localhost'; GRANT EXECUTE ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_1,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc_1 CREATE PROCEDURE sp3166_s_i () SQL SECURITY INVOKER @@ -321,7 +314,6 @@ CREATE PROCEDURE sp3166_ins () SQL SECURITY INVOKER BEGIN insert into db_storedproc_1.t3166 values ('inserted from sp3166_ins'); END// -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -340,7 +332,6 @@ c1 inserted outside SP GRANT INSERT ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -361,7 +352,6 @@ inserted from sp3166_s_i inserted from sp3166_ins REVOKE SELECT ON db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); @@ -379,7 +369,6 @@ inserted from sp3166_ins root@localhost db_storedproc_1 REVOKE EXECUTE on db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc_1,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc_1 CALL sp3166_s_i(); diff --git a/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result b/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result index 24ebd38e403..6591a138d73 100644 --- a/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result +++ b/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result @@ -81,7 +81,6 @@ create user 'user_2'@'localhost'; GRANT CREATE ROUTINE ON db_storedproc.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_1,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc CREATE PROCEDURE sp31102 () SQL SECURITY INVOKER @@ -94,7 +93,6 @@ DECLARE res INT; SET res = n * n; RETURN res; END// -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); @@ -113,7 +111,6 @@ fn31105( 9 ) 81 GRANT EXECUTE ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); @@ -134,7 +131,6 @@ a` a` 1000-01-01 -5000 a` -5000 SELECT fn31105( 9 ); fn31105( 9 ) 81 -connect(localhost,user_2,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_2@localhost db_storedproc CALL sp31102(); diff --git a/mysql-test/suite/funcs_1/r/ndb_trig_03.result b/mysql-test/suite/funcs_1/r/ndb_trig_03.result index b02fba0f38d..a7fce94c91d 100644 --- a/mysql-test/suite/funcs_1/r/ndb_trig_03.result +++ b/mysql-test/suite/funcs_1/r/ndb_trig_03.result @@ -85,8 +85,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.3.2: ----------------- @@ -161,8 +159,6 @@ grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT UPDATE, TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_noprivs@localhost @@ -222,8 +218,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT UPDATE ON `priv_db`.* TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -296,8 +290,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT UPDATE ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -351,8 +343,6 @@ grant UPDATE (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs; Grants for test_noprivs@% GRANT TRIGGER ON *.* TO 'test_noprivs'@'%' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -407,8 +397,6 @@ grant TRIGGER, SELECT on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT SELECT, TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_noprivs@localhost @@ -464,8 +452,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.* TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -519,8 +505,6 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -565,8 +549,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO 'test_noprivs'@'localhost' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' @@ -611,7 +593,6 @@ Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT ON `priv_db`.`t2` TO 'test_yesprivs'@'localhost' GRANT SELECT, UPDATE ON `priv_db`.`t1` TO 'test_yesprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost diff --git a/mysql-test/suite/funcs_1/r/ndb_trig_03e.result b/mysql-test/suite/funcs_1/r/ndb_trig_03e.result index 84260822edf..ec7cbeb2876 100644 --- a/mysql-test/suite/funcs_1/r/ndb_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/ndb_trig_03e.result @@ -24,7 +24,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, INSERT ON `priv_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); no trigger privilege on db level for create: -------------------------------------------- @@ -32,7 +31,6 @@ use priv_db; create trigger trg1_1 before INSERT on t1 for each row set new.f1 = 'trig 1_1-no'; ERROR 42000: TRIGGER command denied to user 'test_yesprivs'@'localhost' for table 't1' -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv_db; insert into t1 (f1) values ('insert-yes'); select f1 from t1 order by f1; @@ -253,8 +251,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; create User test_noprivs@localhost; set password for test_noprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_noprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); no trigger privilege on table level for create: ----------------------------------------------- @@ -513,8 +509,6 @@ grant SELECT,INSERT on *.* to test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT SELECT, INSERT ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -563,7 +557,6 @@ revoke TRIGGER on *.* from test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -698,7 +691,6 @@ select f1 from t1 order by f1; f1 insert-yes insert-yes -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_yesprivs@localhost @@ -767,9 +759,7 @@ Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, INSERT, UPDATE ON `priv1_db`.* TO 'test_noprivs'@'localhost' GRANT SELECT, INSERT ON `priv2_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv1_db; -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); use priv1_db; trigger privilege on one db1 db level, not on db2 @@ -982,7 +972,6 @@ create User test_useprivs@localhost; set password for test_useprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; revoke ALL PRIVILEGES, GRANT OPTION FROM test_useprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1010,7 +999,6 @@ select f1 from t1 order by f1; f1 trig 1_1-yes prepare ins1 from 'insert into t1 (f1) values (''insert2-no'')'; -connect(localhost,test_useprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user test_useprivs@localhost @@ -1206,7 +1194,6 @@ create table t1 (f1 char(20)) engine= ndb; create User test_yesprivs@localhost; set password for test_yesprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1303,7 +1290,6 @@ create table t1 (f1 char(20)) engine= ndb; create User test_yesprivs@localhost; set password for test_yesprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user root@localhost @@ -1375,8 +1361,6 @@ show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT USAGE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT SELECT, UPDATE ON `priv_db`.* TO 'test_noprivs'@'localhost' -connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_noprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); update only on column: ---------------------- diff --git a/mysql-test/suite/funcs_1/r/ndb_trig_0407.result b/mysql-test/suite/funcs_1/r/ndb_trig_0407.result index 33e58f50ec1..8597f252e54 100644 --- a/mysql-test/suite/funcs_1/r/ndb_trig_0407.result +++ b/mysql-test/suite/funcs_1/r/ndb_trig_0407.result @@ -67,8 +67,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_general@localhost; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; -connect(localhost,test_general,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_super,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.4: --------------- diff --git a/mysql-test/suite/funcs_1/r/ndb_trig_08.result b/mysql-test/suite/funcs_1/r/ndb_trig_08.result index 6ced07cef73..b2b38694680 100644 --- a/mysql-test/suite/funcs_1/r/ndb_trig_08.result +++ b/mysql-test/suite/funcs_1/r/ndb_trig_08.result @@ -67,8 +67,6 @@ revoke ALL PRIVILEGES, GRANT OPTION FROM test_general@localhost; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; -connect(localhost,test_general,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); -connect(localhost,test_super,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); Testcase 3.5.8.1: (implied in previous tests) --------------------------------------------- diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result index 3efb361dc82..8da7213bded 100644 --- a/mysql-test/suite/funcs_1/r/storedproc.result +++ b/mysql-test/suite/funcs_1/r/storedproc.result @@ -1834,7 +1834,6 @@ CREATE PROCEDURE sp11() insert into mysql.t1 values('a'); SELECT security_type from mysql.proc where specific_name='sp11'; security_type DEFINER -connect(localhost,user_1,,db_storedproc,MYSQL_PORT,MYSQL_SOCK); user_1@localhost db_storedproc CALL sp11(); diff --git a/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc b/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc index f2df99fb5a3..4ecca63351d 100644 --- a/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc +++ b/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc @@ -53,7 +53,6 @@ flush privileges; DROP PROCEDURE IF EXISTS sp1; --enable_warnings ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user1a, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc @@ -75,7 +74,6 @@ USE db_storedproc_1; --source suite/funcs_1/include/show_connection.inc GRANT CREATE ROUTINE ON db_storedproc_1.* TO 'user_1'@'localhost'; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user1b, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc @@ -120,7 +118,6 @@ grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; # disconnect default; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user2, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc @@ -187,7 +184,6 @@ delimiter ;// #disconnect default; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user3, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc @@ -234,7 +230,6 @@ grant SELECT on db_storedproc_1.* to 'user_2'@'localhost'; grant execute on db_storedproc_1.* to 'user_2'@'localhost'; flush privileges; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user5_1, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc @@ -258,7 +253,6 @@ delimiter ;// disconnect user5_1; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user5_2, localhost, user_2, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc @@ -365,7 +359,6 @@ GRANT SELECT ON db_storedproc_1.* TO 'user_2'@'localhost'; GRANT EXECUTE ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user6_1, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc @@ -389,7 +382,6 @@ delimiter ;// disconnect user6_1; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user6_2, localhost, user_2, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc @@ -407,7 +399,6 @@ GRANT INSERT ON db_storedproc_1.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; disconnect user6_2; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user6_3, localhost, user_2, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc CALL sp3166_s_i(); @@ -422,7 +413,6 @@ CALL sp3166_sel(); REVOKE SELECT ON db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user6_4, localhost, user_2, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc --error ER_TABLEACCESS_DENIED_ERROR @@ -439,7 +429,6 @@ CALL sp3166_s_i(); REVOKE EXECUTE on db_storedproc_1.* FROM 'user_2'@'localhost'; FLUSH PRIVILEGES; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user6_5, localhost, user_2, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc --error ER_PROCACCESS_DENIED_ERROR diff --git a/mysql-test/suite/funcs_1/storedproc/storedproc_10.inc b/mysql-test/suite/funcs_1/storedproc/storedproc_10.inc index 83f5f2105c5..8382bcc1e55 100644 --- a/mysql-test/suite/funcs_1/storedproc/storedproc_10.inc +++ b/mysql-test/suite/funcs_1/storedproc/storedproc_10.inc @@ -58,7 +58,6 @@ GRANT CREATE ROUTINE ON db_storedproc.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user2_1, localhost, user_1, , db_storedproc); --source suite/funcs_1/include/show_connection.inc @@ -80,7 +79,6 @@ delimiter ;// disconnect user2_1; ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user2_2, localhost, user_2, , db_storedproc); --source suite/funcs_1/include/show_connection.inc @@ -102,7 +100,6 @@ FLUSH PRIVILEGES; disconnect user2_2; # new connection ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user2_3, localhost, user_2, , db_storedproc); --source suite/funcs_1/include/show_connection.inc CALL sp31102(); @@ -121,7 +118,6 @@ FLUSH PRIVILEGES; CALL sp31102(); SELECT fn31105( 9 ); ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user2_4, localhost, user_2, , db_storedproc); --source suite/funcs_1/include/show_connection.inc CALL sp31102(); diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03.inc b/mysql-test/suite/funcs_1/triggers/triggers_03.inc index 9ef6a9ac9af..f48d1979f77 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03.inc @@ -62,9 +62,7 @@ let $message= Testcase 3.5.3.2/6:; grant SELECT on priv_db.t1 to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -155,9 +153,7 @@ let $message=Testcase 3.5.3.7a:; grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs_424a,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs_424a,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection no_privs_424a; @@ -209,9 +205,7 @@ let $message= Testcase 3.5.3.7b:; grant UPDATE on priv_db.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs_424b,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs_424b,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -263,9 +257,7 @@ let $message= Testcase 3.5.3.7c; grant UPDATE on priv_db.t1 to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs_424c,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs_424c,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -316,9 +308,7 @@ let $message= Testcase 3.5.3.7d:; grant UPDATE (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs_424d,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs_424d,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -369,9 +359,7 @@ let $message= Testcase 3.5.3.8a:; grant TRIGGER, SELECT on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs_425a,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs_425a,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -426,9 +414,7 @@ let $message= Testcase: 3.5.3.8b; grant SELECT on priv_db.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs_425b,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs_425b,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -482,9 +468,7 @@ let $message= Testcase 3.5.3.8c:; grant SELECT on priv_db.t1 to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs_425c,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs_425c,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -534,9 +518,7 @@ let $message=Testcase: 3.5.3.8d:; grant SELECT (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs_425d,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs_425d,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -592,7 +574,6 @@ let $message=Testcase: 3.5.3.x:; grant SELECT on priv_db.t2 to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_353x,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection yes_353x; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc index 475063587d4..2f0ad2c1ccc 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc @@ -36,10 +36,8 @@ let $message= ####### Testcase for column privileges of triggers: #######; grant SELECT,UPDATE on priv_db.* to test_noprivs@localhost; show grants for test_noprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); # grant TRIGGER and UPDATE on column -> succeed diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc index e5933eb84a8..9e6d8598e6f 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc @@ -37,7 +37,6 @@ let $message= Testcase for db level:; show grants for test_noprivs@localhost; # no trigger privilege->create trigger must fail: - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); let $message= no trigger privilege on db level for create:; --source include/show_msg.inc @@ -47,7 +46,6 @@ let $message= no trigger privilege on db level for create:; set new.f1 = 'trig 1_1-no'; # user with minimum privs on t1->no trigger executed; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); use priv_db; insert into t1 (f1) values ('insert-yes'); diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc index 82f4a28f664..2bbcc5f88f0 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc @@ -41,10 +41,8 @@ let $message= ####### Testcase for mix of db and table level: #######; grant SELECT,INSERT on priv2_db.* to test_noprivs@localhost; show grants for test_noprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); use priv1_db; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); use priv1_db; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc index f1efff990f1..9988e1cafc2 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc @@ -27,7 +27,6 @@ let $message= ######### Testcase for definer: ########; revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); # create trigger with not existing definer shall deliver a warning: diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc index b6f4af7e0a7..eebdff5b588 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc @@ -38,10 +38,8 @@ let $message= #### Testcase for mix of user(global) and db level: ####; grant SELECT,INSERT on *.* to test_noprivs@localhost; show grants for test_noprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection yes_privs; @@ -83,7 +81,6 @@ let $message= trigger privilege on user level for create:; --disable_warnings disconnect yes_privs; --enable_warnings - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); select current_user; use priv_db; @@ -184,7 +181,6 @@ let $message= trigger privilege on db level for create:; --disable_warnings disconnect yes_privs; --enable_warnings - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); select current_user; use no_priv_db; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc index ea7c385768c..6258b040642 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc @@ -32,7 +32,6 @@ let $message= #### Testcase for trigger privilege on execution time ########; revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; revoke ALL PRIVILEGES, GRANT OPTION FROM test_useprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; @@ -56,7 +55,6 @@ let $message= #### Testcase for trigger privilege on execution time ########; select f1 from t1 order by f1; prepare ins1 from 'insert into t1 (f1) values (''insert2-no'')'; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (use_privs,localhost,test_useprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); select current_user; use priv_db; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc index 94f30fe13c2..ca4b9e2a0a9 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc @@ -30,10 +30,8 @@ let $message= ######### Testcase for table level: ########; set password for test_noprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_noprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); ################ Section 3.5.3 ############ diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc index e43f4ce97a3..2f72ba64bfd 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc @@ -27,7 +27,6 @@ let $message= ######### Testcase for transactions: ########; revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_0407.inc b/mysql-test/suite/funcs_1/triggers/triggers_0407.inc index d68b3d79086..2bc9dd66478 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_0407.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_0407.inc @@ -22,9 +22,7 @@ let $message= Testcase: 3.5:; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (con1_general,localhost,test_general,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (con1_super,localhost,test_super,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_08.inc b/mysql-test/suite/funcs_1/triggers/triggers_08.inc index 087f18e8e6b..996a5aa69ae 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_08.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_08.inc @@ -23,9 +23,7 @@ let $message= Testcase: 3.5:; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (con2_general,localhost,test_general,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); - --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (con2_super,localhost,test_super,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection default; diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result index a36b3a1a865..350c7ebd541 100644 --- a/mysql-test/suite/innodb/r/innodb-autoinc.result +++ b/mysql-test/suite/innodb/r/innodb-autoinc.result @@ -1244,3 +1244,16 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 DROP TABLE t1; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 VALUES (18446744073709551615); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb_bug56716.result b/mysql-test/suite/innodb/r/innodb_bug56716.result new file mode 100644 index 00000000000..50d83e8d87a --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56716.result @@ -0,0 +1,4 @@ +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; +a b c +DROP TABLE bug56716; diff --git a/mysql-test/suite/innodb/r/innodb_bug57255.result b/mysql-test/suite/innodb/r/innodb_bug57255.result new file mode 100644 index 00000000000..d61a0d42ba3 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug57255.result @@ -0,0 +1,10 @@ +create table A(id int not null primary key) engine=innodb; +create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb; +create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb; +insert into A values(1), (2); +DELETE FROM A where id = 1; +DELETE FROM C where f1 = 2; +DELETE FROM A where id = 1; +DROP TABLE C; +DROP TABLE B; +DROP TABLE A; diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index fa19dee7d26..5d90a96f61c 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2515,4 +2515,116 @@ LOCK TABLES t1 READ; ALTER TABLE t1 COMMENT 'test'; UNLOCK TABLES; DROP TABLE t1; +# +# Bug#55826: create table .. select crashes with when KILL_BAD_DATA +# is returned +# +CREATE TABLE t1(a INT) ENGINE=innodb; +INSERT INTO t1 VALUES (0); +SET SQL_MODE='STRICT_ALL_TABLES'; +CREATE TABLE t2 +SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`; +ERROR 22007: Incorrect datetime value: '' for column 'NOW()' at row 1 +DROP TABLE t1; +SET SQL_MODE=DEFAULT; +# +# Bug#55580: segfault in read_view_sees_trx_id +# +CREATE TABLE t1 (a INT) ENGINE=Innodb; +CREATE TABLE t2 (a INT) ENGINE=Innodb; +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (1),(2); +START TRANSACTION; +SELECT * FROM t2 LOCK IN SHARE MODE; +a +1 +2 +START TRANSACTION; +SELECT * FROM t1 LOCK IN SHARE MODE; +a +1 +2 +SELECT * FROM t1 FOR UPDATE; +# should not crash +SELECT * FROM t1 GROUP BY (SELECT a FROM t2 LIMIT 1 FOR UPDATE) + t1.a; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +DROP TABLE t1,t2; +# +# Bug#55656: mysqldump can be slower after bug #39653 fix +# +CREATE TABLE t1 (a INT , b INT, c INT, d INT, +KEY (b), PRIMARY KEY (a,b)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3); +EXPLAIN SELECT COUNT(*) FROM t1; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 4 +ref NULL +rows 3 +Extra Using index +DROP INDEX b ON t1; +CREATE INDEX b ON t1(a,b); +EXPLAIN SELECT COUNT(*) FROM t1; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key PRIMARY +key_len 8 +ref NULL +rows 3 +Extra Using index +DROP INDEX b ON t1; +CREATE INDEX b ON t1(a,b,c); +EXPLAIN SELECT COUNT(*) FROM t1; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key PRIMARY +key_len 8 +ref NULL +rows 3 +Extra Using index +DROP INDEX b ON t1; +CREATE INDEX b ON t1(a,b,c,d); +EXPLAIN SELECT COUNT(*) FROM t1; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key PRIMARY +key_len 8 +ref NULL +rows 3 +Extra Using index +DROP TABLE t1; +# End of 5.1 tests +# +# Test for bug #39932 "create table fails if column for FK is in different +# case than in corr index". +# +drop tables if exists t1, t2; +create table t1 (pk int primary key) engine=InnoDB; +# Even although the below statement uses uppercased field names in +# foreign key definition it still should be able to find explicitly +# created supporting index. So it should succeed and should not +# create any additional supporting indexes. +create table t2 (fk int, key x (fk), +constraint x foreign key (FK) references t1 (PK)) engine=InnoDB; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `fk` int(11) DEFAULT NULL, + KEY `x` (`fk`), + CONSTRAINT `x` FOREIGN KEY (`fk`) REFERENCES `t1` (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t2, t1; diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test index 0a7de237a42..f4ba2feab73 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc.test @@ -665,6 +665,18 @@ SELECT * FROM t1; SHOW CREATE TABLE t1; DROP TABLE t1; +## +# 55277: Failing assertion: auto_inc > 0 +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 VALUES (18446744073709551615); +# Restart the server +-- source include/restart_mysqld.inc +SHOW CREATE TABLE t1; +DROP TABLE t1; + --disable_query_log -EVAL SET GLOBAL innodb_file_format_check=$file_format_check; +eval SET GLOBAL innodb_file_format_check=$file_format_check; --enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb_bug53756.test b/mysql-test/suite/innodb/t/innodb_bug53756.test index 8324f2640a2..d3b0a77c680 100644 --- a/mysql-test/suite/innodb/t/innodb_bug53756.test +++ b/mysql-test/suite/innodb/t/innodb_bug53756.test @@ -34,8 +34,8 @@ INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44); --echo --echo # Select a less restrictive isolation level. # Don't use user variables. They won't survive server crash. ---let $global_isolation= `SELECT @@global.tx_isolation`; ---let $session_isolation= `SELECT @@session.tx_isolation`; +--let $global_isolation= `SELECT @@global.tx_isolation` +--let $session_isolation= `SELECT @@session.tx_isolation` SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; COMMIT; diff --git a/mysql-test/suite/innodb/t/innodb_bug56716.test b/mysql-test/suite/innodb/t/innodb_bug56716.test new file mode 100644 index 00000000000..3345038d9c1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56716.test @@ -0,0 +1,10 @@ +# +# Bug #56716 InnoDB locks a record gap without locking the table +# +-- source include/have_innodb.inc + +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; + +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; + +DROP TABLE bug56716; diff --git a/mysql-test/suite/innodb/t/innodb_bug57255.test b/mysql-test/suite/innodb/t/innodb_bug57255.test new file mode 100644 index 00000000000..2b37a0a6092 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug57255.test @@ -0,0 +1,36 @@ +# Test Bug #57255. Cascade deletes that affect different rows should not +# result in DB_FOREIGN_EXCEED_MAX_CASCADE error + +--source include/have_innodb.inc + +create table A(id int not null primary key) engine=innodb; + +create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb; + +create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb; + +insert into A values(1), (2); + +--disable_query_log +let $i=257; +while ($i) +{ +insert into B(f1) values(1); +dec $i; +} +let $i=486; +while ($i) +{ +insert into C(f1) values(2); +dec $i; +} +--enable_query_log + +# Following Deletes should not report error +DELETE FROM A where id = 1; +DELETE FROM C where f1 = 2; +DELETE FROM A where id = 1; + +DROP TABLE C; +DROP TABLE B; +DROP TABLE A; diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index 1171eaa899c..991440e54dd 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -504,11 +504,7 @@ INSERT INTO t2 VALUES (),(); CREATE OR REPLACE VIEW v1 AS SELECT 1 FROM t2 WHERE b =(SELECT a FROM t1 LIMIT 1); ---disable_query_log ---disable_result_log CONNECT (con1, localhost, root,,); ---enable_query_log ---enable_result_log CONNECTION default; DELIMITER |; @@ -768,4 +764,101 @@ UNLOCK TABLES; DROP TABLE t1; +--echo # +--echo # Bug#55826: create table .. select crashes with when KILL_BAD_DATA +--echo # is returned +--echo # +CREATE TABLE t1(a INT) ENGINE=innodb; +INSERT INTO t1 VALUES (0); +SET SQL_MODE='STRICT_ALL_TABLES'; +--error ER_TRUNCATED_WRONG_VALUE +CREATE TABLE t2 + SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`; +DROP TABLE t1; +SET SQL_MODE=DEFAULT; + + + +--echo # +--echo # Bug#55580: segfault in read_view_sees_trx_id +--echo # +CREATE TABLE t1 (a INT) ENGINE=Innodb; +CREATE TABLE t2 (a INT) ENGINE=Innodb; +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (1),(2); + +connect (con1,localhost,root,,test); +connect (con2,localhost,root,,test); + +connection con1; +START TRANSACTION; +SELECT * FROM t2 LOCK IN SHARE MODE; + +connection con2; +START TRANSACTION; +SELECT * FROM t1 LOCK IN SHARE MODE; + +connection con1; +let $conn_id= `SELECT CONNECTION_ID()`; +--send SELECT * FROM t1 FOR UPDATE + +connection con2; +let $wait_timeout= 2; +let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST +WHERE ID=$conn_id AND STATE='Sending data'; +--source include/wait_condition.inc +--echo # should not crash +--error ER_LOCK_DEADLOCK +SELECT * FROM t1 GROUP BY (SELECT a FROM t2 LIMIT 1 FOR UPDATE) + t1.a; + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug#55656: mysqldump can be slower after bug #39653 fix +--echo # + +CREATE TABLE t1 (a INT , b INT, c INT, d INT, + KEY (b), PRIMARY KEY (a,b)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3); +--query_vertical EXPLAIN SELECT COUNT(*) FROM t1 + +DROP INDEX b ON t1; +CREATE INDEX b ON t1(a,b); +--query_vertical EXPLAIN SELECT COUNT(*) FROM t1 + +DROP INDEX b ON t1; +CREATE INDEX b ON t1(a,b,c); +--query_vertical EXPLAIN SELECT COUNT(*) FROM t1 + +DROP INDEX b ON t1; +CREATE INDEX b ON t1(a,b,c,d); +--query_vertical EXPLAIN SELECT COUNT(*) FROM t1 + +DROP TABLE t1; + +--echo # + + --echo End of 5.1 tests + + +--echo # +--echo # Test for bug #39932 "create table fails if column for FK is in different +--echo # case than in corr index". +--echo # +--disable_warnings +drop tables if exists t1, t2; +--enable_warnings +create table t1 (pk int primary key) engine=InnoDB; +--echo # Even although the below statement uses uppercased field names in +--echo # foreign key definition it still should be able to find explicitly +--echo # created supporting index. So it should succeed and should not +--echo # create any additional supporting indexes. +create table t2 (fk int, key x (fk), + constraint x foreign key (FK) references t1 (PK)) engine=InnoDB; +show create table t2; +drop table t2, t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result b/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result index a36b3a1a865..350c7ebd541 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result @@ -1244,3 +1244,16 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 DROP TABLE t1; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 VALUES (18446744073709551615); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug53756.result b/mysql-test/suite/innodb_plugin/r/innodb_bug53756.result new file mode 100644 index 00000000000..37453be8201 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug53756.result @@ -0,0 +1,118 @@ +DROP TABLE IF EXISTS bug_53756 ; +CREATE TABLE bug_53756 (pk INT, c1 INT) ENGINE=InnoDB; +ALTER TABLE bug_53756 ADD PRIMARY KEY (pk); +INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44); + +# Select a less restrictive isolation level. +SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +COMMIT; + +# Start a transaction in the default connection for isolation. +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +SELECT * FROM bug_53756; +pk c1 +1 11 +2 22 +3 33 +4 44 + +# connection con1 deletes row 1 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +DELETE FROM bug_53756 WHERE pk=1; + +# connection con2 deletes row 2 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +DELETE FROM bug_53756 WHERE pk=2; + +# connection con3 updates row 3 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +UPDATE bug_53756 SET c1=77 WHERE pk=3; + +# connection con4 updates row 4 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +UPDATE bug_53756 SET c1=88 WHERE pk=4; + +# connection con5 inserts row 5 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +INSERT INTO bug_53756 VALUES(5, 55); + +# connection con6 inserts row 6 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +INSERT INTO bug_53756 VALUES(6, 66); + +# connection con1 commits. +COMMIT; + +# connection con3 commits. +COMMIT; + +# connection con4 rolls back. +ROLLBACK; + +# connection con6 rolls back. +ROLLBACK; + +# The connections 2 and 5 stay open. + +# connection default selects resulting data. +# Delete of row 1 was committed. +# Update of row 3 was committed. +# Due to isolation level read committed, these should be included. +# All other changes should not be included. +SELECT * FROM bug_53756; +pk c1 +2 22 +3 77 +4 44 + +# connection default +# +# Crash server. +START TRANSACTION; +INSERT INTO bug_53756 VALUES (666,666); +SET SESSION debug="+d,crash_commit_before"; +COMMIT; +ERROR HY000: Lost connection to MySQL server during query + +# +# disconnect con1, con2, con3, con4, con5, con6. +# +# Restart server. + +# +# Select recovered data. +# Delete of row 1 was committed. +# Update of row 3 was committed. +# These should be included. +# All other changes should not be included. +# Delete of row 2 and insert of row 5 should be rolled back +SELECT * FROM bug_53756; +pk c1 +2 22 +3 77 +4 44 + +# Clean up. +DROP TABLE bug_53756; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56716.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56716.result new file mode 100644 index 00000000000..50d83e8d87a --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56716.result @@ -0,0 +1,4 @@ +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; +a b c +DROP TABLE bug56716; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug57255.result b/mysql-test/suite/innodb_plugin/r/innodb_bug57255.result new file mode 100644 index 00000000000..d61a0d42ba3 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug57255.result @@ -0,0 +1,10 @@ +create table A(id int not null primary key) engine=innodb; +create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb; +create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb; +insert into A values(1), (2); +DELETE FROM A where id = 1; +DELETE FROM C where f1 = 2; +DELETE FROM A where id = 1; +DROP TABLE C; +DROP TABLE B; +DROP TABLE A; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 53e979c350f..32ee3c21946 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -2390,4 +2390,14 @@ a 2 UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; DROP TABLE t1,t2; +# +# Bug#54606 innodb fast alter table + pack_keys=0 +# prevents adding new indexes +# +CREATE TABLE t1 (a INT, b CHAR(9), c INT, key(b)) +ENGINE=InnoDB +PACK_KEYS=0; +CREATE INDEX a ON t1 (a); +CREATE INDEX c on t1 (c); +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test b/mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test index 5e4cf9dcb4c..99cdac72e2e 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test @@ -1,8 +1,6 @@ -- source include/have_innodb_plugin.inc # embedded server ignores 'delayed', so skip this -- source include/not_embedded.inc -# remove the next line after bug #55503 is fixed --- source include/not_valgrind.inc let $innodb_file_format_check_orig=`select @@innodb_file_format_check`; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test b/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test index 49394a019d0..997c503d2d3 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test @@ -1,8 +1,6 @@ -- source include/have_innodb_plugin.inc # embedded server ignores 'delayed', so skip this -- source include/not_embedded.inc -# remove the next line after bug #55503 is fixed --- source include/not_valgrind.inc let $innodb_file_format_check_orig=`select @@innodb_file_format_check`; @@ -667,6 +665,18 @@ SELECT * FROM t1; SHOW CREATE TABLE t1; DROP TABLE t1; +## +# 55277: Failing assertion: auto_inc > 0 +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(c1 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 VALUES (18446744073709551615); +# Restart the server +-- source include/restart_mysqld.inc +SHOW CREATE TABLE t1; +DROP TABLE t1; + # # restore environment to the state it was before this test execution # diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53756-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_bug53756-master.opt new file mode 100644 index 00000000000..425fda95086 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53756-master.opt @@ -0,0 +1 @@ +--skip-stack-trace --skip-core-file diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test b/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test new file mode 100644 index 00000000000..8c48550a64d --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test @@ -0,0 +1,184 @@ +# This is the test case for bug #53756. Alter table operation could +# leave a deleted record for the temp table (later renamed to the altered +# table) in the SYS_TABLES secondary index, we should ignore this row and +# find the first non-deleted row for the specified table_id when load table +# metadata in the function dict_load_table_on_id() during crash recovery. + +# +# innobackup needs to connect to the server. Not supported in embedded. +--source include/not_embedded.inc +# +# This test case needs to crash the server. Needs a debug server. +--source include/have_debug.inc +# +# Don't test this under valgrind, memory leaks will occur. +--source include/not_valgrind.inc +# +# This test case needs InnoDB. +-- source include/have_innodb_plugin.inc + +# +# Precautionary clean up. +# +--disable_warnings +DROP TABLE IF EXISTS bug_53756 ; +--enable_warnings + +# +# Create test data. +# +CREATE TABLE bug_53756 (pk INT, c1 INT) ENGINE=InnoDB; +ALTER TABLE bug_53756 ADD PRIMARY KEY (pk); +INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44); + +--echo +--echo # Select a less restrictive isolation level. +# Don't use user variables. They won't survive server crash. +--let $global_isolation= `SELECT @@global.tx_isolation` +--let $session_isolation= `SELECT @@session.tx_isolation` +SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +COMMIT; + +--echo +--echo # Start a transaction in the default connection for isolation. +START TRANSACTION; +SELECT @@tx_isolation; +SELECT * FROM bug_53756; + +--echo +--echo # connection con1 deletes row 1 +--connect (con1,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +DELETE FROM bug_53756 WHERE pk=1; + +--echo +--echo # connection con2 deletes row 2 +--connect (con2,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +DELETE FROM bug_53756 WHERE pk=2; + +--echo +--echo # connection con3 updates row 3 +--connect (con3,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +UPDATE bug_53756 SET c1=77 WHERE pk=3; + +--echo +--echo # connection con4 updates row 4 +--connect (con4,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +UPDATE bug_53756 SET c1=88 WHERE pk=4; + +--echo +--echo # connection con5 inserts row 5 +--connect (con5,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +INSERT INTO bug_53756 VALUES(5, 55); + +--echo +--echo # connection con6 inserts row 6 +--connect (con6,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +INSERT INTO bug_53756 VALUES(6, 66); + +--echo +--echo # connection con1 commits. +--connection con1 +COMMIT; + +--echo +--echo # connection con3 commits. +--connection con3 +COMMIT; + +--echo +--echo # connection con4 rolls back. +--connection con4 +ROLLBACK; + +--echo +--echo # connection con6 rolls back. +--connection con6 +ROLLBACK; + +--echo +--echo # The connections 2 and 5 stay open. + +--echo +--echo # connection default selects resulting data. +--echo # Delete of row 1 was committed. +--echo # Update of row 3 was committed. +--echo # Due to isolation level read committed, these should be included. +--echo # All other changes should not be included. +--connection default +SELECT * FROM bug_53756; + +--echo +--echo # connection default +--connection default +--echo # +--echo # Crash server. +# +# Write file to make mysql-test-run.pl expect the "crash", but don't start +# it until it's told to +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# +START TRANSACTION; +INSERT INTO bug_53756 VALUES (666,666); +# +# Request a crash on next execution of commit. +SET SESSION debug="+d,crash_commit_before"; +# +# Execute the statement that causes the crash. +--error 2013 +COMMIT; +--echo +--echo # +--echo # disconnect con1, con2, con3, con4, con5, con6. +--disconnect con1 +--disconnect con2 +--disconnect con3 +--disconnect con4 +--disconnect con5 +--disconnect con6 +--echo # +--echo # Restart server. +# +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# +# Turn on reconnect +--enable_reconnect +# +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc +# +# Turn off reconnect again +--disable_reconnect +--echo + +--echo # +--echo # Select recovered data. +--echo # Delete of row 1 was committed. +--echo # Update of row 3 was committed. +--echo # These should be included. +--echo # All other changes should not be included. +--echo # Delete of row 2 and insert of row 5 should be rolled back +SELECT * FROM bug_53756; + +--echo +--echo # Clean up. +DROP TABLE bug_53756; + +--disable_query_log +eval SET GLOBAL tx_isolation= '$global_isolation'; +eval SET SESSION tx_isolation= '$session_isolation'; +--enable_query_log + diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56716.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56716.test new file mode 100644 index 00000000000..24e90f5acc5 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56716.test @@ -0,0 +1,10 @@ +# +# Bug #56716 InnoDB locks a record gap without locking the table +# +-- source include/have_innodb_plugin.inc + +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; + +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; + +DROP TABLE bug56716; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test b/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test new file mode 100644 index 00000000000..96184c355b6 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test @@ -0,0 +1,36 @@ +# Test Bug #57255. Cascade deletes that affect different rows should not +# result in DB_FOREIGN_EXCEED_MAX_CASCADE error + +--source include/have_innodb_plugin.inc + +create table A(id int not null primary key) engine=innodb; + +create table B(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references A(id) on delete cascade) engine=innodb; + +create table C(id int not null auto_increment primary key, f1 int not null, foreign key(f1) references B(id) on delete cascade) engine=innodb; + +insert into A values(1), (2); + +--disable_query_log +let $i=257; +while ($i) +{ +insert into B(f1) values(1); +dec $i; +} +let $i=486; +while ($i) +{ +insert into C(f1) values(2); +dec $i; +} +--enable_query_log + +# Following Deletes should not report error +DELETE FROM A where id = 1; +DELETE FROM C where f1 = 2; +DELETE FROM A where id = 1; + +DROP TABLE C; +DROP TABLE B; +DROP TABLE A; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test index 5adaba43050..4855d9e2055 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test @@ -634,4 +634,18 @@ UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; DROP TABLE t1,t2; +--echo # +--echo # Bug#54606 innodb fast alter table + pack_keys=0 +--echo # prevents adding new indexes +--echo # + +CREATE TABLE t1 (a INT, b CHAR(9), c INT, key(b)) + ENGINE=InnoDB + PACK_KEYS=0; +CREATE INDEX a ON t1 (a); +CREATE INDEX c on t1 (c); + +DROP TABLE t1; + + --echo End of 5.1 tests diff --git a/mysql-test/suite/maria/r/ps_maria.result b/mysql-test/suite/maria/r/ps_maria.result index e2dcfc68d46..c4dfe826b4d 100644 --- a/mysql-test/suite/maria/r/ps_maria.result +++ b/mysql-test/suite/maria/r/ps_maria.result @@ -1929,26 +1929,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1976,26 +1976,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2026,26 +2026,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2066,26 +2066,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2114,26 +2114,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2158,26 +2158,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2204,26 +2204,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2242,26 +2242,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/suite/ndb/r/ps_7ndb.result b/mysql-test/suite/ndb/r/ps_7ndb.result index 6a6b0129548..b94e5d7cba3 100644 --- a/mysql-test/suite/ndb/r/ps_7ndb.result +++ b/mysql-test/suite/ndb/r/ps_7ndb.result @@ -1912,26 +1912,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1959,26 +1959,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2009,26 +2009,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2049,26 +2049,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2097,26 +2097,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2141,26 +2141,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2187,26 +2187,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2225,26 +2225,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/suite/parts/r/partition_alter3_innodb.result b/mysql-test/suite/parts/r/partition_alter3_innodb.result index cb104d4be54..7825a2350b0 100644 --- a/mysql-test/suite/parts/r/partition_alter3_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter3_innodb.result @@ -141,7 +141,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 7 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -165,7 +165,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -190,7 +190,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 3 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -226,7 +226,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 3 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -248,7 +248,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -269,7 +269,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -289,7 +289,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -308,7 +308,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 7 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -326,7 +326,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 10 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -452,7 +452,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 7 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -476,7 +476,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 5 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -504,7 +504,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 3 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -538,7 +538,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -563,7 +563,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 3 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -587,7 +587,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 23 Using where +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 10 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -610,7 +610,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 5 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -632,7 +632,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 7 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -653,7 +653,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 10 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 diff --git a/mysql-test/suite/parts/r/partition_alter3_myisam.result b/mysql-test/suite/parts/r/partition_alter3_myisam.result index 374b108b57e..a5dec48e85c 100644 --- a/mysql-test/suite/parts/r/partition_alter3_myisam.result +++ b/mysql-test/suite/parts/r/partition_alter3_myisam.result @@ -155,7 +155,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 7 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -187,7 +187,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -228,7 +228,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 3 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -278,7 +278,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 3 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -312,7 +312,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 4 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -343,7 +343,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -371,7 +371,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 5 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -396,7 +396,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part1 ALL NULL NULL NULL NULL 7 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -418,7 +418,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 10 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -552,7 +552,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 7 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -584,7 +584,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 5 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -628,7 +628,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p6 ALL NULL NULL NULL NULL 3 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -676,7 +676,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -713,7 +713,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 3 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -747,7 +747,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 10 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -778,7 +778,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 5 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -806,7 +806,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 part7 ALL NULL NULL NULL NULL 7 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 @@ -831,7 +831,7 @@ t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 10 Using where # check read single success: 1 # check read all success: 1 # check read row by row success: 1 diff --git a/mysql-test/suite/parts/r/partition_repair_myisam.result b/mysql-test/suite/parts/r/partition_repair_myisam.result index 2d0a26b397c..4af00ddcc6d 100644 --- a/mysql-test/suite/parts/r/partition_repair_myisam.result +++ b/mysql-test/suite/parts/r/partition_repair_myisam.result @@ -408,7 +408,7 @@ ALTER TABLE t1_will_crash CHECK PARTITION p6; Table Op Msg_type Msg_text test.t1_will_crash check warning Size of datafile is: 868 Should be: 604 test.t1_will_crash check error Record-count is not ok; is 8 Should be: 7 -test.t1_will_crash check warning Found 10 key parts. Should be: 7 +test.t1_will_crash check warning Found 10 parts. Should be: 7 test.t1_will_crash check error Partition p6 returned error test.t1_will_crash check error Corrupt ALTER TABLE t1_will_crash REPAIR PARTITION p6; diff --git a/mysql-test/suite/pbxt/r/func_sapdb.result b/mysql-test/suite/pbxt/r/func_sapdb.result index 7a61f434d2f..b0c697e54ac 100644 --- a/mysql-test/suite/pbxt/r/func_sapdb.result +++ b/mysql-test/suite/pbxt/r/func_sapdb.result @@ -185,7 +185,7 @@ date("1997-12-31 23:59:59.000001") as f8, time("1997-12-31 23:59:59.000001") as f9; describe t1; Field Type Null Key Default Extra -f1 date NO 0000-00-00 +f1 date YES NULL f2 datetime YES NULL f3 time YES NULL f4 time YES NULL diff --git a/mysql-test/suite/pbxt/r/join_nested.result b/mysql-test/suite/pbxt/r/join_nested.result index 4e687b810db..5495ba2a55d 100644 --- a/mysql-test/suite/pbxt/r/join_nested.result +++ b/mysql-test/suite/pbxt/r/join_nested.result @@ -232,7 +232,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Warnings: -Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10))) where 1 +Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`))) where 1 SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM (t6, t7) LEFT JOIN @@ -553,7 +553,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`))) SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM t0,t1 @@ -649,7 +649,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) SELECT t9.a,t9.b FROM t9; a b @@ -840,7 +840,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) where (`test`.`t1`.`a` <= 2) +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) where (`test`.`t1`.`a` <= 2) CREATE INDEX idx_b ON t2(b); EXPLAIN EXTENDED SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b @@ -854,7 +854,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 1 100.00 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Warnings: -Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t3`.`a` = 1) and (`test`.`t3`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) where 1 +Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t3`.`a` = 1) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`)))) where 1 SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b FROM (t3,t4) LEFT JOIN @@ -916,7 +916,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) CREATE INDEX idx_b ON t4(b); CREATE INDEX idx_b ON t5(b); EXPLAIN EXTENDED @@ -966,7 +966,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`))) CREATE INDEX idx_b ON t8(b); EXPLAIN SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, @@ -1487,7 +1487,7 @@ on (t1.a = t2.a); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 1 SIMPLE t2 ref a a 5 test.t1.a 1 -1 SIMPLE t3 ref a a 5 test.t2.a 1 +1 SIMPLE t3 ref a a 5 test.t1.a 1 drop table t1, t2, t3; CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, type varchar(10)); CREATE TABLE t2 (pid int NOT NULL PRIMARY KEY, type varchar(10)); diff --git a/mysql-test/suite/pbxt/r/negation_elimination.result b/mysql-test/suite/pbxt/r/negation_elimination.result index fdf09954e18..f3edfccf67e 100644 --- a/mysql-test/suite/pbxt/r/negation_elimination.result +++ b/mysql-test/suite/pbxt/r/negation_elimination.result @@ -388,7 +388,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index NULL a 5 NULL 21 100.00 Using where; Using index +1 SIMPLE t1 index NULL a 5 NULL 5 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where `test`.`t1`.`a` having `test`.`t1`.`a` drop table t1; diff --git a/mysql-test/suite/pbxt/r/select.result b/mysql-test/suite/pbxt/r/select.result index f85e6ccab1d..11244cd3689 100644 --- a/mysql-test/suite/pbxt/r/select.result +++ b/mysql-test/suite/pbxt/r/select.result @@ -1384,52 +1384,52 @@ Table Op Msg_type Msg_text test.t2 analyze status OK explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; companynr companynr 37 36 @@ -1437,7 +1437,7 @@ companynr companynr explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Using join buffer +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008; fld1 companynr fld3 period 038008 37 reporters 1008 @@ -1511,7 +1511,7 @@ count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1) 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069 explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>""; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 100.00 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> '')) select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3; @@ -1955,7 +1955,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE explain select fld3 from t2 where fld1=fld1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502; companynr fld1 34 250501 @@ -2007,7 +2007,7 @@ count(*) 4181 explain select min(fld1),max(fld1),count(*) from t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index NULL fld1 4 NULL 1200 Using index +1 SIMPLE t2 index NULL fld1 4 NULL 1199 Using index select min(fld1),max(fld1),count(*) from t2; min(fld1) max(fld1) count(*) 0 1232609 1199 @@ -2093,9 +2093,9 @@ show full columns from t2 from test like 's%'; Field Type Collation Null Key Default Extra Privileges Comment show keys from t2; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t2 0 PRIMARY 1 auto A 1200 NULL NULL BTREE -t2 0 fld1 1 fld1 A 1200 NULL NULL BTREE -t2 1 fld3 1 fld3 A 1200 NULL NULL BTREE +t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE +t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE +t2 1 fld3 1 fld3 A 1199 NULL NULL BTREE drop table t4, t3, t2, t1; DO 1; DO benchmark(100,1+1),1,1; diff --git a/mysql-test/suite/percona/percona_query_response_time-stored.result b/mysql-test/suite/percona/percona_query_response_time-stored.result index 386180c791a..df51f2bfd58 100644 --- a/mysql-test/suite/percona/percona_query_response_time-stored.result +++ b/mysql-test/suite/percona/percona_query_response_time-stored.result @@ -22,12 +22,13 @@ SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 2 FLUSH QUERY_RESPONSE_TIME; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 44 @@ -76,7 +77,7 @@ time 2097152.00000 4194304.00000 8388608.00000 -TOO LONG QUERY +TOO LONG SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1; SELECT test_f(); test_f() @@ -91,14 +92,15 @@ SELECT test_f(); test_f() Hello, world! SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 5 2 44 -4 5 2 44 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 5 4 2 44 +4 5 4 2 44 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 44 @@ -147,7 +149,7 @@ time 2097152.00000 4194304.00000 8388608.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 2 @@ -161,14 +163,15 @@ SELECT test_f(); test_f() Hello, world! SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 2 2 14 -1 2 2 14 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 2 1 2 14 +1 2 1 2 14 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 14 @@ -187,7 +190,7 @@ time 10000.000000 100000.000000 1000000.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 10 @@ -201,14 +204,15 @@ SELECT test_f(); test_f() Hello, world! SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 2 2 17 -1 2 2 17 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 2 1 2 17 +1 2 1 2 17 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 17 @@ -230,7 +234,7 @@ time 117649.000000 823543.000000 5764801.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 7 @@ -244,14 +248,15 @@ SELECT test_f(); test_f() Hello, world! SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 2 2 7 -1 2 2 7 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 2 1 2 7 +1 2 1 2 7 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 7 @@ -263,7 +268,7 @@ time 156.000000 24336.000000 3796416.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 156 @@ -277,14 +282,15 @@ SELECT test_f(); test_f() Hello, world! SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 2 2 6 -1 2 2 6 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 2 1 2 6 +1 2 1 2 6 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 6 @@ -295,7 +301,7 @@ time 1.000000 1000.000000 1000000.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 1000 diff --git a/mysql-test/suite/percona/percona_query_response_time.result b/mysql-test/suite/percona/percona_query_response_time.result index 3c12284a525..54657b6ca06 100644 --- a/mysql-test/suite/percona/percona_query_response_time.result +++ b/mysql-test/suite/percona/percona_query_response_time.result @@ -9,12 +9,13 @@ SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 2 FLUSH QUERY_RESPONSE_TIME; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 44 @@ -63,7 +64,7 @@ time 2097152.00000 4194304.00000 8388608.00000 -TOO LONG QUERY +TOO LONG SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1; SELECT SLEEP(0.31); SLEEP(0.31) @@ -123,17 +124,18 @@ SELECT SLEEP(2.5); SLEEP(2.5) 0 SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 20 5 44 -10 20 5 44 -1 20 5 44 -5 20 5 44 -3 20 5 44 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 20 15 5 44 +10 20 15 5 44 +1 20 15 5 44 +5 20 15 5 44 +3 20 15 5 44 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 44 @@ -182,7 +184,7 @@ time 2097152.00000 4194304.00000 8388608.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 2 @@ -250,15 +252,16 @@ SELECT SLEEP(2.5); SLEEP(2.5) 0 SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 20 3 14 -11 20 3 14 -8 20 3 14 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 20 17 3 14 +11 20 17 3 14 +8 20 17 3 14 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 14 @@ -277,7 +280,7 @@ time 10000.000000 100000.000000 1000000.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 10 @@ -345,15 +348,16 @@ SELECT SLEEP(2.5); SLEEP(2.5) 0 SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 20 3 17 -11 20 3 17 -8 20 3 17 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 20 17 3 17 +11 20 17 3 17 +8 20 17 3 17 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 17 @@ -375,7 +379,7 @@ time 117649.000000 823543.000000 5764801.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 7 @@ -443,15 +447,16 @@ SELECT SLEEP(2.5); SLEEP(2.5) 0 SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 20 3 7 -11 20 3 7 -8 20 3 7 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 20 17 3 7 +11 20 17 3 7 +8 20 17 3 7 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 7 @@ -463,7 +468,7 @@ time 156.000000 24336.000000 3796416.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 156 @@ -531,15 +536,16 @@ SELECT SLEEP(2.5); SLEEP(2.5) 0 SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0; -SELECT c.count, +SELECT d.count, (SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count, -(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count, +(SELECT SUM((b.total * 1000000) DIV 1000000) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as query_total, +(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count != 0) as not_zero_region_count, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count -FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0; -count query_count not_zero_region_count region_count -1 20 3 6 -11 20 3 6 -8 20 3 6 +FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as d WHERE d.count > 0; +count query_count query_total not_zero_region_count region_count +1 20 17 3 6 +11 20 17 3 6 +8 20 17 3 6 SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; region_count 6 @@ -550,7 +556,7 @@ time 1.000000 1000.000000 1000000.00000 -TOO LONG QUERY +TOO LONG SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; Variable_name Value query_response_time_range_base 1000 diff --git a/mysql-test/suite/percona/percona_server_variables.result b/mysql-test/suite/percona/percona_server_variables.result index 25f961b201f..cb2af0d3d0e 100644 --- a/mysql-test/suite/percona/percona_server_variables.result +++ b/mysql-test/suite/percona/percona_server_variables.result @@ -77,8 +77,10 @@ innodb_adaptive_checkpoint Value innodb_adaptive_flushing Value innodb_adaptive_hash_index Value innodb_additional_mem_pool_size Value +innodb_auto_lru_dump Value innodb_autoextend_increment Value innodb_autoinc_lock_mode Value +innodb_buffer_pool_shm_checksum Value innodb_buffer_pool_shm_key Value innodb_buffer_pool_size Value innodb_change_buffering Value diff --git a/mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result b/mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result index 3bf33044d75..f826136e81e 100644 --- a/mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result +++ b/mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result @@ -139,14 +139,14 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO db1.t1 VALUES(20) -master-bin.000001 # Query # # SAVEPOINT has_comment +master-bin.000001 # Query # # SAVEPOINT `has_comment` master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t1 VALUES(30) master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t2 VALUES("in savepoint has_comment") -master-bin.000001 # Query # # SAVEPOINT mixed_cases +master-bin.000001 # Query # # SAVEPOINT `mixed_cases` master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t2 VALUES("in savepoint mixed_cases") master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t1 VALUES(40) -master-bin.000001 # Query # # ROLLBACK TO mixed_cases -master-bin.000001 # Query # # ROLLBACK TO has_comment +master-bin.000001 # Query # # ROLLBACK TO `mixed_cases` +master-bin.000001 # Query # # ROLLBACK TO `has_comment` master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t2 VALUES("after rollback to") master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t1 VALUES(50) master-bin.000001 # Xid # # COMMIT /* XID */ diff --git a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result index fc53aca5136..e3cddf4c606 100644 --- a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result +++ b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result @@ -65,3 +65,12 @@ c1 DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; + +# Bug#55616 Killing thread or query during CREATE IF NOT EXISTS makes +# slave SQL thread abort + +CREATE TABLE t1 ( i INT ); +CREATE TABLE IF NOT EXISTS t1 +AS SELECT SLEEP(3); +KILL QUERY master1; +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_create_tmp_table_if_not_exists.result b/mysql-test/suite/rpl/r/rpl_create_tmp_table_if_not_exists.result index 8d0b61cc6d8..de44a1e5d2a 100644 --- a/mysql-test/suite/rpl/r/rpl_create_tmp_table_if_not_exists.result +++ b/mysql-test/suite/rpl/r/rpl_create_tmp_table_if_not_exists.result @@ -19,4 +19,9 @@ master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS t master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp -master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `tmp2` ( + `c1` int(11) DEFAULT NULL +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`tmp2` (`c1`) SELECT * FROM tmp +master-bin.000001 # Query # # COMMIT diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 35f4cd3ecbb..d076a24e1f0 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -883,8 +883,8 @@ master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # BEGIN -master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query # # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, `b`) ;file_id=# +master-bin.000001 # Table_map # # table_id: # (test_rpl.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test_rpl`; DELETE FROM t1 @@ -997,7 +997,7 @@ master-bin.000001 # Query # # use `test_rpl`; INSERT INTO t1 VALUES (3, 'before master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test_rpl`; INSERT INTO t1 VALUES (5, 'before savepoint s2') -master-bin.000001 # Query # # SAVEPOINT s2 +master-bin.000001 # Query # # SAVEPOINT `s2` master-bin.000001 # Query # # use `test_rpl`; INSERT INTO t1 VALUES (6, 'after savepoint s2') master-bin.000001 # Table_map # # table_id: # (test_rpl.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F diff --git a/mysql-test/suite/rpl/r/rpl_row_create_table.result b/mysql-test/suite/rpl/r/rpl_row_create_table.result index e480ff3dfe9..c6aa05f9e90 100644 --- a/mysql-test/suite/rpl/r/rpl_row_create_table.result +++ b/mysql-test/suite/rpl/r/rpl_row_create_table.result @@ -467,4 +467,10 @@ DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3; DROP TEMPORARY TABLES t7; DROP TABLES t4, t5; DROP TABLES IF EXISTS bug48506_t4; +CREATE TABLE t1 SELECT 1; +CREATE TABLE IF NOT EXISTS t1 SELECT 1; +Warnings: +Note 1050 Table 't1' already exists +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; end of the tests diff --git a/mysql-test/suite/rpl/r/rpl_stm_create_if_not_exists.result b/mysql-test/suite/rpl/r/rpl_stm_create_if_not_exists.result new file mode 100644 index 00000000000..9ae1ef315b6 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_stm_create_if_not_exists.result @@ -0,0 +1,704 @@ +# WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT +# EXISTS ... SELECT' behaviour +# +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; + + +CREATE TABLE t2(c1 INT, c2 char(10)); +INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc'); + +# The original query should be binlogged if the table does not exist. +# ------------------------------------------------------------------ + +CREATE TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY) +SELECT 'abc' AS c3, 1 AS c4; +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY) +SELECT 'abc' AS c3, 1 AS c4 +Comparing tables master:test.t1 and slave:test.t1 + +# The statement should be binlogged as two events. one is +# 'CREATE TABLE IF NOT EXISTS ..', another one is +# 'INSERT ... SELECT'. +# ------------------------------------------------------------------ + +CREATE TABLE IF NOT EXISTS t1 +SELECT 'abc', 2; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 2 +master-bin.000001 # Query # # COMMIT +Comparing tables master:test.t1 and slave:test.t1 + +# Verify if it can be binlogged with right database name when the table +# is not in the default database + +DROP DATABASE IF EXISTS db1; +CREATE DATABASE db1; +USE db1; +CREATE TABLE IF NOT EXISTS test.t1 +SELECT 'abc', 20; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `db1`; CREATE TABLE IF NOT EXISTS `test`.`t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `db1`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 20 +master-bin.000001 # Query # # COMMIT +Comparing tables master:test.t1 and slave:test.t1 +USE test; +DROP DATABASE db1; + +# It should be binlogged as 'REPLACE ... SELECT' +# if the original statement has option REPLACE + +CREATE TABLE IF NOT EXISTS t1 +REPLACE SELECT '123', 2; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2 +master-bin.000001 # Query # # COMMIT +Comparing tables master:test.t1 and slave:test.t1 + +# It should be binlogged as 'INSERT IGNORE... SELECT' +# if the original statement has option IGNORE + +CREATE TABLE IF NOT EXISTS t1 +IGNORE SELECT '123', 2; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2 +master-bin.000001 # Query # # COMMIT +Comparing tables master:test.t1 and slave:test.t1 + +# Nothing should be binlogged if error happens and no any row is inserted + +CREATE TABLE IF NOT EXISTS t1 +SELECT '123', 2; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +Comparing tables master:test.t1 and slave:test.t1 + +# Verify it can binlog well when there are some braces('(') + +CREATE TABLE IF NOT EXISTS t1 +(SELECT '123', 3) UNION (SELECT '123', 4); +Warnings: +Note 1050 Table 't1' already exists +CREATE TABLE IF NOT EXISTS t1 +REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4); +Warnings: +Note 1050 Table 't1' already exists +CREATE TABLE IF NOT EXISTS t1 +IGNORE (SELECT '123', 3) UNION (SELECT '123', 4); +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) (SELECT 'abc', 3) UNION (SELECT 'abc', 4) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4) +master-bin.000001 # Query # # COMMIT +Comparing tables master:test.t1 and slave:test.t1 + +# Throw a warning that table already exists and don't insert anything + +CREATE VIEW t3 AS SELECT * FROM t2; +CREATE TABLE IF NOT EXISTS t3 +SELECT '123', 2; +Warnings: +Note 1050 Table 't3' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +DROP VIEW t3; + +# The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER + +DROP PROCEDURE IF EXISTS p1; +CREATE PROCEDURE p1(IN a INT) +CREATE TABLE IF NOT EXISTS t1 SELECT '123', a; +call p1(500); +Warnings: +Note 1050 Table 't1' already exists +call p1(600); +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',500) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',600) +master-bin.000001 # Query # # COMMIT +Comparing tables master:test.t1 and slave:test.t1 +DROP PROCEDURE p1; + +# The statement can be binlogged correctly when it is in a prepared statement + +PREPARE stm FROM "CREATE TABLE IF NOT EXISTS t1 SELECT '123', ?"; +SET @a= 700; +EXECUTE stm USING @a; +Warnings: +Note 1050 Table 't1' already exists +SET @a= 800; +EXECUTE stm USING @a; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 700 +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 800 +master-bin.000001 # Query # # COMMIT +Comparing tables master:test.t1 and slave:test.t1 + +# The statement can be binlogged correctly when it is in a conditional comment + +# The whole statement in a conditional comment +/*!CREATE TABLE IF NOT EXISTS t1 +SELECT 'abc', 900*/; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 900*/ +master-bin.000001 # Query # # COMMIT + +# There is an long comment before SELECT +/*!CREATE /*blabla*/ TABLE IF NOT EXISTS t1 +SELECT 'abc', 901*/; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 901*/ +master-bin.000001 # Query # # COMMIT + +# Conditional comment starts just from SELECT +CREATE TABLE IF NOT EXISTS t1 +/*!SELECT 'abc',*/ 902; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc',*/ 902 +master-bin.000001 # Query # # COMMIT + +# Only SELECT keyword is in the conditional comment +CREATE TABLE IF NOT EXISTS t1 +/*!SELECT*/ /*!'abc',*/ 904; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT*/ /*!'abc',*/ 904 +master-bin.000001 # Query # # COMMIT + +# Conditional comment is after SELECT keyword +CREATE TABLE IF NOT EXISTS t1 +SELECT /*!'abc',*/ 903; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT /*!'abc',*/ 903 +master-bin.000001 # Query # # COMMIT + +# Conditional comment ends just before SELECT keyword +/*!CREATE TABLE IF NOT EXISTS t1 +*/SELECT 'abc', 905; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 905 +master-bin.000001 # Query # # COMMIT +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t2; +DROP TABLE t1; + + +CREATE TABLE t2(c1 INT, c2 char(10)); +INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc'); + +# The original query should be binlogged if the table does not exist. +# ------------------------------------------------------------------ + +CREATE TEMPORARY TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY) +SELECT 'abc' AS c3, 1 AS c4; +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY) +SELECT 'abc' AS c3, 1 AS c4 + +# The statement should be binlogged as two events. one is +# 'CREATE TEMPORARY TABLE IF NOT EXISTS ..', another one is +# 'INSERT ... SELECT'. +# ------------------------------------------------------------------ + +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +SELECT 'abc', 2; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 2 +master-bin.000001 # Query # # COMMIT + +# Verify if it can be binlogged with right database name when the table +# is not in the default database + +DROP DATABASE IF EXISTS db1; +CREATE DATABASE db1; +USE db1; +CREATE TEMPORARY TABLE IF NOT EXISTS test.t1 +SELECT 'abc', 20; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `db1`; CREATE TEMPORARY TABLE IF NOT EXISTS `test`.`t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `db1`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 20 +master-bin.000001 # Query # # COMMIT +USE test; +DROP DATABASE db1; + +# It should be binlogged as 'REPLACE ... SELECT' +# if the original statement has option REPLACE + +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +REPLACE SELECT '123', 2; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2 +master-bin.000001 # Query # # COMMIT + +# It should be binlogged as 'INSERT IGNORE... SELECT' +# if the original statement has option IGNORE + +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +IGNORE SELECT '123', 2; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 2 +master-bin.000001 # Query # # COMMIT + +# Nothing should be binlogged if error happens and no any row is inserted + +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +SELECT '123', 2; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info + +# Verify it can binlog well when there are some braces('(') + +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +(SELECT '123', 3) UNION (SELECT '123', 4); +Warnings: +Note 1050 Table 't1' already exists +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4); +Warnings: +Note 1050 Table 't1' already exists +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +IGNORE (SELECT '123', 3) UNION (SELECT '123', 4); +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; REPLACE INTO `test`.`t1` (`c3`,`c4`) (SELECT 'abc', 3) UNION (SELECT 'abc', 4) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT IGNORE INTO `test`.`t1` (`c3`,`c4`) (SELECT '123', 3) UNION (SELECT '123', 4) +master-bin.000001 # Query # # COMMIT + +# The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER + +DROP PROCEDURE IF EXISTS p1; +CREATE PROCEDURE p1(IN a INT) +CREATE TEMPORARY TABLE IF NOT EXISTS t1 SELECT '123', a; +call p1(500); +Warnings: +Note 1050 Table 't1' already exists +call p1(600); +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',500) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', NAME_CONST('a',600) +master-bin.000001 # Query # # COMMIT +DROP PROCEDURE p1; + +# The statement can be binlogged correctly when it is in a prepared statement + +PREPARE stm FROM "CREATE TEMPORARY TABLE IF NOT EXISTS t1 SELECT '123', ?"; +SET @a= 700; +EXECUTE stm USING @a; +Warnings: +Note 1050 Table 't1' already exists +SET @a= 800; +EXECUTE stm USING @a; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 700 +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT '123', 800 +master-bin.000001 # Query # # COMMIT + +# The statement can be binlogged correctly when it is in a conditional comment + +# The whole statement in a conditional comment +/*!CREATE TEMPORARY TABLE IF NOT EXISTS t1 +SELECT 'abc', 900*/; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 900*/ +master-bin.000001 # Query # # COMMIT + +# There is an long comment before SELECT +/*!CREATE TEMPORARY /*blabla*/ TABLE IF NOT EXISTS t1 +SELECT 'abc', 901*/; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 901*/ +master-bin.000001 # Query # # COMMIT + +# Conditional comment starts just from SELECT +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +/*!SELECT 'abc',*/ 902; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc',*/ 902 +master-bin.000001 # Query # # COMMIT + +# Only SELECT keyword is in the conditional comment +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +/*!SELECT*/ /*!'abc',*/ 904; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; /*! INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT*/ /*!'abc',*/ 904 +master-bin.000001 # Query # # COMMIT + +# Conditional comment is after SELECT keyword +CREATE TEMPORARY TABLE IF NOT EXISTS t1 +SELECT /*!'abc',*/ 903; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT /*!'abc',*/ 903 +master-bin.000001 # Query # # COMMIT + +# Conditional comment ends just before SELECT keyword +/*!CREATE TEMPORARY TABLE IF NOT EXISTS t1 +*/SELECT 'abc', 905; +Warnings: +Note 1050 Table 't1' already exists +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE IF NOT EXISTS `t1` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + `c3` char(10) DEFAULT NULL, + `c4` int(11) NOT NULL, + PRIMARY KEY (`c4`) +) +master-bin.000001 # Query # # use `test`; INSERT INTO `test`.`t1` (`c3`,`c4`) SELECT 'abc', 905 +master-bin.000001 # Query # # COMMIT +DROP TABLE t2; +DROP TEMPORARY TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test index 114f71af873..cf26e58c3ec 100644 --- a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test +++ b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test @@ -119,5 +119,32 @@ SELECT * FROM t2; DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; +sync_slave_with_master; + +--echo +--echo # Bug#55616 Killing thread or query during CREATE IF NOT EXISTS makes +--echo # slave SQL thread abort +--echo + +--connection master1 +let $con_id = `SELECT CONNECTION_ID()`; + +CREATE TABLE t1 ( i INT ); +send CREATE TABLE IF NOT EXISTS t1 + AS SELECT SLEEP(3); + +connection master; +let $wait_timeout = 3; +let $show_statement = SHOW PROCESSLIST; +let $field = State; +let $condition = = 'User sleep'; +source include/wait_show_condition.inc; + +--replace_result $con_id master1 +eval KILL QUERY $con_id; +sync_slave_with_master; + +connection master; +DROP TABLE t1; source include/master-slave-end.inc; diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_fatal.test b/mysql-test/suite/rpl/t/rpl_loaddata_fatal.test index e80fc160d8f..b8975308a86 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddata_fatal.test +++ b/mysql-test/suite/rpl/t/rpl_loaddata_fatal.test @@ -1,4 +1,4 @@ -source include/have_binlog_format_mixed_or_statement.inc; +source include/have_binlog_format_statement.inc; source include/have_debug.inc; source include/master-slave.inc; diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_map.test b/mysql-test/suite/rpl/t/rpl_loaddata_map.test index ddee9e7e989..1db7c4a893b 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddata_map.test +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map.test @@ -16,7 +16,7 @@ # BUG#33413 show binlog events fails if binlog has event size of close # to max_allowed_packet -source include/have_binlog_format_mixed_or_statement.inc; +source include/have_binlog_format_statement.inc; source include/master-slave.inc; diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test b/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test index 63e65834e5b..69b481bddd1 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test +++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test @@ -3,8 +3,8 @@ # This test verifies if loading data infile will work fine # if the path of the load data file is a symbolic link. # ---source include/master-slave.inc --source include/not_windows.inc +--source include/master-slave.inc --source include/have_binlog_format_statement.inc create table t1(a int not null auto_increment, b int, primary key(a) ); diff --git a/mysql-test/suite/rpl/t/rpl_row_create_table.test b/mysql-test/suite/rpl/t/rpl_row_create_table.test index a72ca75e975..148032f2987 100644 --- a/mysql-test/suite/rpl/t/rpl_row_create_table.test +++ b/mysql-test/suite/rpl/t/rpl_row_create_table.test @@ -299,5 +299,18 @@ DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3; DROP TEMPORARY TABLES t7; DROP TABLES t4, t5; DROP TABLES IF EXISTS bug48506_t4; +sync_slave_with_master; + +# +# Bug#55598 RBR: CREATE TABLE IF NOT EXISTS and INSERT written to binary log +# twice +# +connection master; +CREATE TABLE t1 SELECT 1; +CREATE TABLE IF NOT EXISTS t1 SELECT 1; +let $diff_table=test.t1; +source include/rpl_diff_tables.inc; +DROP TABLE t1; + source include/master-slave-end.inc; --echo end of the tests diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test index be5ebb661ca..d854aa64dc5 100644 --- a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test +++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test @@ -205,7 +205,7 @@ DROP TABLE `t1`; -- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. --- let $MYSQLD_DATADIR= `SELECT @@datadir`; +-- let $MYSQLD_DATADIR= `SELECT @@datadir` -- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog -- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog @@ -330,7 +330,7 @@ while($ntables) -- echo ### assertion: check that binlog is not corrupt. Using mysqlbinlog to -- echo ### detect failure. Before the patch mysqlbinlog would find -- echo ### a corrupted event, thence would fail. --- let $MYSQLD_DATADIR= `SELECT @@datadir`; +-- let $MYSQLD_DATADIR= `SELECT @@datadir` -- exec $MYSQL_BINLOG -v --hex $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog ## clean up diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test index 22309c33724..b7342fd1c40 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test +++ b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test @@ -8,7 +8,7 @@ # 2 - Catches error. ########################################################################## ---source include/have_binlog_format_mixed_or_statement.inc +--source include/have_binlog_format_statement.inc --source include/have_innodb.inc --source include/have_debug.inc --source include/master-slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_stm_create_if_not_exists.test b/mysql-test/suite/rpl/t/rpl_stm_create_if_not_exists.test new file mode 100644 index 00000000000..69866cad267 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_stm_create_if_not_exists.test @@ -0,0 +1,14 @@ +# +--echo # WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT +--echo # EXISTS ... SELECT' behaviour +--echo # + +source include/master-slave.inc; +source include/have_binlog_format_statement.inc; + +source extra/rpl_tests/rpl_stm_create_if_not_exists.test; + +let $is_temporary=1; +source extra/rpl_tests/rpl_stm_create_if_not_exists.test; + +source include/master-slave-end.inc; diff --git a/mysql-test/suite/rpl/t/rpl_stm_log.test b/mysql-test/suite/rpl/t/rpl_stm_log.test index 2af9d7f85bc..7bc17fbaada 100644 --- a/mysql-test/suite/rpl/t/rpl_stm_log.test +++ b/mysql-test/suite/rpl/t/rpl_stm_log.test @@ -1,5 +1,5 @@ # Requires statement logging --- source include/have_binlog_format_mixed_or_statement.inc +-- source include/have_binlog_format_statement.inc -- source include/master-slave.inc let $engine_type=MyISAM; -- source extra/rpl_tests/rpl_log.test diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv.test b/mysql-test/suite/sys_vars/t/secure_file_priv.test index 7a534e7d6e4..3e2a4fa467a 100644 --- a/mysql-test/suite/sys_vars/t/secure_file_priv.test +++ b/mysql-test/suite/sys_vars/t/secure_file_priv.test @@ -9,7 +9,7 @@ SHOW VARIABLES LIKE 'secure_file_priv'; # Doing this in a portable manner is difficult but we should be able to # count on the depth of the directory hierarchy used. Three steps up from # the datadir is the 'mysql_test' directory. ---let $PROTECTED_FILE=`SELECT concat(@@datadir,'/../../../bug50373.txt')`; +--let $PROTECTED_FILE=`SELECT concat(@@datadir,'/../../../bug50373.txt')` --eval SELECT * FROM t1 INTO OUTFILE '$PROTECTED_FILE'; DELETE FROM t1; --eval LOAD DATA INFILE '$PROTECTED_FILE' INTO TABLE t1; diff --git a/mysql-test/t/alter_table_trans.test b/mysql-test/t/alter_table_trans.test new file mode 100644 index 00000000000..9096a392af4 --- /dev/null +++ b/mysql-test/t/alter_table_trans.test @@ -0,0 +1,15 @@ +# +# Test of alter table with transactional tables +# + +--source include/have_innodb.inc +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +# +# This test caused a crash in wait_if_global_read_lock() +# +CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb; +ALTER TABLE t1 RENAME TO t2, DISABLE KEYS; +DROP TABLE t2; diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index b31fa83588b..4e337d54660 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1553,26 +1553,25 @@ drop table t1; # whole alter table code is being tested all around the test suite already. # -create table t1 (v varchar(32) not null); +create table t1 (v varchar(32) not null) engine=csv; insert into t1 values ('def'),('abc'),('hij'),('3r4f'); select * from t1; # Fast alter, no copy performed -alter table t1 change v v2 varchar(32); +alter table t1 change v v2 varchar(32) not null; select * from t1; # Fast alter, no copy performed -alter table t1 change v2 v varchar(64); +alter table t1 change v2 v varchar(64) not null; select * from t1; update t1 set v = 'lmn' where v = 'hij'; select * from t1; # Regular alter table -alter table t1 add i int auto_increment not null primary key first; +alter table t1 add i int not null first; select * from t1; -update t1 set i=5 where i=3; +update t1 set i=3 where v = 'abc'; select * from t1; -alter table t1 change i i bigint; +alter table t1 change i i bigint not null; select * from t1; -alter table t1 add unique key (i, v); -select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn'); +select * from t1 where i between 2 and 4 and v in ('def','3r4f','abc'); drop table t1; # diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index 5a0e86568f3..ea5c87babbb 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -387,4 +387,17 @@ DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1; DROP TABLE t1; +--echo # +--echo # Bug #53034: Multiple-table DELETE statements not accepting +--echo # "Access compatibility" syntax +--echo # + +CREATE TABLE t1 (id INT); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; + +DELETE FROM t1.*, test.t2.*, a.* USING t1, t2, t3 AS a; + +DROP TABLE t1, t2, t3; + --echo End of 5.1 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 6dbc8a05789..72a78f612a2 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1082,6 +1082,20 @@ select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt, from t1 a, t1 b; select *, f1 = f2 from t1; drop table t1; + +--echo # +--echo # Bug #54465: assert: field_types == 0 || field_types[field_pos] == +--echo # MYSQL_TYPE_LONGLONG +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2); + +SELECT MAX((SELECT 1 FROM t1 ORDER BY @var LIMIT 1)) m FROM t1 t2, t1 + ORDER BY t1.a; + +DROP TABLE t1; + --echo # --echo End of 5.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 2f9a48ffd6a..57eee43d75e 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -838,4 +838,15 @@ select date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND); select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND); +# +# Bug #55565: debug assertion when ordering by expressions with user +# variable assignments +# + +CREATE TABLE t1(a DOUBLE NOT NULL); +INSERT INTO t1 VALUES (0),(9.216e-096); +--echo # should not crash +SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a); +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index bc0695aaa93..fd0a18ab4dd 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -401,6 +401,7 @@ create table t1 (a int, b blob); insert into t1 values (1, ''), (2, NULL), (3, '1'); select * from t1; +--error ER_ILLEGAL_VALUE_FOR_TYPE select geometryfromtext(b) IS NULL, geometryfromwkb(b) IS NULL, astext(b) IS NULL, aswkb(b) IS NULL, geometrytype(b) IS NULL, centroid(b) IS NULL, @@ -419,6 +420,7 @@ select intersects(b, b) IS NULL, crosses(b, b) IS NULL from t1; +--error ER_ILLEGAL_VALUE_FOR_TYPE select point(b, b) IS NULL, linestring(b) IS NULL, polygon(b) IS NULL, multipoint(b) IS NULL, multilinestring(b) IS NULL, multipolygon(b) IS NULL, @@ -702,24 +704,44 @@ drop table t1; # Bug#44684: valgrind reports invalid reads in # Item_func_spatial_collection::val_str # +--error ER_ILLEGAL_VALUE_FOR_TYPE SELECT MultiPoint(12345,''); -SELECT MultiPoint(123451,''); -SELECT MultiPoint(1234512,''); -SELECT MultiPoint(12345123,''); - -SELECT MultiLineString(12345,''); -SELECT MultiLineString(123451,''); -SELECT MultiLineString(1234512,''); -SELECT MultiLineString(12345123,''); - -SELECT LineString(12345,''); -SELECT LineString(123451,''); -SELECT LineString(1234512,''); -SELECT LineString(12345123,''); - -SELECT Polygon(12345,''); -SELECT Polygon(123451,''); -SELECT Polygon(1234512,''); -SELECT Polygon(12345123,''); +#SELECT MultiPoint(123451,''); +#SELECT MultiPoint(1234512,''); +#SELECT MultiPoint(12345123,''); + +--error ER_ILLEGAL_VALUE_FOR_TYPE +#SELECT MultiLineString(12345,''); +#SELECT MultiLineString(123451,''); +#SELECT MultiLineString(1234512,''); +#SELECT MultiLineString(12345123,''); + +--error ER_ILLEGAL_VALUE_FOR_TYPE +#SELECT LineString(12345,''); +#SELECT LineString(123451,''); +#SELECT LineString(1234512,''); +#SELECT LineString(12345123,''); + +--error ER_ILLEGAL_VALUE_FOR_TYPE +#SELECT Polygon(12345,''); +#SELECT Polygon(123451,''); +#SELECT Polygon(1234512,''); +#SELECT Polygon(12345123,''); + +# +# Bug55531 crash with conversions of geometry types / strings +# +--error ER_ILLEGAL_VALUE_FOR_TYPE +SELECT 1 FROM (SELECT GREATEST(1,GEOMETRYCOLLECTION('00000','00000')) b FROM DUAL) AS d WHERE (LINESTRING(d.b)); + + +--echo # +--echo # BUG#51875: crash when loading data into geometry function polyfromwkb +--echo # +SET @a=0x00000000030000000100000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440; +SET @a=POLYFROMWKB(@a); +SET @a=0x00000000030000000000000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440; +SET @a=POLYFROMWKB(@a); + --echo End of 5.1 tests diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test index 7d4a27d9204..e68f414e0bc 100644 --- a/mysql-test/t/index_merge_innodb.test +++ b/mysql-test/t/index_merge_innodb.test @@ -29,3 +29,56 @@ let $merge_table_support= 0; --source include/index_merge2.inc --source include/index_merge_2sweeps.inc --source include/index_merge_ror_cpk.inc + +--echo # +--echo # BUG#56862/640419: Wrong result with sort_union index merge when one +--echo # of the merged index scans is the primary key scan +--echo # + +CREATE TABLE t1 ( + pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, + a int, + b int, + INDEX idx(a)) +ENGINE=INNODB; + +INSERT INTO t1(a,b) VALUES + (11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500), + (3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800), + (6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700), + (13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000); +INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1; +INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1; +INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1 VALUES (1000000, 0, 0); + +SET SESSION sort_buffer_size = 1024*36; + +EXPLAIN +SELECT COUNT(*) FROM + (SELECT * FROM t1 + WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; +SELECT COUNT(*) FROM + (SELECT * FROM t1 + WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; + +--replace_column 9 # +EXPLAIN +SELECT COUNT(*) FROM + (SELECT * FROM t1 IGNORE INDEX(idx) + WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; +SELECT COUNT(*) FROM + (SELECT * FROM t1 IGNORE INDEX(idx) + WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; + +DROP TABLE t1; diff --git a/mysql-test/t/information_schema_all_engines-master.opt b/mysql-test/t/information_schema_all_engines-master.opt new file mode 100644 index 00000000000..9104e73e554 --- /dev/null +++ b/mysql-test/t/information_schema_all_engines-master.opt @@ -0,0 +1 @@ +--loose-skip-safemalloc --loose-mutex-deadlock-detector=0 diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index 5ec0aefe021..045b5807391 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -504,3 +504,28 @@ DROP TABLE t1, t2; --echo End of 5.0 tests. + +--echo # +--echo # Bug#54106 assert in Protocol::end_statement, +--echo # INSERT IGNORE ... SELECT ... UNION SELECT ... +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT); + +--error ER_FIELD_SPECIFIED_TWICE +INSERT INTO t1 (a, a) VALUES (1, 1); +# Verify that ER_FIELD_SPECIFIED_TWICE is not ignorable +--error ER_FIELD_SPECIFIED_TWICE +INSERT IGNORE t1 (a, a) VALUES (1, 1); + +--error ER_FIELD_SPECIFIED_TWICE +INSERT IGNORE t1 (a, a) SELECT 1,1; +# Used to cause an assert +--error ER_FIELD_SPECIFIED_TWICE +INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2; + +DROP TABLE t1; diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 43b373c9703..05d630edfb2 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -851,4 +851,74 @@ ENGINE=MERGE UNION=(t1,t2); SELECT t1.a FROM mm1,t1; DROP TABLE t1, t2, mm1; +#--echo # +#--echo # Bug #55568: user variable assignments crash server when used within +#--echo # query +#--echo # +# +# +# This test case is invalidated because of fix of bug 55531 +# The reason is that {1} is not a valid geometric collection. +# +#CREATE TABLE t1 (a INT); + +#INSERT INTO t1 VALUES (0), (1); + +#let $i=2; +#while ($i) +#{ +# SELECT MULTIPOINT( +# 1, +# ( +# SELECT MULTIPOINT( +# MULTIPOINT( +# 1, +# (SELECT COUNT(*) FROM (SELECT 1 FROM t1 GROUP BY a,a) d) +# ) +# ) FROM t1 +# ) +# ) != COUNT(*) q FROM t1 GROUP BY a; +# dec $i; +#} +# +#DROP TABLE t1; + +--echo # +--echo # Bug #54468: crash after item's print() function when ordering/grouping +--echo # by subquery +--echo # + +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (), (); + +SELECT 1 FROM t1 +GROUP BY +GREATEST(t1.a, + (SELECT 1 FROM + (SELECT t1.b FROM t1,t1 t2 + ORDER BY t1.a, t1.a LIMIT 1) AS d) + ); + +DROP TABLE t1; + +--echo # +--echo # Bug #53544: Server hangs during JOIN query in stored procedure called +--echo # twice in a row +--echo # + +CREATE TABLE t1(c INT); + +INSERT INTO t1 VALUES (1), (2); + +PREPARE stmt FROM "SELECT t2.c AS f1 FROM t1 LEFT JOIN + t1 t2 ON t1.c=t2.c RIGHT JOIN + t1 t3 ON t1.c=t3.c + GROUP BY f1;"; + +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index 5b07d8966f1..6ae7fb6dfee 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -1196,5 +1196,45 @@ SELECT COUNT(*) DROP TABLE t1,t2,t3,t4,t5; +# +# BUG#49322: Nested left joins + not-exist optimization +# + +CREATE TABLE t1 ( + pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, + a int DEFAULT NULL, + KEY idx(a) +); +CREATE TABLE t2 ( + pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, + a int DEFAULT NULL, + KEY idx(a) +); +CREATE TABLE t3 ( + pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, + a int DEFAULT NULL, + KEY idx(a) +); + +INSERT INTO t1 VALUES + (1,2), (2,7), (3,5), (4,7), (5,5), (6,NULL), (7,NULL), (8,9); +INSERT INTO t2 VALUES + (1,NULL), (4,2), (5,2), (3,4), (2,8); +INSERT INTO t3 VALUES + (1,9), (2,2), (3,5), (4,2), (5,7), (6,0), (7,5); + +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a + FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a; + +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a + FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a + WHERE t2.pk IS NULL; + +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a + FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a + WHERE t3.pk IS NULL; + +DROP TABLE t1, t2, t3; + --echo End of 5.0 tests diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index cf881e6aaa2..6d1ef15337f 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -981,4 +981,96 @@ EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1 DROP TABLE t1; +--echo # +--echo # Bug#49600: outer join of two single-row tables with joining attributes +--echo # evaluated to nulls + +create table t1 (a int, b int); +create table t2 (a int, b int); +insert into t1 values (1, NULL); +insert into t2 values (2, NULL); + +select * from t1 left join t2 on t1.b=t2.b; + +select * from t1 left join t2 on t1.b=t2.b where 1=1; + +drop table t1,t2; + +--echo # +--echo # Bug#53161: outer join in the derived table is erroneously converted +--echo # into an inner join for a query with a group by clause +--echo # + +create table t1 (pk int not null primary key, a int not null); +create table t2 like t1; +create table t3 like t1; +create table t4 (pk int not null primary key); +insert into t1 values (1000, 1), (1001, 1); +insert into t2 values (2000, 2), (2001, 2); +insert into t3 values (3000, 3), (3001, 2); +insert into t4 values (4000), (4001); + +explain extended +select t2.pk, + (select t3.pk+if(isnull(t4.pk),0,t4.pk) + from t3 left join t4 on t4.pk=t3.pk + where t3.pk=t2.pk+1000 limit 1 ) as t + from t1,t2 + where t2.pk=t1.pk+1000 and t1.pk>1000 + group by t2.pk; + +select t2.pk, + (select t3.pk+if(isnull(t4.pk),0,t4.pk) + from t3 left join t4 on t4.pk=t3.pk + where t3.pk=t2.pk+1000 limit 1 ) as t + from t1,t2 + where t2.pk=t1.pk+1000 and t1.pk>1000 + group by t2.pk; + +drop table t1,t2,t3,t4; + +--echo # +--echo # Bug#57024: Poor performance when conjunctive condition over the outer +--echo # table is used in the on condition of an outer join +--echo # + +create table t1 (a int); +insert into t1 values (NULL), (NULL), (NULL), (NULL); +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 values (4), (2), (1), (3); + +create table t2 like t1; +insert into t2 select if(t1.a is null, 10, t1.a) from t1; + +create table t3 (a int, b int, index idx(a)); +insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101); + +analyze table t1,t2,t3; + +flush status; +select sum(t3.b) from t1 left join t3 on t3.a=t1.a and t1.a is not null; +show status like "handler_read%"; +flush status; +select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10; +show status like "handler_read%"; + +drop table t1,t2,t3; + --echo End of 5.1 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index df99d6150ab..0b34f9fdbac 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -1119,35 +1119,38 @@ UNLOCK TABLES; --echo # --echo # Trigger on parent DELETE FROM t4 WHERE c1 = 4; -CREATE TRIGGER t4_ai AFTER INSERT ON t4 FOR EACH ROW SET @a=1; +CREATE TRIGGER t4_ai1 AFTER INSERT ON t4 FOR EACH ROW SET @a=1; SET @a=0; INSERT INTO t4 VALUES (4); SELECT @a; SELECT * FROM t4 ORDER BY c1; -DROP TRIGGER t4_ai; +DROP TRIGGER t4_ai1; +CHECK TABLE t3; --echo # Trigger on parent under LOCK TABLES LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; -CREATE TRIGGER t4_ai AFTER INSERT ON t4 FOR EACH ROW SET @a=1; +CREATE TRIGGER t4_ai2 AFTER INSERT ON t4 FOR EACH ROW SET @a=1; SET @a=0; INSERT INTO t4 VALUES (4); SELECT @a; SELECT * FROM t4 ORDER BY c1; -DROP TRIGGER t4_ai; +DROP TRIGGER t4_ai2; UNLOCK TABLES; +CHECK TABLE t3; --echo # --echo # Trigger on child DELETE FROM t4 WHERE c1 = 4; -CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW SET @a=1; +CREATE TRIGGER t3_ai3 AFTER INSERT ON t3 FOR EACH ROW SET @a=1; SET @a=0; INSERT INTO t4 VALUES (4); SELECT @a; INSERT INTO t3 VALUES (33); SELECT @a; SELECT * FROM t4 ORDER BY c1; -DROP TRIGGER t3_ai; +DROP TRIGGER t3_ai3; +CHECK TABLE t3; --echo # Trigger on child under LOCK TABLES LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; -CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW SET @a=1; +CREATE TRIGGER t3_ai4 AFTER INSERT ON t3 FOR EACH ROW SET @a=1; SET @a=0; INSERT INTO t4 VALUES (4); SELECT @a; @@ -1155,29 +1158,47 @@ INSERT INTO t3 VALUES (33); SELECT @a; SELECT * FROM t4 ORDER BY c1; DELETE FROM t4 WHERE c1 = 33; -DROP TRIGGER t3_ai; +DROP TRIGGER t3_ai4; +CHECK TABLE t3; --echo # --echo # Trigger with table use on child DELETE FROM t4 WHERE c1 = 4; -CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); +CREATE TRIGGER t3_ai5 AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); +SELECT COUNT(*) FROM t2; INSERT INTO t4 VALUES (4); SELECT * FROM t4 ORDER BY c1; INSERT INTO t3 VALUES (33); SELECT * FROM t4 ORDER BY c1; DELETE FROM t4 WHERE c1 = 22; DELETE FROM t4 WHERE c1 = 33; -DROP TRIGGER t3_ai; +DROP TRIGGER t3_ai5; +UNLOCK TABLES; +CHECK TABLE t2,t3; --echo # Trigger with table use on child under LOCK TABLES LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, t1 WRITE; -CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); +CREATE TRIGGER t3_ai6 AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); INSERT INTO t4 VALUES (4); SELECT * FROM t4 ORDER BY c1; INSERT INTO t3 VALUES (33); SELECT * FROM t4 ORDER BY c1; -DROP TRIGGER t3_ai; +DROP TRIGGER t3_ai6; +UNLOCK TABLES; +check table t2,t3,t4; DELETE FROM t4 WHERE c1 = 22; DELETE FROM t4 WHERE c1 = 33; +--echo # Trigger with table use on child under different LOCK TABLES +DELETE FROM t4 WHERE c1 = 4; +LOCK TABLES t4 WRITE,t3 WRITE, t2 WRITE, t1 WRITE; +CREATE TRIGGER t3_ai7 AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2 VALUES(22); +INSERT INTO t4 VALUES (4); +SELECT * FROM t4 ORDER BY c1; +INSERT INTO t3 VALUES (33); +SELECT * FROM t4 ORDER BY c1; +DROP TRIGGER t3_ai7; UNLOCK TABLES; +check table t2,t3,t4; +DELETE FROM t4 WHERE c1 = 22; +DELETE FROM t4 WHERE c1 = 33; # --echo # --echo # Repair @@ -1715,6 +1736,84 @@ t2 WHERE b SOUNDS LIKE e AND d = 1; DROP TABLE t2, t1; +--echo # +--echo # Bug#46339 - crash on REPAIR TABLE merge table USE_FRM +--echo # +--disable_warnings +DROP TABLE IF EXISTS m1, t1; +--enable_warnings +# +# Test derived from a proposal of Shane Bester. +# +CREATE TABLE t1 (c1 INT) ENGINE=MYISAM; +CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1) INSERT_METHOD=LAST; +# +# REPAIR ... USE_FRM with LOCK TABLES. +# +LOCK TABLE m1 READ; +REPAIR TABLE m1 USE_FRM; +UNLOCK TABLES; +# +# REPAIR ... USE_FRM without LOCK TABLES. +# +# This statement crashed the server (Bug#46339). +# +REPAIR TABLE m1 USE_FRM; +# +DROP TABLE m1,t1; +# +# Test derived from a proposal of Matthias Leich. +# +# Base table is missing. +# +CREATE TABLE m1 (f1 BIGINT) ENGINE=MRG_MyISAM UNION(t1); +# +# This statement crashed the server (Bug#46339). +# +REPAIR TABLE m1 USE_FRM; +# +# Create base table. +# +CREATE TABLE t1 (f1 BIGINT) ENGINE = MyISAM; +# +# This statement crashed the server (Bug#46339). +# +REPAIR TABLE m1 USE_FRM; +# +# Normal repair as reference. +# +REPAIR TABLE m1; +# +# Cleanup. +# +DROP TABLE m1, t1; +# +# Same with temporary tables. +# +# Base table is missing. +# +CREATE TEMPORARY TABLE m1 (f1 BIGINT) ENGINE=MRG_MyISAM UNION(t1); +# +# This statement crashed the server (Bug#46339). +# +REPAIR TABLE m1 USE_FRM; +# +# Create base table. +# +CREATE TEMPORARY TABLE t1 (f1 BIGINT) ENGINE=MyISAM; +# +# This statement crashed the server (Bug#46339). +# +REPAIR TABLE m1 USE_FRM; +# +# Normal repair as reference. +# +REPAIR TABLE m1; +# +# Cleanup. +# +DROP TABLE m1, t1; + --echo End of 5.1 tests --disable_result_log diff --git a/mysql-test/t/merge_debug.test b/mysql-test/t/merge_debug.test new file mode 100644 index 00000000000..2e30cf88b5d --- /dev/null +++ b/mysql-test/t/merge_debug.test @@ -0,0 +1,42 @@ +# +# Test failures with MERGE +# + +--source include/have_debug.inc + +let $default=`select @@global.storage_engine`; +set global storage_engine=myisam; +set session storage_engine=myisam; + +--disable_warnings +drop table if exists crashed,t2,t3,t4; +--enable_warnings + +SET @orig_debug=@@debug; + +# +# Check that MariaDB handles reopen that fails without crashing +# +CREATE TABLE crashed (c1 INT); +CREATE TABLE t2 (c1 INT); +CREATE TABLE t3 (c1 INT); +CREATE TABLE t4 (c1 INT) ENGINE=MRG_MYISAM UNION=(crashed,t2,t3) INSERT_METHOD=LAST; +INSERT INTO crashed VALUES (10); +INSERT INTO t2 VALUES (20); +INSERT INTO t3 VALUES (30); + +LOCK TABLES t3 WRITE, t2 WRITE, t4 WRITE, crashed WRITE; +SET GLOBAL debug="+d,*,myisam_pretend_crashed_table_on_open"; +--disable_warnings +CREATE TRIGGER t1_ai AFTER INSERT ON crashed FOR EACH ROW INSERT INTO t2 VALUES(29); +--enable_warnings +SET GLOBAL debug=@orig_debug; +--error ER_TABLE_NOT_LOCKED +INSERT INTO t4 VALUES (39); +--error ER_TABLE_NOT_LOCKED +INSERT INTO crashed VALUES (11); +INSERT INTO t2 VALUES (21); +INSERT INTO t3 VALUES (31); +UNLOCK TABLES; +DROP TRIGGER t1_ai; +DROP TABLE t4,crashed,t2,t3; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 87e952dd069..d405e4e5e3a 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -655,5 +655,26 @@ SET SESSION sql_safe_updates = 1; UPDATE IGNORE t1, t1 t1a SET t1.a = 1 WHERE t1a.a = 1; DROP TABLE t1; +--echo # +--echo # Bug#54543: update ignore with incorrect subquery leads to assertion +--echo # failure: inited==INDEX +--echo # +SET SESSION sql_safe_updates = 0; +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1), (2); + +CREATE TABLE t2 ( a INT ); +INSERT INTO t2 VALUES (1), (2); + +CREATE TABLE t3 ( a INT ); +INSERT INTO t3 VALUES (1), (2); + +--echo # Should not crash +UPDATE IGNORE + ( SELECT ( SELECT COUNT(*) FROM t1 GROUP BY a, @v ) a FROM t2 ) x, t3 +SET t3.a = 0; + +DROP TABLE t1, t2, t3; +SET SESSION sql_safe_updates = DEFAULT; --echo end of tests diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 7c9fbf031bb..783708cc3b2 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -1,6 +1,6 @@ # We are using .opt file since we need small binlog size # TODO: Need to look at making a row based version once the new row based client is completed. [jbm] --- source include/have_binlog_format_mixed_or_statement.inc +-- source include/have_binlog_format_statement.inc -- source include/have_log_bin.inc diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index f1a00368e12..eaf9d168da0 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1,3 +1,5 @@ +call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); + # Embedded server doesn't support external clients --source include/not_embedded.inc diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index b103140190f..ca19de75d4b 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -106,7 +106,7 @@ select otto from (select 1 as otto) as t1; # expecting a SQL-state for a command that can't give one should fail --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --error 1 ---exec echo "error S00000; remove_file $MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp;" | $MYSQL_TEST 2>&1 +--exec echo "disable_warnings ; error S00000; remove_file $MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp;" | $MYSQL_TEST 2>&1 # ---------------------------------------------------------------------------- @@ -334,6 +334,15 @@ eval select $mysql_errno as "after_!errno_masked_error" ; --exec echo "disable_abort_on_error; error 1000; select 3 from t1; error 1000; select 3 from t1;" | $MYSQL_TEST 2>&1 # ---------------------------------------------------------------------------- +# Check some non-query statements that would fail +# ---------------------------------------------------------------------------- +--exec illegal_command +--cat_file does_not_exist +--perl + exit(1); +EOF + +# ---------------------------------------------------------------------------- # Switch the abort on error on and check the effect on $mysql_errno # ---------------------------------------------------------------------------- --error ER_PARSE_ERROR @@ -493,6 +502,32 @@ remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; --error 1 --exec echo "--disable_query_log;" | $MYSQL_TEST 2>&1 +# +# Extra text after `` +# +# Cannot use exec echo here as ` may or may not need to be escaped +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +let $x= `select 1` BOO ; +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--let $x= `select 1`; +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +# Missing ; in next line should be detected and cause failure +let $x= `select 1` +let $x= 2; +echo $x; +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; + # Allow trailing # comment --sleep 1 # Wait for insert delayed to be executed. @@ -700,6 +735,16 @@ echo banana = $cat; let $cat=ba\\\$cat\\\$cat; echo Not a banana: $cat; +# Bug #55413 would cause this to fail +let $escape= with\`some\"escaped\'quotes; +echo $escape; + +--let $escape= with\`some\"escaped\'quotes +echo $escape; + +# This only works with "--let" syntax +--let $tick= single'tick`backtick +echo $tick; # Test illegal uses of let @@ -871,7 +916,7 @@ while ($outer) } # Test source in an if in a while which is false on 1st iteration -# Also test --error in same context +# Also test --error and --disable_abort_on_error in same context let $outer= 2; # Number of outer loops let $ifval= 0; # false 1st time while ($outer) @@ -882,6 +927,10 @@ while ($outer) --source $MYSQLTEST_VARDIR/tmp/sourced.inc --error ER_NO_SUCH_TABLE SELECT * from nowhere; + --disable_abort_on_error +# Statement giving a different error, to make sure we don't mask it + SELECT * FROM nowhere else; + --enable_abort_on_error } dec $outer; inc $ifval; @@ -1101,6 +1150,36 @@ if (!$counter) } # ---------------------------------------------------------------------------- +# Test if with some non-numerics +# ---------------------------------------------------------------------------- + +let $counter=alpha; +if ($counter) +{ + echo Counter is true, (counter=alpha); +} +let $counter= ; +if ($counter) +{ + echo oops, space is true; +} +let $counter=-0; +if ($counter) +{ + echo oops, -0 is true; +} +if (beta) +{ + echo Beta is true; +} +let $counter=gamma; +while ($counter) +{ + echo while with string, only once; + let $counter=000; +} + +# ---------------------------------------------------------------------------- # Test while, { and } # ---------------------------------------------------------------------------- @@ -1396,19 +1475,6 @@ eval select "$long_rep" as x; # Repeat connect/disconnect --write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql -let $i=100; -while ($i) -{ - connect (test_con1,localhost,root,,); - disconnect test_con1; - dec $i; -} -EOF ---exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK; exit;" | $MYSQL_TEST 2>&1 -remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; - -# Repeat connect/disconnect ---write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql let $i=200; while ($i) { @@ -1416,9 +1482,8 @@ while ($i) disconnect test_con1; dec $i; } +echo 200 connects succeeded; EOF ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---error 1 --exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql;" | $MYSQL_TEST 2>&1 remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; @@ -1445,7 +1510,6 @@ EOF remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; # connect when "disable_abort_on_error" caused "connection not found" ---replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --disable_abort_on_error connect (con1,localhost,root,,); connection default; @@ -1460,6 +1524,22 @@ show tables; disconnect con2; connection default; +# Test enable_connect_log +--enable_connect_log +connect (con1,localhost,root,,); +connection default; +connection con1; +--disable_query_log +# These should not be logged +connect (con2,localhost,root,,*NO-ONE*); +connection con2; +disconnect con2; +connection con1; +--enable_query_log +disconnect con1; +connection default; +--disable_connect_log + # ---------------------------------------------------------------------------- # Test mysqltest arguments # ---------------------------------------------------------------------------- @@ -1551,12 +1631,14 @@ select "this will be executed"; --exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql -R $MYSQLTEST_VARDIR/tmp/zero_length_file.result > /dev/null 2>&1 remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.result; +--disable_warnings --error 0,1 remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.reject; --error 0,1 remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.log; --error 0,1 remove_file $MYSQL_TEST_DIR/r/zero_length_file.reject; +--enable_warnings # # Test that a test file that does not generate any output fails. @@ -1732,7 +1814,16 @@ select 1; --reap EOF --error 1 ---exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.in 2>&1 +# Must filter unpredictable extra warning from output +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.in > $MYSQL_TMP_DIR/mysqltest.out 2>&1 +--perl + my $dir= $ENV{'MYSQL_TMP_DIR'}; + open (FILE, "$dir/mysqltest.out"); + while (<FILE>) { + print unless /Note: net_clear/; # This shows up on rare occations + } +EOF +remove_file $MYSQL_TMP_DIR/mysqltest.out; remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.in; drop table t1; @@ -1741,11 +1832,13 @@ drop table t1; # test for remove_file # ---------------------------------------------------------------------------- +--disable_warnings --error 1 --exec echo "remove_file ;" | $MYSQL_TEST 2>&1 --error 1 remove_file non_existing_file; +--enable_warnings # ---------------------------------------------------------------------------- # test for remove_files_wildcard @@ -1785,7 +1878,7 @@ Content for test_file1 contains EOF END_DELIMITER file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; -# write to already exisiting file +# write to already existing file --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --error 1 --exec echo "write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;" | $MYSQL_TEST 2>&1 @@ -1901,8 +1994,10 @@ EOF --error 1 --exec echo "file_exists ;" | $MYSQL_TEST 2>&1 +--disable_warnings --error 0,1 remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +--enable_warnings --error 1 file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; @@ -1939,6 +2034,7 @@ remove_file $MYSQLTEST_VARDIR/tmp/file2.tmp; # - Check that if source file does not exist, nothing will be created. +--disable_warnings --error 1 file_exists $MYSQLTEST_VARDIR/tmp/file1.tmp; --error 1 @@ -1949,6 +2045,7 @@ move_file $MYSQLTEST_VARDIR/tmp/file1.tmp $MYSQLTEST_VARDIR/tmp/file2.tmp; file_exists $MYSQLTEST_VARDIR/tmp/file1.tmp; --error 1 file_exists $MYSQLTEST_VARDIR/tmp/file2.tmp; +--enable_warnings # - Check that if source file exists, everything works properly. diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index 8ca70258bc0..8051dd0e866 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -73,6 +73,8 @@ drop table t1; # a different cacert # --exec echo "this query should not execute;" > $MYSQLTEST_VARDIR/tmp/test.sql +# Handle that openssl gives different error messages from YaSSL. +--replace_regex /error:00000005:lib\(0\):func\(0\):DH lib/ASN: bad other signature confirmation/ --error 1 --exec $MYSQL_TEST --ssl-ca=$MYSQL_TEST_DIR/std_data/untrusted-cacert.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 @@ -80,6 +82,7 @@ drop table t1; # Test that we can't open connection to server if we are using # a blank ca # +--replace_regex /error:00000005:lib\(0\):func\(0\):DH lib/ASN: bad other signature confirmation/ --error 1 --exec $MYSQL_TEST --ssl-ca= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 @@ -87,6 +90,7 @@ drop table t1; # Test that we can't open connection to server if we are using # a nonexistent ca file # +--replace_regex /error:00000005:lib\(0\):func\(0\):DH lib/ASN: bad other signature confirmation/ --error 1 --exec $MYSQL_TEST --ssl-ca=nonexisting_file.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index de380e09e8a..0bacd785808 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -1469,4 +1469,29 @@ SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a; DROP TABLE t1, t2; +--echo # +--echo # Bug #50394: Regression in EXPLAIN with index scan, LIMIT, GROUP BY and +--echo # ORDER BY computed col +--echo # +CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL, KEY( a, b ) ); + +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); +INSERT INTO t1 SELECT a + 5, b + 5 FROM t1; + +CREATE TABLE t2( a INT PRIMARY KEY, b INT ); + +INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); +INSERT INTO t2 SELECT a + 5, b + 5 FROM t2; + +EXPLAIN +SELECT count(*) AS c, t1.a +FROM t1 JOIN t2 ON t1.b = t2.a +WHERE t2.b = 1 +GROUP BY t1.a +ORDER by c +LIMIT 2; + +DROP TABLE t1, t2; + + --echo End of 5.1 tests diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index e6e000ec916..e0e3f2af396 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -14,6 +14,55 @@ drop table if exists t1, t2; --enable_warnings +--echo # +--echo # Bug#57113: ha_partition::extra(ha_extra_function): +--echo # Assertion `m_extra_cache' failed +CREATE TABLE t1 +(id INT NOT NULL PRIMARY KEY, + name VARCHAR(16) NOT NULL, + year YEAR, + INDEX name (name(8)) +) +PARTITION BY HASH(id) PARTITIONS 2; + +INSERT INTO t1 VALUES ( 1, 'FooBar', '1924' ); + +CREATE TABLE t2 (id INT); + +INSERT INTO t2 VALUES (1),(2); + +UPDATE t1, t2 SET t1.year = '1955' WHERE t1.name = 'FooBar'; + +DROP TABLE t1, t2; + + +--echo # +--echo # Bug#55458: Partitioned MyISAM table gets crashed by multi-table update +--echo # +CREATE TABLE t1 ( + `id` int NOT NULL, + `user_num` int DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM CHARSET=latin1; +INSERT INTO t1 VALUES (1,8601); +INSERT INTO t1 VALUES (2,8601); +INSERT INTO t1 VALUES (3,8601); +INSERT INTO t1 VALUES (4,8601); +CREATE TABLE t2 ( + `id` int(11) NOT NULL, + `user_num` int DEFAULT NULL, + `name` varchar(64) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM CHARSET=latin1 +PARTITION BY HASH (id) +PARTITIONS 2; +INSERT INTO t2 VALUES (1,8601,'John'); +INSERT INTO t2 VALUES (2,8601,'JS'); +INSERT INTO t2 VALUES (3,8601,'John S'); + +UPDATE t1, t2 SET t2.name = 'John Smith' WHERE t1.user_num = t2.user_num; + +DROP TABLE t1, t2; # # Bug#48276: can't add column if subpartition exists CREATE TABLE t1 (a INT, b INT) diff --git a/mysql-test/t/partition_binlog_stmt.test b/mysql-test/t/partition_binlog_stmt.test new file mode 100644 index 00000000000..c426de9f303 --- /dev/null +++ b/mysql-test/t/partition_binlog_stmt.test @@ -0,0 +1,26 @@ +--source include/have_partition.inc +--source include/have_binlog_format_statement.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo # +--echo # Bug#51851: Server with SBR locks mutex twice on LOAD DATA into +--echo # partitioned MyISAM table +--write_file init_file.txt +abcd +EOF + +CREATE TABLE t1 +(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name TINYBLOB NOT NULL, + modified TIMESTAMP DEFAULT '0000-00-00 00:00:00', + INDEX namelocs (name(255))) ENGINE = MyISAM +PARTITION BY HASH(id) PARTITIONS 2; + +LOAD DATA LOCAL INFILE 'init_file.txt' +INTO TABLE t1 (name); + +--remove_file init_file.txt +DROP TABLE t1; diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 434392c2e28..d3f10628254 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -1252,4 +1252,18 @@ PARTITION pmax VALUES LESS THAN MAXVALUE); DROP TABLE old; +--echo # +--echo # Bug #56709: Memory leaks at running the 5.1 test suite +--echo # + +CREATE TABLE t1 (a TIMESTAMP NOT NULL PRIMARY KEY); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE t1 +PARTITION BY RANGE (EXTRACT(DAY FROM a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/partition_not_blackhole-master.opt b/mysql-test/t/partition_not_blackhole-master.opt new file mode 100644 index 00000000000..1e47be930bc --- /dev/null +++ b/mysql-test/t/partition_not_blackhole-master.opt @@ -0,0 +1 @@ +--loose-skip-blackhole diff --git a/mysql-test/t/partition_not_blackhole.test b/mysql-test/t/partition_not_blackhole.test new file mode 100644 index 00000000000..7352aeaa230 --- /dev/null +++ b/mysql-test/t/partition_not_blackhole.test @@ -0,0 +1,26 @@ +--source include/have_partition.inc +--source include/not_blackhole.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +let $MYSQLD_DATADIR= `SELECT @@datadir`; + +--echo # +--echo # Bug#46086: crash when dropping a partitioned table and +--echo # the original engine is disabled +--echo # Copy a .frm and .par file which was created with: +--echo # create table `t1` (`id` int primary key) engine=blackhole +--echo # partition by key () partitions 1; +--copy_file std_data/parts/t1_blackhole.frm $MYSQLD_DATADIR/test/t1.frm +--copy_file std_data/parts/t1_blackhole.par $MYSQLD_DATADIR/test/t1.par +SHOW TABLES; +--replace_result $MYSQLD_DATADIR ./ +--error ER_NOT_FORM_FILE +SHOW CREATE TABLE t1; +--error ER_BAD_TABLE_ERROR +DROP TABLE t1; +--list_files $MYSQLD_DATADIR/test t1* +--remove_file $MYSQLD_DATADIR/test/t1.frm +--remove_file $MYSQLD_DATADIR/test/t1.par diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test index 358832496e5..db544d4643f 100644 --- a/mysql-test/t/partition_pruning.test +++ b/mysql-test/t/partition_pruning.test @@ -9,6 +9,30 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; --enable_warnings --echo # +--echo # Bug#53806: Wrong estimates for range query in partitioned MyISAM table +--echo # Bug#46754: 'rows' field doesn't reflect partition pruning +--echo # +CREATE TABLE t1 (a INT PRIMARY KEY) +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (1), +PARTITION p1 VALUES LESS THAN (2), +PARTITION p2 VALUES LESS THAN (3), +PARTITION p3 VALUES LESS THAN (4), +PARTITION p4 VALUES LESS THAN (5), +PARTITION p5 VALUES LESS THAN (6), +PARTITION max VALUES LESS THAN MAXVALUE); + +INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8); + +--replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 11 # +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; +--replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 11 # +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; +--replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 11 # +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; +DROP TABLE t1; + +--echo # --echo # Bug#49742: Partition Pruning not working correctly for RANGE --echo # CREATE TABLE t1 (a INT PRIMARY KEY) diff --git a/mysql-test/t/partition_range.test b/mysql-test/t/partition_range.test index 4d011ddc468..f386fac4998 100644 --- a/mysql-test/t/partition_range.test +++ b/mysql-test/t/partition_range.test @@ -846,3 +846,44 @@ insert into t2 values(52, 20070322, 456, 'filler') ; select sum(count) from t2 ch where ch.defid in (50,52) and ch.day between 20070320 and 20070401 group by defid; drop table t1, t2; + +--echo # +--echo # Bug#50939: Loose Index Scan unduly relies on engine to remember range +--echo # endpoints +--echo # +CREATE TABLE t1 ( + a INT, + b INT, + KEY ( a, b ) +) PARTITION BY HASH (a) PARTITIONS 1; + +CREATE TABLE t2 ( + a INT, + b INT, + KEY ( a, b ) +); + +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); + +INSERT INTO t1 SELECT a + 5, b + 5 FROM t1; +INSERT INTO t1 SELECT a + 10, b + 10 FROM t1; +INSERT INTO t1 SELECT a + 20, b + 20 FROM t1; +INSERT INTO t1 SELECT a + 40, b + 40 FROM t1; + +INSERT INTO t2 SELECT * FROM t1; + +--echo # plans should be identical +EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a; +EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; + +FLUSH status; +SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a; +--echo # Should be no more than 4 reads. +SHOW status LIKE 'handler_read_key'; + +FLUSH status; +SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a; +--echo # Should be no more than 4 reads. +SHOW status LIKE 'handler_read_key'; + +DROP TABLE t1, t2; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 4390b70e9e9..9b3f3e750e1 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3079,4 +3079,26 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP TABLE t1; +--echo # +--echo # Bug#54494 crash with explain extended and prepared statements +--echo # +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2); +PREPARE stmt FROM 'EXPLAIN EXTENDED SELECT 1 FROM t1 RIGHT JOIN t1 t2 ON 1'; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + +--echo # +--echo # Bug#54488 crash when using explain and prepared statements with subqueries +--echo # +CREATE TABLE t1(f1 INT); +INSERT INTO t1 VALUES (1),(1); +PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))'; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + --echo End of 5.1 tests. diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index 1543c757908..10a96285451 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -58,6 +58,10 @@ drop function if exists f1; drop view if exists v1, v2; --enable_warnings +# Avoid selecting from a huge table possibly left over from previous tests, +# as this really hurts --valgrind testing. +TRUNCATE TABLE mysql.general_log; + delimiter |; create procedure p_verify_reprepare_count(expected int) begin diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 5d5ad180f1a..0ad3d3e8504 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1313,4 +1313,16 @@ SELECT * FROM t1 FORCE INDEX (PRIMARY) DROP TABLE t1; +--echo # +--echo # Bug #54802: 'NOT BETWEEN' evaluation is incorrect +--echo # + +CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key)); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); + +EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key; +SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test index cec44078279..fb49ce23644 100644 --- a/mysql-test/t/row.test +++ b/mysql-test/t/row.test @@ -266,3 +266,22 @@ SELECT 1 FROM t1 WHERE ROW(a, b) >= ROW('1', (SELECT 1 FROM t1 WHERE a > 1234)); --enable_warnings DROP TABLE t1; + +--echo # +--echo # Bug #54190: Comparison to row subquery produces incorrect result +--echo # + +SELECT ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0); +SELECT ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0); + +CREATE TABLE t1 (i INT); +INSERT INTO t1 () VALUES (1), (2), (3); + +SELECT ROW(1,2) = (SELECT 1,2 FROM t1 WHERE 1 = 0); +SELECT ROW(1,2) = (SELECT 1,3 FROM t1 WHERE 1 = 0); +SELECT i FROM t1 WHERE ROW(1,2) = (SELECT 1,2 FROM DUAL WHERE 1 = 0); +SELECT i FROM t1 WHERE ROW(1,2) = (SELECT 1,3 FROM DUAL WHERE 1 = 0); + +DROP TABLE t1; + +--echo End of 5.1 tests diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index c287091ab54..41edd7f1216 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -87,4 +87,79 @@ SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) +1 FROM t2 t2_a, t2 t2_b DROP TABLE t1,t2; ---echo End of 5.1 tests. +--echo # +--echo # Bug#54568: create view cause Assertion failed: 0, +--echo # file .\item_subselect.cc, line 836 +--echo # +EXPLAIN SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); +DESCRIBE SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); +--echo # None of the below should crash +CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); +CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); +DROP VIEW v1, v2; + +--echo # +--echo # Bug#51070: Query with a NOT IN subquery predicate returns a wrong +--echo # result set +--echo # +CREATE TABLE t1 ( a INT, b INT ); +INSERT INTO t1 VALUES ( 1, NULL ), ( 2, NULL ); + +CREATE TABLE t2 ( c INT, d INT ); +INSERT INTO t2 VALUES ( NULL, 3 ), ( NULL, 4 ); + +CREATE TABLE t3 ( e INT, f INT ); +INSERT INTO t3 VALUES ( NULL, NULL ), ( NULL, NULL ); + +CREATE TABLE t4 ( a INT ); +INSERT INTO t4 VALUES (1), (2), (3); + +CREATE TABLE t5 ( a INT ); +INSERT INTO t5 VALUES (NULL), (2); + +--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x +EXPLAIN +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ); +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ); + +EXPLAIN +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL; +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL; +SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) IS NULL; +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS UNKNOWN; +SELECT * FROM t1 WHERE (( a, b ) NOT IN ( SELECT c, d FROM t2 )) IS UNKNOWN; + +SELECT * FROM t1 WHERE 1 = 1 AND ( a, b ) NOT IN ( SELECT c, d FROM t2 ); + +--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x +EXPLAIN +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 ); +SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 ); + +--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x +EXPLAIN +SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 ); +SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 ); + +--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x +EXPLAIN +SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 ); +SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 ); + +--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x +EXPLAIN +SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 ); +SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 ); + +SELECT * FROM t1 WHERE ( a, b ) NOT IN + ( SELECT c, d FROM t2 WHERE c = 1 AND c <> 1 ); + +SELECT * FROM t1 WHERE b NOT IN ( SELECT c FROM t2 WHERE c = 1 ); + +SELECT * FROM t1 WHERE NULL NOT IN ( SELECT c FROM t2 WHERE c = 1 AND c <> 1 ); + +DROP TABLE t1, t2, t3, t4, t5; + +--echo # +--echo # End of 5.1 tests. +--echo # diff --git a/mysql-test/t/timezone2.test b/mysql-test/t/timezone2.test index 15ddceb8d68..c4445da107c 100644 --- a/mysql-test/t/timezone2.test +++ b/mysql-test/t/timezone2.test @@ -273,5 +273,14 @@ UNLOCK TABLES; DROP TABLE t1; +--echo # +--echo # Bug #55424: convert_tz crashes when fed invalid data +--echo # + +CREATE TABLE t1 (a SET('x') NOT NULL); +INSERT INTO t1 VALUES (''); +SELECT CONVERT_TZ(1, a, 1) FROM t1; +SELECT CONVERT_TZ(1, 1, a) FROM t1; +DROP TABLE t1; --echo End of 5.1 tests diff --git a/mysql-test/t/trigger_notembedded.test b/mysql-test/t/trigger_notembedded.test index 1dee1db0a3a..f595f195dcc 100644 --- a/mysql-test/t/trigger_notembedded.test +++ b/mysql-test/t/trigger_notembedded.test @@ -1005,4 +1005,52 @@ disconnect con1; DROP USER 'no_rights'@'localhost'; DROP DATABASE db1; +# +# Bug#55421 Protocol::end_statement(): Assertion `0' on multi-table UPDATE IGNORE +# To reproduce a crash we need to provoke a trigger execution with +# the following conditions: +# - active SELECT statement during trigger execution +# (i.e. LEX::current_select != NULL); +# - IGNORE option (i.e. LEX::current_select->no_error == TRUE); +--disable_warnings +DROP DATABASE IF EXISTS mysqltest_db1; +--enable_warnings + +CREATE DATABASE mysqltest_db1; +USE mysqltest_db1; + +GRANT ALL ON mysqltest_db1.* TO mysqltest_u1@localhost; + +--connect(con1,localhost,mysqltest_u1,,mysqltest_db1) + +CREATE TABLE t1 ( + a1 int, + a2 int +); +INSERT INTO t1 VALUES (1, 20); + +CREATE TRIGGER mysqltest_db1.upd_t1 +BEFORE UPDATE ON t1 FOR EACH ROW SET new.a2 = 200; + +CREATE TABLE t2 ( + a1 int +); + +INSERT INTO t2 VALUES (2); + +--connection default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; + +--error ER_TABLEACCESS_DENIED_ERROR +UPDATE IGNORE t1, t2 SET t1.a1 = 2, t2.a1 = 3 WHERE t1.a1 = 1 AND t2.a1 = 2; +# Cleanup + +DROP DATABASE mysqltest_db1; +DROP USER mysqltest_u1@localhost; + +--disconnect con1 +--connection default +USE test; + --echo End of 5.1 tests. diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index e8374e0ebfc..602f6f089c2 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -357,3 +357,20 @@ SELECT f1,f2-f3 FROM t1; DROP TABLE t1; --echo End of 5.0 tests + +--echo # +--echo # Bug #55779: select does not work properly in mysql server +--echo # Version "5.1.42 SUSE MySQL RPM" +--echo # + +CREATE TABLE t1 (a TIMESTAMP, KEY (a)); + +INSERT INTO t1 VALUES ('2000-01-01 00:00:00'), ('2000-01-01 00:00:00'), + ('2000-01-01 00:00:01'), ('2000-01-01 00:00:01'); + +SELECT a FROM t1 WHERE a >= 20000101000000; +SELECT a FROM t1 WHERE a >= '20000101000000'; + +DROP TABLE t1; + +--echo End of 5.1 tests diff --git a/mysql-test/t/udf_query_cache.test b/mysql-test/t/udf_query_cache.test index ce7bd43ea1f..b0037973631 100644 --- a/mysql-test/t/udf_query_cache.test +++ b/mysql-test/t/udf_query_cache.test @@ -20,6 +20,7 @@ create table t1 (a char); set GLOBAL query_cache_size=1355776; reset query cache; +flush status; select metaphon('MySQL') from t1; show status like "Qcache_hits"; diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index 8e6eed60242..400ce07b7fd 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -172,13 +172,13 @@ USE `#mysql50#../blablabla`; # # Test of Bug #56441: mysql_upgrade 5.0->5.1 fails for tables with long names # -copy_file $MYSQL_TEST_DIR/std_data/long_table_name.MYI $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYI; -copy_file $MYSQL_TEST_DIR/std_data/long_table_name.MYD $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYD; -copy_file $MYSQL_TEST_DIR/std_data/long_table_name.frm $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.frm; +copy_file $MYSQL_TEST_DIR/std_data/long_table_name.MYI $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com.MYI; +copy_file $MYSQL_TEST_DIR/std_data/long_table_name.MYD $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com.MYD; +copy_file $MYSQL_TEST_DIR/std_data/long_table_name.frm $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com.frm; show full tables; -rename table `#mysql50#ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com` to `ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com`; +rename table `#mysql50#ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com` to `ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com`; show full tables; -drop table `ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com`; +drop table `ltoriaeinnovacionendesarrolloempres#9120761097220077376#cio_com`; --echo # End of 5.1 tests diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index b6b58e7bd46..4f27866de23 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -328,4 +328,22 @@ INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1); DROP TABLE t1; +# +# Bug #55615: debug assertion after using variable in assignment and +# referred to +# Bug #55564: crash with user variables, assignments, joins... +# + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (0),(0); +--echo # BUG#55615 : should not crash +SELECT (@a:=(SELECT @a:=1 FROM t1 LIMIT 1)) AND COUNT(1) FROM t1 GROUP BY @a; +--echo # BUG#55564 : should not crash +SELECT IF( + @v:=LEAST((SELECT 1 FROM t1 t2 LEFT JOIN t1 ON (@v) GROUP BY t1.a), a), + count(*), 1) +FROM t1 GROUP BY a LIMIT 1; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/variables_debug.test b/mysql-test/t/variables_debug.test index 12f5d2e6ca5..e6f1bbddc2a 100644 --- a/mysql-test/t/variables_debug.test +++ b/mysql-test/t/variables_debug.test @@ -25,4 +25,17 @@ SELECT @@global.debug; SET GLOBAL debug=@old_debug; +--echo # +--echo # Bug #56709: Memory leaks at running the 5.1 test suite +--echo # + +SET @old_local_debug = @@debug; + +SET @@debug='d,foo'; +SELECT @@debug; +SET @@debug=''; +SELECT @@debug; + +SET @@debug = @old_local_debug; + --echo End of 5.1 tests diff --git a/mysql-test/t/warnings_debug.test b/mysql-test/t/warnings_debug.test new file mode 100644 index 00000000000..99d02330960 --- /dev/null +++ b/mysql-test/t/warnings_debug.test @@ -0,0 +1,19 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (a int primary key) engine=innodb; + +# Test that warnings produced during autocommit (after calling +# set_ok_status()) are still reported to the client. +SET SESSION debug="+d,warn_during_ha_commit_trans"; +INSERT INTO t1 VALUES (1); +# The warning will be shown automatically by mysqltest; there was a bug where +# this didn't happen because the warning was not counted when sending result +# packet. Show the warnings manually also. +SHOW WARNINGS; + +drop table t1; diff --git a/mysys/Makefile.am b/mysys/Makefile.am index dc0b2bfb84b..7d1c1ff062c 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -19,10 +19,11 @@ MYSQLBASEdir= $(prefix) INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \ -I$(top_srcdir)/include -I$(srcdir) pkglib_LIBRARIES = libmysys.a +noinst_LTLIBRARIES = libmysys.la LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a noinst_HEADERS = mysys_priv.h my_static.h my_handler_errors.h \ my_safehash.h -libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ +libmysys_la_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ mf_path.c mf_loadpath.c my_file.c \ my_open.c my_create.c my_dup.c my_seek.c my_read.c \ my_pread.c my_write.c my_getpagesize.c \ @@ -57,19 +58,22 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ my_memmem.c stacktrace.c \ my_windac.c my_access.c base64.c my_libwrap.c \ wqueue.c +libmysys_la_LDFLAGS = $(AM_LDFLAGS) @WRAPLIBS@ +libmysys_la_LIBADD = $(ZLIB_LIBS) if NEED_THREAD # mf_keycache is used only in the server, so it is safe to leave the file # out of the non-threaded library. # In fact, it will currently not compile without thread support. -libmysys_a_SOURCES += mf_keycache.c mf_keycaches.c +libmysys_la_SOURCES += thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c \ + my_pthread.c my_thr_init.c waiting_threads.c \ + mf_keycache.c mf_keycaches.c endif EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c waiting_threads.c \ CMakeLists.txt mf_soundex.c \ my_conio.c my_wincond.c my_winthread.c -libmysys_a_LIBADD = @THREAD_LOBJECTS@ # test_dir_DEPENDENCIES= $(LIBRARIES) # testhash_DEPENDENCIES= $(LIBRARIES) # test_charset_DEPENDENCIES= $(LIBRARIES) @@ -83,8 +87,6 @@ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \ -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \ @DEFS@ -libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@ - # I hope this always does the right thing. Otherwise this is only test programs FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@ @@ -95,6 +97,10 @@ CLEANFILES = test_bitmap$(EXEEXT) test_priority_queue$(EXEEXT) \ testhash$(EXEEXT) test_gethwaddr$(EXEEXT) \ test_base64$(EXEEXT) test_thr_mutex$(EXEEXT) +libmysys_a_SOURCES= +libmysys.a: libmysys.la + $(CP) .libs/libmysys.a $@ + # # The CP .. RM stuff is to avoid problems with some compilers (like alpha ccc) # which automaticly removes the object files you use to compile a final program diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index e7e5f75f486..0c3f45be374 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -40,16 +40,31 @@ #include <m_string.h> #include <my_bit.h> -void create_last_word_mask(MY_BITMAP *map) + +/* Create a mask of the significant bits for the last byte (1,3,7,..255) */ + +static inline uchar last_byte_mask(uint bits) { - /* Get the number of used bits (1..8) in the last byte */ - unsigned int const used= 1U + ((map->n_bits-1U) & 0x7U); + /* Get the number of used bits-1 (0..7) in the last byte */ + unsigned int const used= (bits - 1U) & 7U; + /* Return bitmask for the significant bits */ + return ((2U << used) - 1); +} - /* - Create a mask with the upper 'unused' bits set and the lower 'used' - bits clear. The bits within each byte is stored in big-endian order. - */ - unsigned char const mask= (~((1 << used) - 1)) & 255; +/* + Create a mask with the upper 'unused' bits set and the lower 'used' + bits clear. The bits within each byte is stored in big-endian order. +*/ + +static inline uchar invers_last_byte_mask(uint bits) +{ + return last_byte_mask(bits) ^ 255; +} + + +void create_last_word_mask(MY_BITMAP *map) +{ + unsigned char const mask= invers_last_byte_mask(map->n_bits); /* The first bytes are to be set to zero since they represent real bits @@ -267,40 +282,41 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size) my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size) { - uint prefix_bits= prefix_size & 0x7, res; - uchar *m= (uchar*)map->bitmap; - uchar *end_prefix= m+prefix_size/8; + uint prefix_mask= last_byte_mask(prefix_size); + uchar *m= (uchar*) map->bitmap; + uchar *end_prefix= m+(prefix_size-1)/8; uchar *end; DBUG_ASSERT(m && prefix_size <= map->n_bits); - end= m+no_bytes_in_map(map); + + /* Empty prefix is always true */ + if (!prefix_size) + return 1; while (m < end_prefix) if (*m++ != 0xff) return 0; - *map->last_word_ptr&= ~map->last_word_mask; /*Clear bits*/ - res= 0; - if (prefix_bits && *m++ != (1 << prefix_bits)-1) - goto ret; + end= ((uchar*) map->bitmap) + no_bytes_in_map(map) - 1; + if (m == end) + return ((*m & last_byte_mask(map->n_bits)) == prefix_mask); - while (m < end) - if (*m++ != 0) - goto ret; - res= 1; -ret: - return res; -} + if (*m != prefix_mask) + return 0; + while (++m < end) + if (*m != 0) + return 0; + return ((*m & last_byte_mask(map->n_bits)) == 0); +} my_bool bitmap_is_set_all(const MY_BITMAP *map) { my_bitmap_map *data_ptr= map->bitmap; my_bitmap_map *end= map->last_word_ptr; - *map->last_word_ptr |= map->last_word_mask; - for (; data_ptr <= end; data_ptr++) + for (; data_ptr < end; data_ptr++) if (*data_ptr != 0xFFFFFFFF) return FALSE; - return TRUE; + return (*data_ptr | map->last_word_mask) == 0xFFFFFFFF; } @@ -308,13 +324,11 @@ my_bool bitmap_is_clear_all(const MY_BITMAP *map) { my_bitmap_map *data_ptr= map->bitmap; my_bitmap_map *end; - if (*map->last_word_ptr & ~map->last_word_mask) - return FALSE; end= map->last_word_ptr; for (; data_ptr < end; data_ptr++) if (*data_ptr) return FALSE; - return TRUE; + return (*data_ptr & ~map->last_word_mask) == 0; } /* Return TRUE if map1 is a subset of map2 */ @@ -327,14 +341,13 @@ my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2) map1->n_bits==map2->n_bits); end= map1->last_word_ptr; - *map1->last_word_ptr &= ~map1->last_word_mask; - *map2->last_word_ptr &= ~map2->last_word_mask; - while (m1 <= end) + while (m1 < end) { if ((*m1++) & ~(*m2++)) return 0; } - return 1; + /* here both maps have the same number of bits - see assert above */ + return ((*m1 & ~*m2 & ~map1->last_word_mask) ? 0 : 1); } /* True if bitmaps has any common bits */ @@ -347,14 +360,13 @@ my_bool bitmap_is_overlapping(const MY_BITMAP *map1, const MY_BITMAP *map2) map1->n_bits==map2->n_bits); end= map1->last_word_ptr; - *map1->last_word_ptr &= ~map1->last_word_mask; - *map2->last_word_ptr &= ~map2->last_word_mask; - while (m1 <= end) + while (m1 < end) { if ((*m1++) & (*m2++)) return 1; } - return 0; + /* here both maps have the same number of bits - see assert above */ + return ((*m1 & *m2 & ~map1->last_word_mask) ? 1 : 0); } @@ -366,15 +378,15 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2) DBUG_ASSERT(map->bitmap && map2->bitmap); end= to+min(len,len2); - *map2->last_word_ptr&= ~map2->last_word_mask; /*Clear last bits in map2*/ while (to < end) *to++ &= *from++; - if (len2 < len) + if (len2 <= len) { - end+=len-len2; + to[-1]&= ~map2->last_word_mask; /* Clear last not relevant bits */ + end+= len-len2; while (to < end) - *to++=0; + *to++= 0; } } @@ -386,13 +398,12 @@ my_bool bitmap_union_is_set_all(const MY_BITMAP *map1, const MY_BITMAP *map2) DBUG_ASSERT(map1->bitmap && map2->bitmap && map1->n_bits==map2->n_bits); - *map1->last_word_ptr|= map1->last_word_mask; - end= map1->last_word_ptr; - while ( m1 <= end) + while ( m1 < end) if ((*m1++ | *m2++) != 0xFFFFFFFF) return FALSE; - return TRUE; + /* here both maps have the same number of bits - see assert above */ + return ((*m1 | *m2 | map1->last_word_mask) != 0xFFFFFFFF); } @@ -479,14 +490,13 @@ void bitmap_invert(MY_BITMAP *map) uint bitmap_bits_set(const MY_BITMAP *map) { uchar *m= (uchar*)map->bitmap; - uchar *end= m + no_bytes_in_map(map); + uchar *end= m + no_bytes_in_map(map) - 1; uint res= 0; DBUG_ASSERT(map->bitmap); - *map->last_word_ptr&= ~map->last_word_mask; /*Reset last bits to zero*/ while (m < end) res+= my_count_bits_ushort(*m++); - return res; + return res + my_count_bits_ushort(*m & last_byte_mask(map->n_bits)); } @@ -510,27 +520,30 @@ uint bitmap_get_first_set(const MY_BITMAP *map) DBUG_ASSERT(map->bitmap); data_ptr= map->bitmap; - *map->last_word_ptr &= ~map->last_word_mask; - for (i=0; data_ptr <= end; data_ptr++, i++) - { + for (i=0; data_ptr < end; data_ptr++, i++) if (*data_ptr) + goto found; + if (!(*data_ptr & ~map->last_word_mask)) + return MY_BIT_NONE; + +found: + { + byte_ptr= (uchar*)data_ptr; + for (j=0; ; j++, byte_ptr++) { - byte_ptr= (uchar*)data_ptr; - for (j=0; ; j++, byte_ptr++) + if (*byte_ptr) { - if (*byte_ptr) + for (k=0; ; k++) { - for (k=0; ; k++) - { - if (*byte_ptr & (1 << k)) - return (i*32) + (j*8) + k; - } + if (*byte_ptr & (1 << k)) + return (i*32) + (j*8) + k; } } } } - return MY_BIT_NONE; + DBUG_ASSERT(0); + return MY_BIT_NONE; /* Impossible */ } @@ -544,25 +557,29 @@ uint bitmap_get_first(const MY_BITMAP *map) data_ptr= map->bitmap; *map->last_word_ptr|= map->last_word_mask; - for (i=0; data_ptr <= end; data_ptr++, i++) - { + for (i=0; data_ptr < end; data_ptr++, i++) if (*data_ptr != 0xFFFFFFFF) + goto found; + if ((*data_ptr | map->last_word_mask) == 0xFFFFFFFF) + return MY_BIT_NONE; + +found: + { + byte_ptr= (uchar*)data_ptr; + for (j=0; ; j++, byte_ptr++) { - byte_ptr= (uchar*)data_ptr; - for (j=0; ; j++, byte_ptr++) + if (*byte_ptr != 0xFF) { - if (*byte_ptr != 0xFF) + for (k=0; ; k++) { - for (k=0; ; k++) - { - if (!(*byte_ptr & (1 << k))) - return (i*32) + (j*8) + k; - } + if (!(*byte_ptr & (1 << k))) + return (i*32) + (j*8) + k; } } } } - return MY_BIT_NONE; + DBUG_ASSERT(0); + return MY_BIT_NONE; /* Impossible */ } @@ -777,7 +794,7 @@ uint get_rand_bit(uint bitsize) return (rand() % bitsize); } -bool test_set_get_clear_bit(MY_BITMAP *map, uint bitsize) +my_bool test_set_get_clear_bit(MY_BITMAP *map, uint bitsize) { uint i, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; @@ -800,7 +817,7 @@ error2: return TRUE; } -bool test_flip_bit(MY_BITMAP *map, uint bitsize) +my_bool test_flip_bit(MY_BITMAP *map, uint bitsize) { uint i, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; @@ -823,13 +840,13 @@ error2: return TRUE; } -bool test_operators(MY_BITMAP *map __attribute__((unused)), +my_bool test_operators(MY_BITMAP *map __attribute__((unused)), uint bitsize __attribute__((unused))) { return FALSE; } -bool test_get_all_bits(MY_BITMAP *map, uint bitsize) +my_bool test_get_all_bits(MY_BITMAP *map, uint bitsize) { uint i; bitmap_set_all(map); @@ -871,7 +888,7 @@ error6: return TRUE; } -bool test_compare_operators(MY_BITMAP *map, uint bitsize) +my_bool test_compare_operators(MY_BITMAP *map, uint bitsize) { uint i, j, test_bit1, test_bit2, test_bit3,test_bit4; uint no_loops= bitsize > 128 ? 128 : bitsize; @@ -977,7 +994,7 @@ error5: return TRUE; } -bool test_count_bits_set(MY_BITMAP *map, uint bitsize) +my_bool test_count_bits_set(MY_BITMAP *map, uint bitsize) { uint i, bit_count=0, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; @@ -1003,7 +1020,7 @@ error2: return TRUE; } -bool test_get_first_bit(MY_BITMAP *map, uint bitsize) +my_bool test_get_first_bit(MY_BITMAP *map, uint bitsize) { uint i, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; @@ -1028,7 +1045,7 @@ error2: return TRUE; } -bool test_get_next_bit(MY_BITMAP *map, uint bitsize) +my_bool test_get_next_bit(MY_BITMAP *map, uint bitsize) { uint i, j, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; @@ -1047,7 +1064,7 @@ error1: return TRUE; } -bool test_prefix(MY_BITMAP *map, uint bitsize) +my_bool test_prefix(MY_BITMAP *map, uint bitsize) { uint i, j, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; @@ -1082,7 +1099,7 @@ error3: } -bool do_test(uint bitsize) +my_bool do_test(uint bitsize) { MY_BITMAP map; my_bitmap_map buf[1024]; diff --git a/mysys/my_copy.c b/mysys/my_copy.c index 8ea9620b20b..e1c549f4676 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -112,7 +112,7 @@ int my_copy(const char *from, const char *to, myf MyFlags) { my_errno= errno; if (MyFlags & MY_WME) - my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno); + my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), to, errno); if (MyFlags & MY_FAE) goto err; } diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 80b355ea69a..d125c6ba72f 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -112,7 +112,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_get_one_option get_one_option) { - uint opt_found, argvpos= 0, length; + uint UNINIT_VAR(opt_found), argvpos= 0, length; my_bool end_of_options= 0, must_be_var, set_maximum_value, option_is_loose; char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN]; @@ -121,7 +121,6 @@ int handle_options(int *argc, char ***argv, void *value; int error, i; - LINT_INIT(opt_found); /* handle_options() assumes arg0 (program name) always exists */ DBUG_ASSERT(argc && *argc >= 1); DBUG_ASSERT(argv && *argv); @@ -614,7 +613,6 @@ static int setval(const struct my_option *opts, void *value, char *argument, my_bool set_maximum_value) { int err= 0; - int pos; if (value && argument) { @@ -658,18 +656,21 @@ static int setval(const struct my_option *opts, void *value, char *argument, return EXIT_OUT_OF_MEMORY; break; case GET_ENUM: - pos= find_type(argument, opts->typelib, 2) - 1; - (*(ulong *)result_pos)= pos; - if (pos < 0) { - /* - Accept an integer representation of the enumerated item. - */ - char *endptr; - unsigned int arg= (unsigned int) strtol(argument, &endptr, 10); - if (*endptr || arg >= opts->typelib->count) - return EXIT_ARGUMENT_INVALID; - *(int*)result_pos= arg; + int type= find_type(argument, opts->typelib, 2); + if (type < 1) + { + /* + Accept an integer representation of the enumerated item. + */ + char *endptr; + ulong arg= strtoul(argument, &endptr, 10); + if (*endptr || arg >= opts->typelib->count) + return EXIT_ARGUMENT_INVALID; + *((ulong*) result_pos)= arg; + } + else + *((ulong*) result_pos)= type - 1; } break; case GET_SET: @@ -1006,7 +1007,7 @@ static void init_one_value(const struct my_option *option, void *variable, *((int*) variable)= (int) getopt_ll_limit_value((int) value, option, NULL); break; case GET_ENUM: - *((ulong*) variable)= (uint) value; + *((ulong*) variable)= (ulong) value; break; case GET_UINT: *((uint*) variable)= (uint) getopt_ull_limit_value((uint) value, option, NULL); diff --git a/mysys/my_redel.c b/mysys/my_redel.c index cf0986a7821..2de989a2854 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -40,7 +40,8 @@ struct utimbuf { #define REDEL_EXT ".BAK" -int my_redel(const char *org_name, const char *tmp_name, myf MyFlags) +int my_redel(const char *org_name, const char *tmp_name, + time_t backup_time_stamp, myf MyFlags) { int error=1; DBUG_ENTER("my_redel"); @@ -51,13 +52,9 @@ int my_redel(const char *org_name, const char *tmp_name, myf MyFlags) goto end; if (MyFlags & MY_REDEL_MAKE_BACKUP) { - char name_buff[FN_REFLEN+20]; - char ext[20]; - ext[0]='-'; - get_date(ext+1,2+4,(time_t) 0); - strmov(strend(ext),REDEL_EXT); - if (my_rename(org_name, fn_format(name_buff, org_name, "", ext, 2), - MyFlags)) + char name_buff[FN_REFLEN + MY_BACKUP_NAME_EXTRA_LENGTH]; + my_create_backup_name(name_buff, org_name, backup_time_stamp); + if (my_rename(org_name, name_buff, MyFlags)) goto end; } else if (my_delete_allow_opened(org_name, MyFlags)) @@ -149,3 +146,23 @@ int my_copystat(const char *from, const char *to, int MyFlags) #endif return 0; } /* my_copystat */ + + +/** + Create a backup file name. + @fn my_create_backup_name() + @param to Store new file name here + @param from Original name + + @info + The backup name is made by adding -YYMMDDHHMMSS.BAK to the file name +*/ + +void my_create_backup_name(char *to, const char *from, time_t backup_start) +{ + char ext[MY_BACKUP_NAME_EXTRA_LENGTH+1]; + ext[0]='-'; + get_date(ext+1, GETDATE_SHORT_DATE | GETDATE_HHMMSSTIME, backup_start); + strmov(strend(ext),REDEL_EXT); + strmov(strmov(to, from), ext); +} diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c index 7c3ddbb911c..bc7ac751fad 100644 --- a/mysys/my_symlink2.c +++ b/mysys/my_symlink2.c @@ -34,8 +34,8 @@ File my_create_with_symlink(const char *linkname, const char *filename, char abs_linkname[FN_REFLEN]; DBUG_ENTER("my_create_with_symlink"); DBUG_PRINT("enter", ("linkname: %s filename: %s", - linkname ? linkname : "(null)", - filename ? filename : "(null)")); + linkname ? linkname : "(NULL)", + filename ? filename : "(NULL)")); if (my_disable_symlinks) { diff --git a/mysys/my_uuid.c b/mysys/my_uuid.c index f115806b4e9..e2372391b06 100644 --- a/mysys/my_uuid.c +++ b/mysys/my_uuid.c @@ -50,7 +50,7 @@ static ulonglong uuid_time= 0; static uchar uuid_suffix[2+6]; /* clock_seq and node */ #ifdef THREAD -pthread_mutex_t LOCK_uuid_generator; +static pthread_mutex_t LOCK_uuid_generator; #endif /* diff --git a/mysys/sha1.c b/mysys/sha1.c index 3469e480c26..e5b33a9ad13 100644 --- a/mysys/sha1.c +++ b/mysys/sha1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2004, 2006 MySQL AB +/* Copyright (c) 2002, 2004, 2006 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 @@ -6,26 +6,57 @@ 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 + 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 */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ /* Original Source from: http://www.faqs.org/rfcs/rfc3174.html + Copyright (C) The Internet Society (2001). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + Acknowledgement + Funding for the RFC Editor function is currently provided by the + Internet Society. + DESCRIPTION - This file implements the Secure Hashing Algorithm 1 as - defined in FIPS PUB 180-1 published April 17, 1995. - - The SHA-1, produces a 160-bit message digest for a given data - stream. It should take about 2**n steps to find a message with the - same digest as a given message and 2**(n/2) to find any two - messages with the same digest, when n is the digest size in bits. - Therefore, this algorithm can serve as a means of providing a - "fingerprint" for a message. + This file implements the Secure Hashing Algorithm 1 as + defined in FIPS PUB 180-1 published April 17, 1995. + + The SHA-1, produces a 160-bit message digest for a given data + stream. It should take about 2**n steps to find a message with the + same digest as a given message and 2**(n/2) to find any two + messages with the same digest, when n is the digest size in bits. + Therefore, this algorithm can serve as a means of providing a + "fingerprint" for a message. PORTABILITY ISSUES SHA-1 is defined in terms of 32-bit "words". This code uses diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index b8aa9e5fcc0..341b2f0058e 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -63,6 +63,11 @@ update_status: A storage engine should also call update_status internally in the ::external_lock(F_UNLCK) method. In MyISAM and CSV this functions updates the length of the datafile. + MySQL does in some exceptional cases (when doing DLL statements on + open tables calls thr_unlock() followed by thr_lock() without calling + ::external_lock() in between. In this case thr_unlock() is called with + the THR_UNLOCK_UPDATE_STATUS flag and thr_unlock() will call + update_status for write locks. get_status: When one gets a lock this functions is called. In MyISAM this stores the number of rows and size of the datafile @@ -105,8 +110,30 @@ static inline pthread_cond_t *get_cond(void) return &my_thread_var->suspend; } + +/* + Priority for locks (decides in which order locks are locked) + We want all write locks to be first, followed by read locks. + Locks from MERGE tables has a little lower priority than other + locks, to allow one to release merge tables without having + to unlock and re-lock other locks. + The lower the number, the higher the priority for the lock. + Read locks should have 4, write locks should have 0. + UNLOCK is 8, to force these last in thr_merge_locks. + For MERGE tables we add 2 (THR_LOCK_MERGE_PRIV) to the lock priority. + THR_LOCK_LATE_PRIV (1) is used when one locks other tables to be merged + with existing locks. This way we prioritize the original locks over the + new locks. +*/ + +static uint lock_priority[(uint)TL_WRITE_ONLY+1] = +{ 8, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0}; + +#define LOCK_CMP(A,B) ((uchar*) ((A)->lock) + lock_priority[(uint) (A)->type] + (A)->priority < (uchar*) ((B)->lock) + lock_priority[(uint) (B)->type] + (B)->priority) + + /* -** For the future (now the thread specific cond is alloced by my_pthread.c) + For the future (now the thread specific cond is alloced by my_pthread.c) */ my_bool init_thr_lock() @@ -379,6 +406,7 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *param) data->owner= 0; /* no owner yet */ data->status_param=param; data->cond=0; + data->priority= 0; } @@ -530,7 +558,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, } -enum enum_thr_lock_result +static enum enum_thr_lock_result thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, enum thr_lock_type lock_type) { @@ -544,6 +572,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, data->cond=0; /* safety */ data->type=lock_type; data->owner= owner; /* Must be reset ! */ + data->priority&= ~THR_LOCK_LATE_PRIV; VOID(pthread_mutex_lock(&lock->mutex)); DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx type: %d", (long) data, data->owner->info->thread_id, @@ -808,7 +837,7 @@ static inline void free_all_read_locks(THR_LOCK *lock, /* Unlock lock and free next thread on same lock */ -void thr_unlock(THR_LOCK_DATA *data) +void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags) { THR_LOCK *lock=data->lock; enum thr_lock_type lock_type=data->type; @@ -832,6 +861,21 @@ void thr_unlock(THR_LOCK_DATA *data) } else lock->write.last=data->prev; + + if (unlock_flags & THR_UNLOCK_UPDATE_STATUS) + { + /* External lock was not called; Update or restore status */ + if (lock_type >= TL_WRITE_CONCURRENT_INSERT) + { + if (lock->update_status) + (*lock->update_status)(data->status_param); + } + else + { + if (lock->restore_status) + (*lock->restore_status)(data->status_param); + } + } if (lock_type == TL_READ_NO_INSERT) lock->read_no_write_count--; data->type=TL_UNLOCK; /* Mark unlocked */ @@ -967,14 +1011,12 @@ end: /* -** Get all locks in a specific order to avoid dead-locks -** Sort acording to lock position and put write_locks before read_locks if -** lock on same lock. + Get all locks in a specific order to avoid dead-locks + Sort acording to lock position and put write_locks before read_locks if + lock on same lock. Locks on MERGE tables has lower priority than other + locks of the same type. See comment for lock_priority. */ - -#define LOCK_CMP(A,B) ((uchar*) (A->lock) - (uint) ((A)->type) < (uchar*) (B->lock)- (uint) ((B)->type)) - static void sort_locks(THR_LOCK_DATA **data,uint count) { THR_LOCK_DATA **pos,**end,**prev,*tmp; @@ -999,18 +1041,22 @@ static void sort_locks(THR_LOCK_DATA **data,uint count) enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner) { - THR_LOCK_DATA **pos,**end; + THR_LOCK_DATA **pos, **end, **first_lock; DBUG_ENTER("thr_multi_lock"); DBUG_PRINT("lock",("data: 0x%lx count: %d", (long) data, count)); + if (count > 1) sort_locks(data,count); + else if (count == 0) + DBUG_RETURN(THR_LOCK_SUCCESS); + /* lock everything */ for (pos=data,end=data+count; pos < end ; pos++) { enum enum_thr_lock_result result= thr_lock(*pos, owner, (*pos)->type); if (result != THR_LOCK_SUCCESS) { /* Aborted */ - thr_multi_unlock(data,(uint) (pos-data)); + thr_multi_unlock(data,(uint) (pos-data), 0); DBUG_RETURN(result); } #ifdef MAIN @@ -1018,63 +1064,103 @@ thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner) (long) pos[0]->lock, pos[0]->type); fflush(stdout); #endif } + /* - Ensure that all get_locks() have the same status + Call start_trans for all locks. If we lock the same table multiple times, we must use the same - status_param! + status_param; We ensure this by calling copy_status() for all + copies of the same tables. */ -#if !defined(DONT_USE_RW_LOCKS) - if (count > 1) + if ((*data)->lock->start_trans) + ((*data)->lock->start_trans)((*data)->status_param); + for (first_lock=data, pos= data+1 ; pos < end ; pos++) { - THR_LOCK_DATA *last_lock= end[-1]; - pos=end-1; - do + /* Get the current status (row count, checksum, trid etc) */ + if ((*pos)->lock->start_trans) + (*(*pos)->lock->start_trans)((*pos)->status_param); + /* + If same table as previous table use pointer to previous status + information to ensure that all read/write tables shares same + state. + */ + if (pos[0]->lock == pos[-1]->lock && pos[0]->lock->copy_status) + (pos[0]->lock->copy_status)((*pos)->status_param, + (*first_lock)->status_param); + else { - pos--; - if (last_lock->lock == (*pos)->lock && - last_lock->lock->copy_status) - { - if (last_lock->type <= TL_READ_NO_INSERT) - { - THR_LOCK_DATA **read_lock; - /* - If we are locking the same table with read locks we must ensure - that all tables share the status of the last write lock or - the same read lock. - */ - for (; - (*pos)->type <= TL_READ_NO_INSERT && - pos != data && - pos[-1]->lock == (*pos)->lock ; - pos--) ; - - read_lock = pos+1; - do - { - (last_lock->lock->copy_status)((*read_lock)->status_param, - (*pos)->status_param); - } while (*(read_lock++) != last_lock); - last_lock= (*pos); /* Point at last write lock */ - } - else - (*last_lock->lock->copy_status)((*pos)->status_param, - last_lock->status_param); - } - else - last_lock=(*pos); - } while (pos != data); + /* Different lock, use this as base for next lock */ + first_lock= pos; + } } -#endif DBUG_RETURN(THR_LOCK_SUCCESS); } - /* free all locks */ -void thr_multi_unlock(THR_LOCK_DATA **data,uint count) +/** + Merge two sets of locks. + + @param data All locks. First old locks, then new locks. + @param old_count Original number of locks. These are first in 'data'. + @param new_count How many new locks + + The merge is needed if the new locks contains same tables as the old + locks, in which case we have to ensure that same tables shares the + same status (as after a thr_multi_lock()). +*/ + +void thr_merge_locks(THR_LOCK_DATA **data, uint old_count, uint new_count) +{ + THR_LOCK_DATA **pos, **end, **first_lock= 0; + DBUG_ENTER("thr_merge_lock"); + + /* Remove marks on old locks to make them sort before new ones */ + for (pos=data, end= pos + old_count; pos < end ; pos++) + (*pos)->priority&= ~THR_LOCK_LATE_PRIV; + + /* Mark new locks with LATE_PRIV to make them sort after org ones */ + for (pos=data + old_count, end= pos + new_count; pos < end ; pos++) + (*pos)->priority|= THR_LOCK_LATE_PRIV; + + sort_locks(data, old_count + new_count); + + for (pos=data ; pos < end ; pos++) + { + /* Check if lock was unlocked before */ + if (pos[0]->type == TL_UNLOCK || ! pos[0]->lock->fix_status) + { + DBUG_PRINT("info", ("lock skipped. unlocked: %d fix_status: %d", + pos[0]->type == TL_UNLOCK, + pos[0]->lock->fix_status == 0)); + continue; + } + + /* + If same table as previous table use pointer to previous status + information to ensure that all read/write tables shares same + state. + */ + if (first_lock && pos[0]->lock == first_lock[0]->lock) + (pos[0]->lock->fix_status)((*first_lock)->status_param, + (*pos)->status_param); + else + { + /* Different lock, use this as base for next lock */ + first_lock= pos; + (pos[0]->lock->fix_status)((*first_lock)->status_param, 0); + } + } + DBUG_VOID_RETURN; +} + + +/* Unlock all locks */ + +void thr_multi_unlock(THR_LOCK_DATA **data,uint count, uint unlock_flags) { THR_LOCK_DATA **pos,**end; DBUG_ENTER("thr_multi_unlock"); - DBUG_PRINT("lock",("data: 0x%lx count: %d", (long) data, count)); + DBUG_PRINT("lock",("data: 0x%lx count: %d flags: %u", (long) data, count, + unlock_flags)); for (pos=data,end=data+count; pos < end ; pos++) { @@ -1084,7 +1170,7 @@ void thr_multi_unlock(THR_LOCK_DATA **data,uint count) fflush(stdout); #endif if ((*pos)->type != TL_UNLOCK) - thr_unlock(*pos); + thr_unlock(*pos, unlock_flags); else { DBUG_PRINT("lock",("Free lock: data: 0x%lx thread: 0x%lx lock: 0x%lx", @@ -1400,6 +1486,7 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data, enum thr_lock_type new_lock_type) { THR_LOCK *lock=data->lock; + enum enum_thr_lock_result res; DBUG_ENTER("thr_upgrade_write_delay_lock"); pthread_mutex_lock(&lock->mutex); @@ -1420,6 +1507,8 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data, if (lock->get_status) (*lock->get_status)(data->status_param, 0); pthread_mutex_unlock(&lock->mutex); + if (lock->start_trans) + (*lock->start_trans)(data->status_param); DBUG_RETURN(0); } @@ -1440,7 +1529,10 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data, { check_locks(lock,"waiting for lock",0); } - DBUG_RETURN(wait_for_lock(&lock->write_wait,data,1)); + res= wait_for_lock(&lock->write_wait,data,1); + if (res == THR_LOCK_SUCCESS && lock->start_trans) + DBUG_RETURN((*lock->start_trans)(data->status_param)); + DBUG_RETURN(0); } @@ -1684,7 +1776,7 @@ static void *test_thread(void *arg) } } pthread_mutex_unlock(&LOCK_thread_count); - thr_multi_unlock(multi_locks,lock_counts[param]); + thr_multi_unlock(multi_locks,lock_counts[param], THR_UNLOCK_UPDATE_STATUS); } printf("Thread %s (%d) ended\n",my_thread_name(),param); fflush(stdout); diff --git a/plugin/daemon_example/Makefile.am b/plugin/daemon_example/Makefile.am index 02310699396..a64aa169606 100644 --- a/plugin/daemon_example/Makefile.am +++ b/plugin/daemon_example/Makefile.am @@ -27,15 +27,12 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ EXTRA_LTLIBRARIES = libdaemon_example.la pkgplugin_LTLIBRARIES = @plugin_daemon_example_shared_target@ libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -libdaemon_example_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN -libdaemon_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +libdaemon_example_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN libdaemon_example_la_SOURCES = daemon_example.cc - EXTRA_LIBRARIES = libdaemon_example.a noinst_LIBRARIES = @plugin_daemon_example_static_target@ libdaemon_example_a_CXXFLAGS = $(AM_CXXFLAGS) -libdaemon_example_a_CFLAGS = $(AM_CFLAGS) libdaemon_example_a_SOURCES= daemon_example.cc # Don't update the files from bitkeeper diff --git a/plugin/fulltext/Makefile.am b/plugin/fulltext/Makefile.am index 343416072dd..45565e9fdb2 100644 --- a/plugin/fulltext/Makefile.am +++ b/plugin/fulltext/Makefile.am @@ -21,7 +21,7 @@ INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include pkgplugin_LTLIBRARIES= mypluglib.la mypluglib_la_SOURCES= plugin_example.c mypluglib_la_LDFLAGS= -module -rpath $(pkgplugindir) -mypluglib_la_CFLAGS= -DMYSQL_DYNAMIC_PLUGIN +mypluglib_la_CFLAGS= -shared -DMYSQL_DYNAMIC_PLUGIN # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/regex/Makefile.am b/regex/Makefile.am index 0fd62a777f6..6e46e537c4b 100644 --- a/regex/Makefile.am +++ b/regex/Makefile.am @@ -16,10 +16,10 @@ # MA 02111-1307, USA INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -noinst_LIBRARIES = libregex.a -LDADD= libregex.a $(top_builddir)/strings/libmystrings.a +noinst_LTLIBRARIES = libregex.la +LDADD= libregex.la $(top_builddir)/strings/libmystrings.la noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c my_regex.h -libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c +libregex_la_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c noinst_PROGRAMS = re re_SOURCES = split.c debug.c main.c re_LDFLAGS= @NOINST_LDFLAGS@ diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist index aa252ed2b7b..c3c7f9a61b4 100755 --- a/scripts/make_win_bin_dist +++ b/scripts/make_win_bin_dist @@ -280,6 +280,7 @@ cp include/mysql.h \ include/keycache.h \ include/m_ctype.h \ include/my_attribute.h \ + include/my_compiler.h \ include/mysqld_error.h \ include/sql_state.h \ include/mysqld_ername.h \ diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 8bae2ec9db1..2d3775afb3a 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -408,20 +408,16 @@ else echo " shell> $bindir/mysql -u root mysql" echo " mysql> show tables" echo - echo "Try 'mysqld --help' if you have problems with paths. Using --log" - echo "gives you a log in $ldata that may be helpful." + echo "Try 'mysqld --help' if you have problems with paths. Using" + echo "--general-log gives you a log in $ldata that may be helpful." echo - echo "The latest information about MariaDB is available on the web at" - echo "http://askmonty.org/wiki/index.php/MariaDB". - echo "If you have a problem, you can consult the MySQL manual section" - echo "'Problems running mysql_install_db', and the manual section that" - echo "describes problems on your OS at http://dev.mysql.com/doc/" + echo "The latest information about mysql_install_db is available at" + echo "http://kb.askmonty.org/v/installing-system-tables-mysql_install_db." echo "MariaDB is hosted on launchpad; You can find the latest source and" echo "email lists at http://launchpad.net/maria" echo echo "Please check all of the above before mailing us! And remember, if" echo "you do mail us, you should use the $scriptdir/mysqlbug script!" - echo exit 1 fi diff --git a/sql/Makefile.am b/sql/Makefile.am index 5dcbbb9815a..20eef1bb7d7 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -36,7 +36,7 @@ noinst_LTLIBRARIES= libndb.la \ SUPPORTING_LIBS = $(top_builddir)/vio/libvio.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/regex/libregex.a \ + $(top_builddir)/regex/libregex.la \ $(top_builddir)/strings/libmystrings.a mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@ diff --git a/sql/field.cc b/sql/field.cc index c88ba52f31f..cc3a9863587 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1536,7 +1536,7 @@ void Field::make_field(Send_field *field) } else field->org_table_name= field->db_name= ""; - if (orig_table) + if (orig_table && orig_table->alias) { field->table_name= orig_table->alias; field->org_col_name= field_name; @@ -4562,7 +4562,7 @@ String *Field_double::val_str(String *val_buffer, #endif doubleget(nr,ptr); - uint to_length=max(field_length, DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE); + uint to_length= DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE; val_buffer->alloc(to_length); char *to=(char*) val_buffer->ptr(); diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index bde8ff053e7..b28e270a61c 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -232,6 +232,8 @@ void ha_partition::init_handler_variables() m_innodb= FALSE; m_extra_cache= FALSE; m_extra_cache_size= 0; + m_extra_prepare_for_update= FALSE; + m_extra_cache_part_id= NO_CURRENT_PART_ID; m_handler_status= handler_not_initialized; m_low_byte_first= 1; m_part_field_array= NULL; @@ -2403,9 +2405,14 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root) tot_partition_words= (m_tot_parts + 3) / 4; engine_array= (handlerton **) my_alloca(m_tot_parts * sizeof(handlerton*)); for (i= 0; i < m_tot_parts; i++) + { engine_array[i]= ha_resolve_by_legacy_type(ha_thd(), (enum legacy_db_type) - *(uchar *) ((file_buffer) + 12 + i)); + *(uchar *) ((file_buffer) + + 12 + i)); + if (!engine_array[i]) + goto err3; + } address_tot_name_len= file_buffer + 12 + 4 * tot_partition_words; tot_name_words= (uint4korr(address_tot_name_len) + 3) / 4; if (len_words != (tot_partition_words + tot_name_words + 4)) @@ -2444,6 +2451,21 @@ err1: /**************************************************************************** MODULE open/close object ****************************************************************************/ + + +/** + A destructor for partition-specific TABLE_SHARE data. +*/ + +void ha_data_partition_destroy(void *ha_data) +{ + if (ha_data) + { + HA_DATA_PARTITION *ha_part_data= (HA_DATA_PARTITION*) ha_data; + pthread_mutex_destroy(&ha_part_data->LOCK_auto_inc); + } +} + /* Open handler object @@ -2600,6 +2622,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) } DBUG_PRINT("info", ("table_share->ha_data 0x%p", ha_data)); bzero(ha_data, sizeof(HA_DATA_PARTITION)); + table_share->ha_data_destroy= ha_data_partition_destroy; + VOID(pthread_mutex_init(&ha_data->LOCK_auto_inc, MY_MUTEX_INIT_FAST)); } if (is_not_tmp_table) pthread_mutex_unlock(&table_share->mutex); @@ -5375,9 +5399,6 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, when performing the sequential scan we will check this recorded value and call extra_opt whenever we start scanning a new partition. - monty: Neads to be fixed so that it's passed to all handlers when we - move to another partition during table scan. - HA_EXTRA_NO_CACHE: When performing a UNION SELECT HA_EXTRA_NO_CACHE is called from the flush method in the select_union class. @@ -5389,7 +5410,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, for. If no cache is in use they will quickly return after finding this out. And we also ensure that all caches are disabled and no one is left by mistake. - In the future this call will probably be deleted an we will instead call + In the future this call will probably be deleted and we will instead call ::reset(); HA_EXTRA_WRITE_CACHE: @@ -5401,8 +5422,9 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, This is called as part of a multi-table update. When the table to be updated is also scanned then this informs MyISAM handler to drop any caches if dynamic records are used (fixed size records do not care - about this call). We pass this along to all underlying MyISAM handlers - and ignore it for the rest. + about this call). We pass this along to the first partition to scan, and + flag that it is to be called after HA_EXTRA_CACHE when moving to the next + partition to scan. HA_EXTRA_PREPARE_FOR_DROP: Only used by MyISAM, called in preparation for a DROP TABLE. @@ -5549,9 +5571,23 @@ int ha_partition::extra(enum ha_extra_function operation) /* Category 3), used by MyISAM handlers */ case HA_EXTRA_PREPARE_FOR_RENAME: DBUG_RETURN(prepare_for_rename()); + break; + case HA_EXTRA_PREPARE_FOR_UPDATE: + /* + Needs to be run on the first partition in the range now, and + later in late_extra_cache, when switching to a new partition to scan. + */ + m_extra_prepare_for_update= TRUE; + if (m_part_spec.start_part != NO_CURRENT_PART_ID) + { + if (!m_extra_cache) + m_extra_cache_part_id= m_part_spec.start_part; + DBUG_ASSERT(m_extra_cache_part_id == m_part_spec.start_part); + VOID(m_file[m_part_spec.start_part]->extra(HA_EXTRA_PREPARE_FOR_UPDATE)); + } + break; case HA_EXTRA_NORMAL: case HA_EXTRA_QUICK: - case HA_EXTRA_PREPARE_FOR_UPDATE: case HA_EXTRA_FORCE_REOPEN: case HA_EXTRA_PREPARE_FOR_DROP: case HA_EXTRA_FLUSH_CACHE: @@ -5572,10 +5608,22 @@ int ha_partition::extra(enum ha_extra_function operation) break; } case HA_EXTRA_NO_CACHE: + { + int ret= 0; + if (m_extra_cache_part_id != NO_CURRENT_PART_ID) + ret= m_file[m_extra_cache_part_id]->extra(HA_EXTRA_NO_CACHE); + m_extra_cache= FALSE; + m_extra_cache_size= 0; + m_extra_prepare_for_update= FALSE; + m_extra_cache_part_id= NO_CURRENT_PART_ID; + DBUG_RETURN(ret); + } case HA_EXTRA_WRITE_CACHE: { m_extra_cache= FALSE; m_extra_cache_size= 0; + m_extra_prepare_for_update= FALSE; + m_extra_cache_part_id= NO_CURRENT_PART_ID; DBUG_RETURN(loop_extra(operation)); } case HA_EXTRA_IGNORE_NO_KEY: @@ -5703,6 +5751,7 @@ int ha_partition::extra_opt(enum ha_extra_function operation, ulong cachesize) void ha_partition::prepare_extra_cache(uint cachesize) { DBUG_ENTER("ha_partition::prepare_extra_cache()"); + DBUG_PRINT("info", ("cachesize %u", cachesize)); m_extra_cache= TRUE; m_extra_cache_size= cachesize; @@ -5761,16 +5810,18 @@ int ha_partition::loop_extra(enum ha_extra_function operation) { int result= 0, tmp; handler **file; + bool is_select; DBUG_ENTER("ha_partition::loop_extra()"); - /* - TODO, 5.2: this is where you could possibly add optimisations to add the - bitmap _if_ a SELECT. - */ + is_select= (thd_sql_command(ha_thd()) == SQLCOM_SELECT); for (file= m_file; *file; file++) { - if ((tmp= (*file)->extra(operation))) - result= tmp; + if (!is_select || + bitmap_is_set(&(m_part_info->used_partitions), file - m_file)) + { + if ((tmp= (*file)->extra(operation))) + result= tmp; + } } DBUG_RETURN(result); } @@ -5791,14 +5842,25 @@ void ha_partition::late_extra_cache(uint partition_id) { handler *file; DBUG_ENTER("ha_partition::late_extra_cache"); + DBUG_PRINT("info", ("extra_cache %u prepare %u partid %u size %u", + m_extra_cache, m_extra_prepare_for_update, + partition_id, m_extra_cache_size)); - if (!m_extra_cache) + if (!m_extra_cache && !m_extra_prepare_for_update) DBUG_VOID_RETURN; file= m_file[partition_id]; - if (m_extra_cache_size == 0) - VOID(file->extra(HA_EXTRA_CACHE)); - else - VOID(file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size)); + if (m_extra_cache) + { + if (m_extra_cache_size == 0) + VOID(file->extra(HA_EXTRA_CACHE)); + else + VOID(file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size)); + } + if (m_extra_prepare_for_update) + { + VOID(file->extra(HA_EXTRA_PREPARE_FOR_UPDATE)); + } + m_extra_cache_part_id= partition_id; DBUG_VOID_RETURN; } @@ -5819,10 +5881,12 @@ void ha_partition::late_extra_no_cache(uint partition_id) handler *file; DBUG_ENTER("ha_partition::late_extra_no_cache"); - if (!m_extra_cache) + if (!m_extra_cache && !m_extra_prepare_for_update) DBUG_VOID_RETURN; file= m_file[partition_id]; VOID(file->extra(HA_EXTRA_NO_CACHE)); + DBUG_ASSERT(partition_id == m_extra_cache_part_id); + m_extra_cache_part_id= NO_CURRENT_PART_ID; DBUG_VOID_RETURN; } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index e3dc7d17c6d..76b91e160ca 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -44,6 +44,7 @@ typedef struct st_partition_share typedef struct st_ha_data_partition { ulonglong next_auto_inc_val; /**< first non reserved value */ + pthread_mutex_t LOCK_auto_inc; bool auto_inc_initialized; } HA_DATA_PARTITION; @@ -154,6 +155,10 @@ private: */ bool m_extra_cache; uint m_extra_cache_size; + /* The same goes for HA_EXTRA_PREPARE_FOR_UPDATE */ + bool m_extra_prepare_for_update; + /* Which partition has active cache */ + uint m_extra_cache_part_id; void init_handler_variables(); /* @@ -944,8 +949,9 @@ private: DBUG_ASSERT(table_share->ha_data && !auto_increment_lock); if(table_share->tmp_table == NO_TMP_TABLE) { + HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data; auto_increment_lock= TRUE; - pthread_mutex_lock(&table_share->mutex); + pthread_mutex_lock(&ha_data->LOCK_auto_inc); } } virtual void unlock_auto_increment() @@ -958,7 +964,8 @@ private: */ if(auto_increment_lock && !auto_increment_safe_stmt_log_lock) { - pthread_mutex_unlock(&table_share->mutex); + HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data; + pthread_mutex_unlock(&ha_data->LOCK_auto_inc); auto_increment_lock= FALSE; } } diff --git a/sql/handler.cc b/sql/handler.cc index 7b1100ffe9d..d45692e8465 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1093,6 +1093,12 @@ int ha_commit_trans(THD *thd, bool all) my_xid xid= thd->transaction.xid_state.xid.get_my_xid(); DBUG_ENTER("ha_commit_trans"); + /* Just a random warning to test warnings pushed during autocommit. */ + DBUG_EXECUTE_IF("warn_during_ha_commit_trans", + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARNING_NOT_COMPLETE_ROLLBACK, + ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));); + /* We must not commit the normal transaction if a statement transaction is pending. Otherwise statement transaction @@ -2047,7 +2053,21 @@ handler *handler::clone(MEM_ROOT *mem_root) return new_handler; } - +double handler::keyread_time(uint index, uint ranges, ha_rows rows) +{ + /* + It is assumed that we will read trough the whole key range and that all + key blocks are half full (normally things are much better). It is also + assumed that each time we read the next key from the index, the handler + performs a random seek, thus the cost is proportional to the number of + blocks read. This model does not take into account clustered indexes - + engines that support that (e.g. InnoDB) may want to overwrite this method. + */ + double keys_per_block= (stats.block_size/2.0/ + (table->key_info[index].key_length + + ref_length) + 1); + return (rows + keys_per_block - 1)/ keys_per_block; +} void handler::ha_statistic_increment(ulong SSV::*offset) const { @@ -2617,8 +2637,18 @@ void handler::print_keydup_error(uint key_nr, const char *msg) - table->s->path - table->alias */ + +#ifndef DBUG_OFF +#define SET_FATAL_ERROR fatal_error=1 +#else +#define SET_FATAL_ERROR +#endif + void handler::print_error(int error, myf errflag) { +#ifndef DBUG_OFF + bool fatal_error= 0; +#endif DBUG_ENTER("handler::print_error"); DBUG_PRINT("enter",("error: %d",error)); @@ -2636,6 +2666,13 @@ void handler::print_error(int error, myf errflag) case HA_ERR_KEY_NOT_FOUND: case HA_ERR_NO_ACTIVE_RECORD: case HA_ERR_END_OF_FILE: + /* + This errors is not not normally fatal (for example for reads). However + if you get it during an update or delete, then its fatal. + As the user is calling print_error() (which is not done on read), we + assume something when wrong with the update or delete. + */ + SET_FATAL_ERROR; textno=ER_KEY_NOT_FOUND; break; case HA_ERR_WRONG_MRG_TABLE_DEF: @@ -2687,21 +2724,26 @@ void handler::print_error(int error, myf errflag) textno=ER_DUP_UNIQUE; break; case HA_ERR_RECORD_CHANGED: + SET_FATAL_ERROR; textno=ER_CHECKREAD; break; case HA_ERR_CRASHED: + SET_FATAL_ERROR; textno=ER_NOT_KEYFILE; break; case HA_ERR_WRONG_IN_RECORD: + SET_FATAL_ERROR; textno= ER_CRASHED_ON_USAGE; break; case HA_ERR_CRASHED_ON_USAGE: + SET_FATAL_ERROR; textno=ER_CRASHED_ON_USAGE; break; case HA_ERR_NOT_A_TABLE: textno= error; break; case HA_ERR_CRASHED_ON_REPAIR: + SET_FATAL_ERROR; textno=ER_CRASHED_ON_REPAIR; break; case HA_ERR_OUT_OF_MEM: @@ -2800,7 +2842,10 @@ void handler::print_error(int error, myf errflag) if (temporary) my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine); else + { + SET_FATAL_ERROR; my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine); + } } else my_error(ER_GET_ERRNO,errflag,error); @@ -2808,6 +2853,7 @@ void handler::print_error(int error, myf errflag) } } my_error(textno, errflag, table_share->table_name.str, error); + DBUG_ASSERT(!fatal_error || !debug_assert_if_crashed_table); DBUG_VOID_RETURN; } @@ -3686,6 +3732,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name) void st_ha_check_opt::init() { flags= sql_flags= 0; + start_time= my_time(0); } diff --git a/sql/handler.h b/sql/handler.h index 36b0bf77b7a..862da3d2ca7 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1021,6 +1021,7 @@ typedef struct st_ha_check_opt st_ha_check_opt() {} /* Remove gcc warning */ uint flags; /* isam layer flags (e.g. for myisamchk) */ uint sql_flags; /* sql layer flags - for something myisamchk cannot do */ + time_t start_time; /* When check/repair starts */ KEY_CACHE *key_cache; /* new key cache when changing key cache */ void init(); } HA_CHECK_OPT; @@ -1304,6 +1305,16 @@ public: { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; } virtual double read_time(uint index, uint ranges, ha_rows rows) { return rows2double(ranges+rows); } + + /** + Calculate cost of 'keyread' scan for given index and number of records. + + @param index index to read + @param ranges #of ranges to read + @param rows #of records to read + */ + virtual double keyread_time(uint index, uint ranges, ha_rows rows); + virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; } bool has_transactions() { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; } diff --git a/sql/item.cc b/sql/item.cc index 1c1137fa75c..08246ea14c3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7004,14 +7004,14 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) enum_field_types field_type= field->type(); - if (field_type == MYSQL_TYPE_DATE || field_type == MYSQL_TYPE_DATETIME) + if (field_type == MYSQL_TYPE_DATE || field_type == MYSQL_TYPE_DATETIME || + field_type == MYSQL_TYPE_TIMESTAMP) { enum_mysql_timestamp_type type= MYSQL_TIMESTAMP_ERROR; if (field_type == MYSQL_TYPE_DATE) type= MYSQL_TIMESTAMP_DATE; - - if (field_type == MYSQL_TYPE_DATETIME) + else type= MYSQL_TIMESTAMP_DATETIME; const char *field_name= field->field_name; @@ -7438,9 +7438,12 @@ bool Item_cache_row::null_inside() void Item_cache_row::bring_value() { + if (!example) + return; + example->bring_value(); + null_value= example->null_value; for (uint i= 0; i < item_count; i++) values[i]->bring_value(); - return; } diff --git a/sql/item.h b/sql/item.h index 05fde79ce31..474316ed25f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -488,8 +488,7 @@ public: FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM, SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER, PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM, - XPATH_NODESET, XPATH_NODESET_CMP, - VIEW_FIXER_ITEM}; + XPATH_NODESET, XPATH_NODESET_CMP}; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; @@ -2505,6 +2504,7 @@ public: { return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT; } + table_map not_null_tables() const { return 0; } virtual Ref_Type ref_type() { return OUTER_REF; } bool check_inner_refs_processor(uchar * arg); }; @@ -2907,7 +2907,8 @@ public: { return Item_field::save_in_field(field_arg, no_conversions); } - /* + enum Type type() const { return INSERT_VALUE_ITEM; } + /* We use RAND_TABLE_BIT to prevent Item_insert_value from being treated as a constant and precalculated before execution */ diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3875f73a36f..9d12c39be26 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1582,6 +1582,13 @@ int Arg_comparator::compare_row() bool was_null= 0; (*a)->bring_value(); (*b)->bring_value(); + + if ((*a)->null_value || (*b)->null_value) + { + owner->null_value= 1; + return -1; + } + uint n= (*a)->cols(); for (uint i= 0; i<n; i++) { @@ -1750,6 +1757,76 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref) } +/** + The implementation of optimized \<outer expression\> [NOT] IN \<subquery\> + predicates. The implementation works as follows. + + For the current value of the outer expression + + - If it contains only NULL values, the original (before rewrite by the + Item_in_subselect rewrite methods) inner subquery is non-correlated and + was previously executed, there is no need to re-execute it, and the + previous return value is returned. + + - If it contains NULL values, check if there is a partial match for the + inner query block by evaluating it. For clarity we repeat here the + transformation previously performed on the sub-query. The expression + + <tt> + ( oc_1, ..., oc_n ) + \<in predicate\> + ( SELECT ic_1, ..., ic_n + FROM \<table\> + WHERE \<inner where\> + ) + </tt> + + was transformed into + + <tt> + ( oc_1, ..., oc_n ) + \<in predicate\> + ( SELECT ic_1, ..., ic_n + FROM \<table\> + WHERE \<inner where\> AND ... ( ic_k = oc_k OR ic_k IS NULL ) + HAVING ... NOT ic_k IS NULL + ) + </tt> + + The evaluation will now proceed according to special rules set up + elsewhere. These rules include: + + - The HAVING NOT \<inner column\> IS NULL conditions added by the + aforementioned rewrite methods will detect whether they evaluated (and + rejected) a NULL value and if so, will cause the subquery to evaluate + to NULL. + + - The added WHERE and HAVING conditions are present only for those inner + columns that correspond to outer column that are not NULL at the moment. + + - If there is an eligible index for executing the subquery, the special + access method "Full scan on NULL key" is employed which ensures that + the inner query will detect if there are NULL values resulting from the + inner query. This access method will quietly resort to table scan if it + needs to find NULL values as well. + + - Under these conditions, the sub-query need only be evaluated in order to + find out whether it produced any rows. + + - If it did, we know that there was a partial match since there are + NULL values in the outer row expression. + + - If it did not, the result is FALSE or UNKNOWN. If at least one of the + HAVING sub-predicates rejected a NULL value corresponding to an outer + non-NULL, and hence the inner query block returns UNKNOWN upon + evaluation, there was a partial match and the result is UNKNOWN. + + - If it contains no NULL values, the call is forwarded to the inner query + block. + + @see Item_in_subselect::val_bool() + @see Item_is_not_null_test::val_int() + */ longlong Item_in_optimizer::val_int() { bool tmp; @@ -1803,7 +1880,7 @@ longlong Item_in_optimizer::val_int() all_left_cols_null= false; } - if (!((Item_in_subselect*)args[1])->is_correlated && + if (!item_subs->is_correlated && all_left_cols_null && result_for_null_param != UNKNOWN) { /* @@ -1817,8 +1894,11 @@ longlong Item_in_optimizer::val_int() else { /* The subquery has to be evaluated */ - (void) args[1]->val_bool_result(); - null_value= !item_subs->engine->no_rows(); + (void) item_subs->val_bool_result(); + if (item_subs->engine->no_rows()) + null_value= item_subs->null_value; + else + null_value= TRUE; if (all_left_cols_null) result_for_null_param= null_value; } @@ -4614,7 +4694,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref) return TRUE; } - if (escape_item->const_item()) + if (escape_item->const_item() && !thd->lex->view_prepare_mode) { /* If we are on execution stage */ String *escape_str= escape_item->val_str(&cmp.value1); @@ -5507,7 +5587,7 @@ longlong Item_equal::val_int() return 0; List_iterator_fast<Item_field> it(fields); Item *item= const_item ? const_item : it++; - if ((null_value= item->null_value)) + if ((null_value= item->is_null())) return 0; eval_item->store_value(item); while ((item_field= it++)) @@ -5515,7 +5595,7 @@ longlong Item_equal::val_int() /* Skip fields of non-const tables. They haven't been read yet */ if (item_field->field->table->const_table) { - if ((null_value= item_field->null_value) || eval_item->cmp(item_field)) + if ((null_value= item_field->is_null()) || eval_item->cmp(item_field)) return 0; } } diff --git a/sql/item_func.cc b/sql/item_func.cc index 41cdcfa4312..03a517ec33d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2262,7 +2262,7 @@ void Item_func_min_max::fix_length_and_dec() stored to the value pointer, if latter is provided. RETURN - 0 If one of arguments is NULL + 0 If one of arguments is NULL or there was a execution error # index of the least/greatest argument */ @@ -2276,6 +2276,14 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value) Item **arg= args + i; bool is_null; longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); + + /* Check if we need to stop (because of error or KILL) and stop the loop */ + if (thd->is_error()) + { + null_value= 1; + return 0; + } + if ((null_value= args[i]->null_value)) return 0; if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) @@ -2304,6 +2312,12 @@ String *Item_func_min_max::val_str(String *str) if (null_value) return 0; str_res= args[min_max_idx]->val_str(str); + if (args[min_max_idx]->null_value) + { + // check if the call to val_str() above returns a NULL value + null_value= 1; + return NULL; + } str_res->set_charset(collation.collation); return str_res; } @@ -4266,6 +4280,14 @@ longlong Item_func_set_user_var::val_int_result() return entry->val_int(&null_value); } +bool Item_func_set_user_var::val_bool_result() +{ + DBUG_ASSERT(fixed == 1); + check(TRUE); + update(); // Store expression + return entry->val_int(&null_value) != 0; +} + String *Item_func_set_user_var::str_result(String *str) { DBUG_ASSERT(fixed == 1); @@ -4643,7 +4665,7 @@ void Item_func_get_user_var::fix_length_and_dec() decimals=0; break; case STRING_RESULT: - max_length= MAX_BLOB_WIDTH; + max_length= MAX_BLOB_WIDTH - 1; break; case DECIMAL_RESULT: max_length= DECIMAL_MAX_STR_LENGTH; @@ -6103,8 +6125,8 @@ void uuid_short_init() longlong Item_func_uuid_short::val_int() { ulonglong val; - pthread_mutex_lock(&LOCK_uuid_generator); + pthread_mutex_lock(&LOCK_short_uuid_generator); val= uuid_value++; - pthread_mutex_unlock(&LOCK_uuid_generator); + pthread_mutex_unlock(&LOCK_short_uuid_generator); return (longlong) val; } diff --git a/sql/item_func.h b/sql/item_func.h index 2b466960af2..bdaa217d555 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1368,6 +1368,7 @@ public: my_decimal *val_decimal(my_decimal *); double val_result(); longlong val_int_result(); + bool val_bool_result(); String *str_result(String *str); my_decimal *val_decimal_result(my_decimal *); bool is_null_result(); diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index edbe104e307..b3ecbc39933 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -175,6 +175,21 @@ public: item_type=it; } String *val_str(String *); + void fix_length_and_dec() + { + for (unsigned int i= 0; i < arg_count; ++i) + { + if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY) + { + String str; + args[i]->print(&str, QT_ORDINARY); + str.append('\0'); + my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric", + str.ptr()); + } + } + } + const char *func_name() const { return "multipoint"; } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index a2bb91a47f5..cd854f012a8 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -48,7 +48,7 @@ Item_subselect::Item_subselect(): item value is NULL if select_subselect not changed this value (i.e. some rows will be found returned) */ - null_value= 1; + null_value= TRUE; } @@ -452,9 +452,9 @@ void Item_maxmin_subselect::print(String *str, enum_query_type query_type) void Item_singlerow_subselect::reset() { eliminated= FALSE; - null_value= 1; + null_value= TRUE; if (value) - value->null_value= 1; + value->null_value= TRUE; } @@ -591,7 +591,10 @@ bool Item_singlerow_subselect::null_inside() void Item_singlerow_subselect::bring_value() { - exec(); + if (!exec() && assigned()) + null_value= 0; + else + reset(); } double Item_singlerow_subselect::val_real() @@ -599,7 +602,7 @@ double Item_singlerow_subselect::val_real() DBUG_ASSERT(fixed == 1); if (!exec() && !value->null_value) { - null_value= 0; + null_value= FALSE; return value->val_real(); } else @@ -614,7 +617,7 @@ longlong Item_singlerow_subselect::val_int() DBUG_ASSERT(fixed == 1); if (!exec() && !value->null_value) { - null_value= 0; + null_value= FALSE; return value->val_int(); } else @@ -628,7 +631,7 @@ String *Item_singlerow_subselect::val_str(String *str) { if (!exec() && !value->null_value) { - null_value= 0; + null_value= FALSE; return value->val_str(str); } else @@ -643,7 +646,7 @@ my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value) { if (!exec() && !value->null_value) { - null_value= 0; + null_value= FALSE; return value->val_decimal(decimal_value); } else @@ -658,7 +661,7 @@ bool Item_singlerow_subselect::val_bool() { if (!exec() && !value->null_value) { - null_value= 0; + null_value= FALSE; return value->val_bool(); } else @@ -676,7 +679,7 @@ Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex): bool val_bool(); init(select_lex, new select_exists_subselect(this)); max_columns= UINT_MAX; - null_value= 0; //can't be NULL + null_value= FALSE; //can't be NULL maybe_null= 0; //can't be NULL value= 0; DBUG_VOID_RETURN; @@ -839,15 +842,14 @@ double Item_in_subselect::val_real() */ DBUG_ASSERT(0); DBUG_ASSERT(fixed == 1); - null_value= 0; + null_value= was_null= FALSE; if (exec()) { reset(); - null_value= 1; return 0; } if (was_null && !value) - null_value= 1; + null_value= TRUE; return (double) value; } @@ -860,15 +862,14 @@ longlong Item_in_subselect::val_int() */ DBUG_ASSERT(0); DBUG_ASSERT(fixed == 1); - null_value= 0; + null_value= was_null= FALSE; if (exec()) { reset(); - null_value= 1; return 0; } if (was_null && !value) - null_value= 1; + null_value= TRUE; return value; } @@ -881,16 +882,15 @@ String *Item_in_subselect::val_str(String *str) */ DBUG_ASSERT(0); DBUG_ASSERT(fixed == 1); - null_value= 0; + null_value= was_null= FALSE; if (exec()) { reset(); - null_value= 1; return 0; } if (was_null && !value) { - null_value= 1; + null_value= TRUE; return 0; } str->set((ulonglong)value, &my_charset_bin); @@ -901,20 +901,14 @@ String *Item_in_subselect::val_str(String *str) bool Item_in_subselect::val_bool() { DBUG_ASSERT(fixed == 1); - null_value= 0; + null_value= was_null= FALSE; if (exec()) { reset(); - /* - Must mark the IN predicate as NULL so as to make sure an enclosing NOT - predicate will return FALSE. See the comments in - subselect_uniquesubquery_engine::copy_ref_key for further details. - */ - null_value= 1; return 0; } if (was_null && !value) - null_value= 1; + null_value= TRUE; return value; } @@ -925,16 +919,15 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value) method should not be used */ DBUG_ASSERT(0); - null_value= 0; + null_value= was_null= FALSE; DBUG_ASSERT(fixed == 1); if (exec()) { reset(); - null_value= 1; return 0; } if (was_null && !value) - null_value= 1; + null_value= TRUE; int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value); return decimal_value; } @@ -1943,18 +1936,22 @@ int subselect_single_select_engine::exec() } if (!select_lex->uncacheable && thd->lex->describe && !(join->select_options & SELECT_DESCRIBE) && - join->need_tmp && item->const_item()) + join->need_tmp) { - /* - Force join->join_tmp creation, because this subquery will be replaced - by a simple select from the materialization temp table by optimize() - called by EXPLAIN and we need to preserve the initial query structure - so we can display it. - */ - select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; - select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; - if (join->init_save_join_tab()) - DBUG_RETURN(1); /* purecov: inspected */ + item->update_used_tables(); + if (item->const_item()) + { + /* + Force join->join_tmp creation, because this subquery will be replaced + by a simple select from the materialization temp table by optimize() + called by EXPLAIN and we need to preserve the initial query structure + so we can display it. + */ + select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; + select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; + if (join->init_save_join_tab()) + DBUG_RETURN(1); /* purecov: inspected */ + } } if (item->engine_changed) { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 45c3ee3cd20..0a51a0de5d7 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -417,26 +417,6 @@ void Item_sum::mark_as_sum_func() } -void Item_sum::make_field(Send_field *tmp_field) -{ - if (args[0]->type() == Item::FIELD_ITEM && keep_field_type()) - { - ((Item_field*) args[0])->field->make_field(tmp_field); - /* For expressions only col_name should be non-empty string. */ - char *empty_string= (char*)""; - tmp_field->db_name= empty_string; - tmp_field->org_table_name= empty_string; - tmp_field->table_name= empty_string; - tmp_field->org_col_name= empty_string; - tmp_field->col_name= name; - if (maybe_null) - tmp_field->flags&= ~NOT_NULL_FLAG; - } - else - init_make_field(tmp_field, field_type()); -} - - void Item_sum::print(String *str, enum_query_type query_type) { /* orig_args is not filled with valid values until fix_fields() */ @@ -2565,7 +2545,8 @@ bool Item_sum_count_distinct::add() if (always_null) return 0; copy_fields(tmp_table_param); - copy_funcs(tmp_table_param->items_to_copy); + if (copy_funcs(tmp_table_param->items_to_copy, table->in_use)) + return TRUE; for (Field **field=table->field ; *field ; field++) if ((*field)->is_real_null(0)) @@ -3153,7 +3134,8 @@ bool Item_func_group_concat::add() if (always_null) return 0; copy_fields(tmp_table_param); - copy_funcs(tmp_table_param->items_to_copy); + if (copy_funcs(tmp_table_param->items_to_copy, table->in_use)) + return TRUE; for (uint i= 0; i < arg_count_field; i++) { diff --git a/sql/item_sum.h b/sql/item_sum.h index ac6a56400a4..0725a754174 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -354,7 +354,6 @@ public: forced_const= TRUE; } virtual bool const_item() const { return forced_const; } - void make_field(Send_field *field); virtual void print(String *str, enum_query_type query_type); void fix_num_length_and_dec(); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 96dede612c8..443bf3faf6f 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -288,11 +288,6 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, CHARSET_INFO *cs= &my_charset_bin; DBUG_ENTER("extract_date_time"); - LINT_INIT(strict_week_number); - /* Remove valgrind varnings when using gcc 3.3 and -O1 */ - VALGRIND_OR_LINT_INIT(strict_week_number_year_type); - VALGRIND_OR_LINT_INIT(sunday_first_n_first_week_non_iso); - if (!sub_pattern_end) bzero((char*) l_time, sizeof(*l_time)); @@ -2282,8 +2277,6 @@ void Item_extract::print(String *str, enum_query_type query_type) void Item_extract::fix_length_and_dec() { - value.alloc(32); // alloc buffer - maybe_null=1; // If wrong date switch (int_type) { case INTERVAL_YEAR: max_length=4; date_value=1; break; @@ -2326,6 +2319,8 @@ longlong Item_extract::val_int() } else { + char buf[40]; + String value(buf, sizeof(buf), &my_charset_bin);; String *res= args[0]->val_str(&value); if (!res || str_to_time_with_warn(res->ptr(), res->length(), <ime)) { diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index a7a64090f6c..ef86406e1be 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -702,7 +702,6 @@ public: class Item_extract :public Item_int_func { - String value; bool date_value; public: const interval_type int_type; // keep it public @@ -881,6 +880,8 @@ public: { decimals=0; max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; + /* It returns NULL when the second argument is less or equal to 0 */ + maybe_null= 1; } longlong val_int(); }; diff --git a/sql/lock.cc b/sql/lock.cc index 1908e68dbd2..566275c5ea2 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -211,7 +211,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, for (;;) { if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, - &write_lock_used))) + &write_lock_used)) || + ! sql_lock->table_count) break; if (global_read_lock && write_lock_used && @@ -257,8 +258,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, thd_proc_info(thd, "System lock"); DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); - if (sql_lock->table_count && lock_external(thd, sql_lock->table, - sql_lock->table_count)) + if (lock_external(thd, sql_lock->table, sql_lock->table_count)) { /* Clear the lock type of all lock data to avoid reusage. */ reset_lock_data(sql_lock); @@ -279,8 +279,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, thd->lock_id)]; if (rc > 1) /* a timeout or a deadlock */ { - if (sql_lock->table_count) - VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count)); + VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count)); my_error(rc, MYF(0)); my_free((uchar*) sql_lock,MYF(0)); sql_lock= 0; @@ -388,7 +387,7 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock) if (sql_lock->table_count) VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count)); if (sql_lock->lock_count) - thr_multi_unlock(sql_lock->locks,sql_lock->lock_count); + thr_multi_unlock(sql_lock->locks,sql_lock->lock_count, 0); my_free((uchar*) sql_lock,MYF(0)); DBUG_VOID_RETURN; } @@ -418,25 +417,8 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock) uint i,found; DBUG_ENTER("mysql_unlock_read_tables"); - /* Move all write locks first */ - THR_LOCK_DATA **lock=sql_lock->locks; - for (i=found=0 ; i < sql_lock->lock_count ; i++) - { - if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ) - { - swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]); - lock++; - found++; - } - } - /* unlock the read locked tables */ - if (i != found) - { - thr_multi_unlock(lock,i-found); - sql_lock->lock_count= found; - } + /* Call external lock for all tables to be unlocked */ - /* Then do the same for the external locks */ /* Move all write locked tables first */ TABLE **table=sql_lock->table; for (i=found=0 ; i < sql_lock->table_count ; i++) @@ -455,6 +437,27 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock) VOID(unlock_external(thd,table,i-found)); sql_lock->table_count=found; } + + /* Call thr_unlock() for all tables to be unlocked */ + + /* Move all write locks first */ + THR_LOCK_DATA **lock=sql_lock->locks; + for (i=found=0 ; i < sql_lock->lock_count ; i++) + { + if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ) + { + swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]); + lock++; + found++; + } + } + /* unlock the read locked tables */ + if (i != found) + { + thr_multi_unlock(lock, i-found, 0); + sql_lock->lock_count= found; + } + /* Fix the lock positions in TABLE */ table= sql_lock->table; found= 0; @@ -582,8 +585,21 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock) if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK, &write_lock_used))) { - for (uint i=0; i < locked->lock_count; i++) - thr_abort_locks(locked->locks[i]->lock, upgrade_lock); + if (table->children_attached) + { + /* + Don't abort locks for underlying tables just because merge table + is deleted. Doing would cause anyone accessing these tables to + spin in open_table/close_table forever until lock is released. + */ + thr_multi_unlock(locked->locks, locked->lock_count, + THR_UNLOCK_UPDATE_STATUS); + } + else + { + for (uint i=0; i < locked->lock_count; i++) + thr_abort_locks(locked->locks[i]->lock, upgrade_lock); + } my_free((uchar*) locked,MYF(0)); } DBUG_VOID_RETURN; @@ -624,21 +640,36 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table) } +/** + Merge two thr_lock:s + mysql_lock_merge() + + @param a Original locks + @param b New locks + + @retval New lock structure that contains a and b + + @note + a and b are freed with my_free() +*/ + MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b) { MYSQL_LOCK *sql_lock; TABLE **table, **end_table; DBUG_ENTER("mysql_lock_merge"); + DBUG_PRINT("enter", ("a->lock_count: %u b->lock_count: %u", + a->lock_count, b->lock_count)); if (!(sql_lock= (MYSQL_LOCK*) my_malloc(sizeof(*sql_lock)+ - sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+ + sizeof(THR_LOCK_DATA*)*((a->lock_count+b->lock_count)*2) + sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME)))) DBUG_RETURN(0); // Fatal error sql_lock->lock_count=a->lock_count+b->lock_count; sql_lock->table_count=a->table_count+b->table_count; sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1); - sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count); + sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count*2); memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks)); memcpy(sql_lock->locks+a->lock_count,b->locks, b->lock_count*sizeof(*b->locks)); @@ -659,6 +690,18 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b) (*table)->lock_data_start+= a->lock_count; } + /* + Ensure that locks of the same tables share same data structures if we + reopen a table that is already open. This can happen for example with + MERGE tables. + */ + + /* Copy the lock data array. thr_merge_lock() reorders its content */ + memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks, + sql_lock->lock_count * sizeof(*sql_lock->locks)); + thr_merge_locks(sql_lock->locks + sql_lock->lock_count, + a->lock_count, b->lock_count); + /* Delete old, not needed locks */ my_free((uchar*) a,MYF(0)); my_free((uchar*) b,MYF(0)); @@ -832,7 +875,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, /* Allocating twice the number of pointers for lock data for use in - thr_mulit_lock(). This function reorders the lock data, but cannot + thr_multi_lock(). This function reorders the lock data, but cannot update the table values. So the second part of the array is copied from the first part immediately before calling thr_multi_lock(). */ @@ -1062,11 +1105,13 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use) void unlock_table_name(THD *thd, TABLE_LIST *table_list) { + DBUG_ENTER("unlock_table_name"); if (table_list->table) { hash_delete(&open_cache, (uchar*) table_list->table); broadcast_refresh(); } + DBUG_VOID_RETURN; } diff --git a/sql/log.cc b/sql/log.cc index 3b3da7adfe7..de5814d2b07 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1726,7 +1726,9 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) String log_query; if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) || - log_query.append(thd->lex->ident.str, thd->lex->ident.length)) + log_query.append("`") || + log_query.append(thd->lex->ident.str, thd->lex->ident.length) || + log_query.append("`")) DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), @@ -1748,7 +1750,9 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) { String log_query; if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) || - log_query.append(thd->lex->ident.str, thd->lex->ident.length)) + log_query.append("`") || + log_query.append(thd->lex->ident.str, thd->lex->ident.length) || + log_query.append("`")) DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), @@ -5102,71 +5106,107 @@ void sql_perror(const char *message) } +#ifdef __WIN__ +extern "C" my_bool reopen_fstreams(const char *filename, + FILE *outstream, FILE *errstream) +{ + int handle_fd; + int err_fd, out_fd; + HANDLE osfh; + + DBUG_ASSERT(filename && errstream); + + // Services don't have stdout/stderr on Windows, so _fileno returns -1. + err_fd= _fileno(errstream); + if (err_fd < 0) + { + if (!freopen(filename, "a+", errstream)) + return TRUE; + + setbuf(errstream, NULL); + err_fd= _fileno(errstream); + } + + if (outstream) + { + out_fd= _fileno(outstream); + if (out_fd < 0) + { + if (!freopen(filename, "a+", outstream)) + return TRUE; + out_fd= _fileno(outstream); + } + } + + if ((osfh= CreateFile(filename, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | + FILE_SHARE_DELETE, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) + return TRUE; + + if ((handle_fd= _open_osfhandle((intptr_t)osfh, + _O_APPEND | _O_TEXT)) == -1) + { + CloseHandle(osfh); + return TRUE; + } + + if (_dup2(handle_fd, err_fd) < 0) + { + CloseHandle(osfh); + return TRUE; + } + + if (outstream && _dup2(handle_fd, out_fd) < 0) + { + CloseHandle(osfh); + return TRUE; + } + + _close(handle_fd); + return FALSE; +} +#else +extern "C" my_bool reopen_fstreams(const char *filename, + FILE *outstream, FILE *errstream) +{ + if (outstream && !freopen(filename, "a+", outstream)) + return TRUE; + + if (errstream && !freopen(filename, "a+", errstream)) + return TRUE; + + return FALSE; +} +#endif + + /* Unfortunately, there seems to be no good way to restore the original streams upon failure. */ static bool redirect_std_streams(const char *file) { - if (freopen(file, "a+", stdout) && freopen(file, "a+", stderr)) - { - setbuf(stderr, NULL); - return FALSE; - } + if (reopen_fstreams(file, stdout, stderr)) + return TRUE; - return TRUE; + setbuf(stderr, NULL); + return FALSE; } bool flush_error_log() { - bool result=0; + bool result= 0; if (opt_error_log) { - char err_renamed[FN_REFLEN], *end; - end= strmake(err_renamed,log_error_file,FN_REFLEN-5); - strmov(end, "-old"); VOID(pthread_mutex_lock(&LOCK_error_log)); -#ifdef __WIN__ - char err_temp[FN_REFLEN+5]; - /* - On Windows is necessary a temporary file for to rename - the current error file. - */ - strxmov(err_temp, err_renamed,"-tmp",NullS); - (void) my_delete(err_temp, MYF(0)); - if (freopen(err_temp,"a+",stdout)) - { - int fd; - size_t bytes; - uchar buf[IO_SIZE]; - - if (!freopen(err_temp,"a+",stderr)) - sql_print_error("Couldn't reopen stderr"); - setbuf(stderr, NULL); - (void) my_delete(err_renamed, MYF(0)); - my_rename(log_error_file,err_renamed,MYF(0)); - redirect_std_streams(log_error_file); - - if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0) - { - while ((bytes= my_read(fd, buf, IO_SIZE, MYF(0))) && - bytes != MY_FILE_ERROR) - my_fwrite(stderr, buf, bytes, MYF(0)); - my_close(fd, MYF(0)); - } - (void) my_delete(err_temp, MYF(0)); - } - else - result= 1; -#else - my_rename(log_error_file,err_renamed,MYF(0)); - if (redirect_std_streams(log_error_file)) - result= 1; -#endif + if (redirect_std_streams(log_error_file)) + result= 1; VOID(pthread_mutex_unlock(&LOCK_error_log)); } - return result; + return result; } void MYSQL_BIN_LOG::signal_update() diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index efb92108781..5dedbfc3007 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1989,7 +1989,7 @@ extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern ulong slave_exec_mode_options; extern my_bool opt_readonly, lower_case_file_system; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; -extern my_bool opt_secure_auth; +extern my_bool opt_secure_auth, debug_assert_if_crashed_table; extern char* opt_secure_file_priv; extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements; extern my_bool sp_automatic_privileges, opt_noacl; @@ -2016,7 +2016,7 @@ extern FILE *stderror_file; extern pthread_key(MEM_ROOT**,THR_MALLOC); extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db, LOCK_mapped_file,LOCK_user_locks, LOCK_status, - LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator, + LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock, LOCK_global_system_variables, LOCK_user_conn, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1218ee666e1..c3d58349ad5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -196,6 +196,9 @@ typedef fp_except fp_except_t; # endif #endif +extern "C" my_bool reopen_fstreams(const char *filename, + FILE *outstream, FILE *errstream); + inline void setup_fpu() { #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) @@ -452,7 +455,7 @@ static pthread_cond_t COND_thread_cache, COND_flush_thread_cache; /* Global variables */ bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0; -my_bool opt_log, opt_slow_log; +my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table; ulong log_output_options; my_bool opt_log_queries_not_using_indexes= 0; bool opt_error_log= IF_WIN(1,0); @@ -690,7 +693,7 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_global_system_variables, LOCK_user_conn, LOCK_slave_list, LOCK_active_mi, - LOCK_connection_count, LOCK_uuid_generator; + LOCK_connection_count, LOCK_short_uuid_generator; /** The below lock protects access to two global server variables: max_prepared_stmt_count and prepared_stmt_count. These variables @@ -790,7 +793,7 @@ bool mysqld_embedded=1; static my_bool plugins_are_initialized= FALSE; #ifndef DBUG_OFF -static const char* default_dbug_option; +static const char* default_dbug_option, *current_dbug_option; #endif #ifdef HAVE_LIBWRAP const char *libwrapName= NULL; @@ -1029,8 +1032,9 @@ static void close_connections(void) Events::deinit(); end_slave(); - if (thread_count) - sleep(2); // Give threads time to die + /* Give threads time to die. */ + for (int i= 0; thread_count && i < 100; i++) + my_sleep(20000); /* Force remaining threads to die by closing the connection to the client @@ -1402,6 +1406,7 @@ void clean_up(bool print_message) #ifdef HAVE_REPLICATION end_slave_list(); #endif + my_uuid_end(); delete binlog_filter; delete rpl_filter; #ifndef EMBEDDED_LIBRARY @@ -1508,7 +1513,7 @@ static void clean_up_mutexes() (void) rwlock_destroy(&LOCK_sys_init_connect); (void) rwlock_destroy(&LOCK_sys_init_slave); (void) pthread_mutex_destroy(&LOCK_global_system_variables); - (void) pthread_mutex_destroy(&LOCK_uuid_generator); + (void) pthread_mutex_destroy(&LOCK_short_uuid_generator); (void) rwlock_destroy(&LOCK_system_variables_hash); (void) pthread_mutex_destroy(&LOCK_global_read_lock); (void) pthread_mutex_destroy(&LOCK_prepared_stmt_count); @@ -3752,7 +3757,7 @@ static int init_thread_environment() (void) my_rwlock_init(&LOCK_system_variables_hash, NULL); (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST); #ifdef HAVE_OPENSSL (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST); @@ -3963,14 +3968,15 @@ static int init_server_components() opt_error_log= 1; // Too long file name else { + my_bool res; #ifndef EMBEDDED_LIBRARY - if (freopen(log_error_file, "a+", stdout)) + res= reopen_fstreams(log_error_file, stdout, stderr); +#else + res= reopen_fstreams(log_error_file, NULL, stderr); #endif - { - if (!(freopen(log_error_file, "a+", stderr))) - sql_print_warning("Couldn't reopen stderr"); + + if (!res) setbuf(stderr, NULL); - } } } @@ -4620,11 +4626,8 @@ we force server id to 2, but this MySQL server will not act as a slave."); #ifdef __WIN__ if (!opt_console) { - if (!freopen(log_error_file,"a+",stdout) || - !freopen(log_error_file,"a+",stderr)) - { - sql_print_warning("Couldn't reopen stdout or stderr"); - } + if (reopen_fstreams(log_error_file, stdout, stderr)) + unireg_abort(1); setbuf(stderr, NULL); FreeConsole(); // Remove window } @@ -5961,7 +5964,7 @@ enum options_mysqld OPT_SECURE_FILE_PRIV, OPT_MIN_EXAMINED_ROW_LIMIT, OPT_LOG_SLOW_SLAVE_STATEMENTS, - OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_OLD_MODE, + OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_DEBUG_ASSERT_IF_CRASHED_TABLE, OPT_OLD_MODE, OPT_TEST_IGNORE_WRONG_OPTIONS, OPT_TEST_RESTART, #if defined(ENABLED_DEBUG_SYNC) OPT_DEBUG_SYNC_TIMEOUT, @@ -6122,14 +6125,18 @@ struct my_option my_long_options[] = &max_system_variables.wt_timeout_long, 0, GET_ULONG, REQUIRED_ARG, 50000000, 0, ULONG_MAX, 0, 0, 0}, #ifndef DBUG_OFF - {"debug", '#', "Debug log.", &default_dbug_option, - &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Debug log.", ¤t_dbug_option, + ¤t_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"debug-crc-break", OPT_DEBUG_CRC, "Call my_debug_put_break_here() if crc matches this number (for debug).", &opt_my_crc_dbug_check, &opt_my_crc_dbug_check, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~(ulong) 0L, 0, 0, 0}, {"debug-flush", OPT_DEBUG_FLUSH, "Default debug log with flush after write", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-assert-if-crashed-table", OPT_DEBUG_ASSERT_IF_CRASHED_TABLE, + "Do an assert in handler::print_error() if we get a crashed table", + &debug_assert_if_crashed_table, &debug_assert_if_crashed_table, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD, "Set the default character set (deprecated option, use --character-set-server instead).", @@ -6451,7 +6458,7 @@ each time the SQL thread starts.", 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, #endif {"myisam-recover", OPT_MYISAM_RECOVER, - "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.", + "Syntax: myisam-recover=OFF or myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, BACKUP_ALL, FORCE or QUICK.", &myisam_recover_options_str, &myisam_recover_options_str, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE @@ -7498,7 +7505,11 @@ thread is in the relay logs.", 1024, 0}, {"thread_handling", OPT_THREAD_HANDLING, "Define threads usage for handling queries: " - "one-thread-per-connection or no-threads.", + "one-thread-per-connection" +#if HAVE_POOL_OF_THREADS == 1 + ", pool-of-threads" +#endif + "or no-threads.", &opt_thread_handling, &opt_thread_handling, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT, @@ -7928,6 +7939,7 @@ SHOW_VAR status_vars[]= { {"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG}, {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG}, {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG}, + {"Key_blocks_warm", (char*) offsetof(KEY_CACHE, warm_blocks), SHOW_KEY_CACHE_LONG}, {"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG}, {"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG}, {"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG}, @@ -8260,6 +8272,7 @@ static int mysql_init_variables(void) #ifndef DBUG_OFF default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace", "d:t:i:o,/tmp/mysqld.trace"); + current_dbug_option= default_dbug_option; #endif opt_error_log= IF_WIN(1,0); #ifdef COMMUNITY_SERVER diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 4796a5601bf..ff426a4a608 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -168,7 +168,17 @@ my_bool net_realloc(NET *net, size_t length) DBUG_ENTER("net_realloc"); DBUG_PRINT("enter",("length: %lu", (ulong) length)); - if (length >= net->max_packet_size) + /* + When compression is off, net->where_b is always 0. + With compression turned on, net->where_b may indicate + that we still have a piece of the previous logical + packet in the buffer, unprocessed. Take it into account + when checking that max_allowed_packet is not exceeded. + This ensures that the client treats max_allowed_packet + limit identically, regardless of compression being on + or off. + */ + if (length >= (net->max_packet_size + net->where_b)) { DBUG_PRINT("error", ("Packet too large. Max size: %lu", net->max_packet_size)); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index acff21c55d5..9e3206900f8 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -709,8 +709,6 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, double read_time); static TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree); -static double get_index_only_read_time(const PARAM* param, ha_rows records, - int keynr); #ifndef DBUG_OFF static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, @@ -2315,9 +2313,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if (!head->covering_keys.is_clear_all()) { int key_for_use= find_shortest_key(head, &head->covering_keys); - double key_read_time= (get_index_only_read_time(¶m, records, - key_for_use) + - (double) records / TIME_FOR_COMPARE); + double key_read_time= head->file->keyread_time(key_for_use, 1, records) + + (double) records / TIME_FOR_COMPARE; DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, " "read time %g", key_for_use, key_read_time)); if (key_read_time < read_time) @@ -3938,43 +3935,6 @@ skip_to_ror_scan: DBUG_RETURN(imerge_trp); } - -/* - Calculate cost of 'index only' scan for given index and number of records. - - SYNOPSIS - get_index_only_read_time() - param parameters structure - records #of records to read - keynr key to read - - NOTES - It is assumed that we will read trough the whole key range and that all - key blocks are half full (normally things are much better). It is also - assumed that each time we read the next key from the index, the handler - performs a random seek, thus the cost is proportional to the number of - blocks read. - - TODO: - Move this to handler->read_time() by adding a flag 'index-only-read' to - this call. The reason for doing this is that the current function doesn't - handle the case when the row is stored in the b-tree (like in innodb - clustered index) -*/ - -static double get_index_only_read_time(const PARAM* param, ha_rows records, - int keynr) -{ - double read_time; - uint keys_per_block= (param->table->file->stats.block_size/2/ - (param->table->key_info[keynr].key_length+ - param->table->file->ref_length) + 1); - read_time=((double) (records+keys_per_block-1)/ - (double) keys_per_block); - return read_time; -} - - typedef struct st_ror_scan_info { uint idx; /* # of used key in param->keys */ @@ -4051,8 +4011,8 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1); } ror_scan->index_read_cost= - get_index_only_read_time(param, param->table->quick_rows[ror_scan->keynr], - ror_scan->keynr); + param->table->file->keyread_time(ror_scan->keynr, 1, + param->table->quick_rows[ror_scan->keynr]); DBUG_RETURN(ror_scan); } @@ -4887,7 +4847,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, We can resolve this by only reading through this key. 0.01 is added to avoid races between range and 'index' scan. */ - found_read_time= get_index_only_read_time(param,found_records,keynr) + + found_read_time= param->table->file->keyread_time(keynr, 1, found_records) + cpu_cost + 0.01; } else @@ -5534,7 +5494,11 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond) SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func, field_item, (Item*)(intptr)i, inv); if (inv) + { tree= !tree ? tmp : tree_or(param, tree, tmp); + if (tree == NULL) + break; + } else tree= tree_and(param, tree, tmp); } @@ -8463,9 +8427,14 @@ int QUICK_RANGE_SELECT::reset() in_range= FALSE; cur_range= (QUICK_RANGE**) ranges.buffer; - if (file->inited == handler::NONE && (error= file->ha_index_init(index,1))) - DBUG_RETURN(error); - + if (file->inited == handler::NONE) + { + if (in_ror_merged_scan) + head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap); + if ((error= file->ha_index_init(index,1))) + DBUG_RETURN(error); + } + /* Do not allocate the buffers twice. */ if (multi_range_length) { diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 3d65fa1de31..5bc16e55ec0 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -216,7 +216,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, File_option *param; DBUG_ENTER("sql_create_definition_file"); DBUG_PRINT("enter", ("Dir: %s, file: %s, base 0x%lx", - dir ? dir->str : "(null)", + dir ? dir->str : "", file_name->str, (ulong) base)); if (dir) diff --git a/sql/protocol.cc b/sql/protocol.cc index 3df0eddea93..bd2bb0e724a 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -203,7 +203,7 @@ net_send_ok(THD *thd, NET *net= &thd->net; uchar buff[MYSQL_ERRMSG_SIZE+10],*pos; bool error= FALSE; - DBUG_ENTER("my_ok"); + DBUG_ENTER("net_send_ok"); if (! net->vio) // hack for re-parsing queries { diff --git a/sql/records.cc b/sql/records.cc index 2fc5a26a210..827450201c9 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -196,7 +196,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, tempfile= &select->file; else tempfile= table->sort.io_cache; - if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used + if (tempfile && my_b_inited(tempfile) && + !(select && select->quick)) { DBUG_PRINT("info",("using rr_from_tempfile")); info->read_record= (table->sort.addon_field ? diff --git a/sql/set_var.cc b/sql/set_var.cc index c4e41bbf261..9e5cf7ab7dd 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -4341,7 +4341,7 @@ bool sys_var_thd_dbug::update(THD *thd, set_var *var) uchar *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b) { - char buf[256]; + char buf[1024]; if (type == OPT_GLOBAL) { DBUG_EXPLAIN_INITIAL(buf, sizeof(buf)); diff --git a/sql/sp.cc b/sql/sp.cc index bcfcb0c4f36..98667f31b80 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -783,7 +783,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, { Parser_state parser_state; - if (parser_state.init(thd, defstr.c_ptr(), defstr.length())) + if (parser_state.init(thd, defstr.c_ptr_safe(), defstr.length())) { ret= SP_INTERNAL_ERROR; goto end; diff --git a/sql/spatial.cc b/sql/spatial.cc index 2305a8eb97d..8b869a5b1ca 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -528,7 +528,7 @@ uint Gis_line_string::init_from_wkb(const char *wkb, uint len, n_points= wkb_get_uint(wkb, bo); proper_length= 4 + n_points * POINT_DATA_SIZE; - if (len < proper_length || res->reserve(proper_length)) + if (!n_points || len < proper_length || res->reserve(proper_length)) return 0; res->q_append(n_points); @@ -746,7 +746,9 @@ uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, if (len < 4) return 0; - n_linear_rings= wkb_get_uint(wkb, bo); + if (!(n_linear_rings= wkb_get_uint(wkb, bo))) + return 0; + if (res->reserve(4, 512)) return 0; wkb+= 4; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 33ea834247e..2be9dcfb777 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2032,6 +2032,8 @@ static void unlink_open_merge(THD *thd, TABLE *table, TABLE ***prev_pp) Remove parent from open_tables list and close it. This includes detaching and hence clearing parent references. */ + DBUG_PRINT("info", ("Closing parent to '%s'.'%s'", + table->s->db.str, table->s->table_name.str)); close_thread_table(thd, prv_p); } } @@ -3061,8 +3063,9 @@ bool reopen_table(TABLE *table) TABLE_LIST table_list; THD *thd= table->in_use; DBUG_ENTER("reopen_table"); - DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str, - table->s->table_name.str, (long) table)); + DBUG_PRINT("tcache", ("table: '%s'.'%s' table: 0x%lx share: 0x%lx", + table->s->db.str, table->s->table_name.str, + (long) table, (long) table->s)); DBUG_ASSERT(table->s->ref_count == 0); DBUG_ASSERT(!table->sort.io_cache); @@ -3349,7 +3352,8 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old) merge_table_found= TRUE; if (!tables || (!db_stat && reopen_table(table))) { - my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), + table->alias ? table->alias : table->s->table_name.str); /* If we could not allocate 'tables', we may close open tables here. If a MERGE table is affected, detach the children first. @@ -3359,9 +3363,10 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old) that they cannot be moved into the unused_tables chain with these pointers set. */ - if (table->child_l || table->parent) - detach_merge_children(table, TRUE); - VOID(hash_delete(&open_cache,(uchar*) table)); + unlink_open_table(thd, table, 0); + /* Restart loop */ + prev= &thd->open_tables; + next= *prev; error=1; } else @@ -3396,7 +3401,7 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old) } DBUG_PRINT("tcache", ("open tables to lock: %u", (uint) (tables_ptr - tables))); - if (tables != tables_ptr) // Should we get back old locks + if (tables != tables_ptr) // Should we get back old locks { MYSQL_LOCK *lock; /* @@ -3545,7 +3550,7 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) char *key= table->s->table_cache_key.str; uint key_length= table->s->table_cache_key.length; - DBUG_PRINT("loop", ("table_name: %s", table->alias)); + DBUG_PRINT("loop", ("table_name: %s", table->alias ? table->alias : "")); HASH_SEARCH_STATE state; for (TABLE *search= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length, &state); @@ -3883,6 +3888,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list, int error; TABLE_SHARE *share; uint discover_retry_count= 0; + bool locked_table; DBUG_ENTER("open_unireg_entry"); safe_mutex_assert_owner(&LOCK_open); @@ -4003,8 +4009,10 @@ retry: } if (!entry->s || !entry->s->crashed) goto err; - // Code below is for repairing a crashed file - if ((error= lock_table_name(thd, table_list, TRUE))) + + // Code below is for repairing a crashed file + locked_table= table_list->table != 0; + if (! locked_table && (error= lock_table_name(thd, table_list, TRUE))) { if (error < 0) goto err; @@ -4038,12 +4046,13 @@ retry: else thd->clear_error(); // Clear error message pthread_mutex_lock(&LOCK_open); - unlock_table_name(thd, table_list); + if (!locked_table) + unlock_table_name(thd, table_list); if (error) goto err; break; - } + } if (Table_triggers_list::check_n_load(thd, share->db.str, share->table_name.str, entry, 0)) @@ -4271,7 +4280,6 @@ void detach_merge_children(TABLE *table, bool clear_refs) { TABLE_LIST *child_l; TABLE *parent= table->child_l ? table : table->parent; - bool first_detach; DBUG_ENTER("detach_merge_children"); /* Either table->child_l or table->parent must be set. Parent must have @@ -4289,7 +4297,7 @@ void detach_merge_children(TABLE *table, bool clear_refs) children attached yet. Also this is called for every child and the parent from close_thread_tables(). */ - if ((first_detach= parent->children_attached)) + if (parent->children_attached) { VOID(parent->file->extra(HA_EXTRA_DETACH_CHILDREN)); parent->children_attached= FALSE; @@ -4301,38 +4309,50 @@ void detach_merge_children(TABLE *table, bool clear_refs) if (clear_refs) { - /* In any case clear the own parent reference. (***) */ - table->parent= NULL; + if (table->parent) + { + /* In any case clear the own parent reference. (***) */ + table->parent= NULL; + table->file->extra(HA_EXTRA_DETACH_CHILD); + } /* - On the first detach, clear all references. If this table is the - parent, we still may need to clear the child references. The first - detach might not have done this. + Clear all references. If this table is the parent, we still may + need to clear the child references. The first detach might not + have done this. */ - if (first_detach || (table == parent)) + for (child_l= parent->child_l; ; child_l= child_l->next_global) { - /* Clear TABLE references to force new assignment at next open. */ - for (child_l= parent->child_l; ; child_l= child_l->next_global) + /* + Do not DBUG_ASSERT(child_l->table); open_tables might be + incomplete or we may have been called twice. + + Clear the parent reference of the children only on the first + detach. The children might already be closed. They will clear + it themselves when this function is called for them with + 'clear_refs' true. See above "(***)". + */ + if (child_l->table) { + if (child_l->table->parent) + { + child_l->table->parent= NULL; + if (child_l->table->db_stat) + child_l->table->file->extra(HA_EXTRA_DETACH_CHILD); + } /* - Do not DBUG_ASSERT(child_l->table); open_tables might be - incomplete. - - Clear the parent reference of the children only on the first - detach. The children might already be closed. They will clear - it themseves when this function is called for them with - 'clear_refs' true. See above "(***)". + Set alias to "" to ensure that table is not used if we are in + LOCK TABLES */ - if (first_detach && child_l->table) - child_l->table->parent= NULL; + ((char*) child_l->table->alias)[0]= 0; /* Clear the table reference to force new assignment at next open. */ child_l->table= NULL; - - /* Break when this was the last child. */ - if (&child_l->next_global == parent->child_last_l) - break; } + + /* Break when this was the last child. */ + if (&child_l->next_global == parent->child_last_l) + break; } } @@ -5129,9 +5149,11 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags) static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table) { + DBUG_ENTER("mark_real_tables_as_free_for_reuse"); for (; table; table= table->next_global) if (!table->placeholder()) table->table->query_id= 0; + DBUG_VOID_RETURN; } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index cde040a88a4..ea402a7dc05 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1349,6 +1349,57 @@ end: } +#ifndef EMBEDDED_LIBRARY +/** + Send a single memory block from the query cache. + + Respects the client/server protocol limits for the + size of the network packet, and splits a large block + in pieces to ensure that individual piece doesn't exceed + the maximal allowed size of the network packet (16M). + + @param[in] net NET handler + @param[in] packet packet to send + @param[in] len packet length + + @return Operation status + @retval FALSE On success + @retval TRUE On error +*/ +static bool +send_data_in_chunks(NET *net, const uchar *packet, ulong len) +{ + /* + On the client we may require more memory than max_allowed_packet + to keep, both, the truncated last logical packet, and the + compressed next packet. This never (or in practice never) + happens without compression, since without compression it's very + unlikely that a) a truncated logical packet would remain on the + client when it's time to read the next packet b) a subsequent + logical packet that is being read would be so large that + size-of-new-packet + size-of-old-packet-tail > + max_allowed_packet. To remedy this issue, we send data in 1MB + sized packets, that's below the current client default of 16MB + for max_allowed_packet, but large enough to ensure there is no + unnecessary overhead from too many syscalls per result set. + */ + static const ulong MAX_CHUNK_LENGTH= 1024*1024; + + while (len > MAX_CHUNK_LENGTH) + { + if (net_real_write(net, packet, MAX_CHUNK_LENGTH)) + return TRUE; + packet+= MAX_CHUNK_LENGTH; + len-= MAX_CHUNK_LENGTH; + } + if (len && net_real_write(net, packet, len)) + return TRUE; + + return FALSE; +} +#endif + + /* Check if the query is in the cache. If it was cached, send it to the user. @@ -1660,11 +1711,11 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", ALIGN_SIZE(sizeof(Query_cache_result))))); Query_cache_result *result = result_block->result(); - if (net_real_write(&thd->net, result->data(), - result_block->used - - result_block->headers_len() - - ALIGN_SIZE(sizeof(Query_cache_result)))) - break; // Client aborted + if (send_data_in_chunks(&thd->net, result->data(), + result_block->used - + result_block->headers_len() - + ALIGN_SIZE(sizeof(Query_cache_result)))) + break; // Client aborted result_block = result_block->next; thd->net.pkt_nr= query->last_pkt_nr; // Keep packet number updated } while (result_block != first_result_block); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2b102e47abe..cad6e920b6c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -91,7 +91,9 @@ extern "C" void free_user_var(user_var_entry *entry) bool Key_part_spec::operator==(const Key_part_spec& other) const { - return length == other.length && !strcmp(field_name, other.field_name); + return length == other.length && + !my_strcasecmp(system_charset_info, field_name, + other.field_name); } /** @@ -273,7 +275,7 @@ const char *set_thd_proc_info(THD *thd, const char *info, const char *old_info= thd->proc_info; DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line, - (info != NULL) ? info : "(null)")); + (info != NULL) ? info : "")); #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) thd->profiling.status_change(info, calling_function, calling_file, calling_line); #endif diff --git a/sql/sql_class.h b/sql/sql_class.h index 7f3be97fe91..fd47de29a63 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1211,6 +1211,13 @@ public: return m_total_warn_count; } + /* Used to count any warnings pushed after calling set_ok_status(). */ + void increment_warning() + { + if (m_status != DA_EMPTY) + m_total_warn_count++; + } + Diagnostics_area() { reset_diagnostics_area(); } private: @@ -2642,7 +2649,9 @@ public: class select_insert :public select_result_interceptor { - public: +protected: + virtual int write_to_binlog(bool is_trans, int errcode); +public: TABLE_LIST *table_list; TABLE *table; List<Item> *fields; @@ -2678,6 +2687,8 @@ class select_create: public select_insert { MYSQL_LOCK *m_lock; /* m_lock or thd->extra_lock */ MYSQL_LOCK **m_plock; + + virtual int write_to_binlog(bool is_trans, int errcode); public: select_create (TABLE_LIST *table_arg, HA_CREATE_INFO *create_info_par, @@ -2693,7 +2704,7 @@ public: {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - int binlog_show_create_table(TABLE **tables, uint count); + int binlog_show_create_table(TABLE **tables, uint count, int errcode); void store_values(List<Item> &values); void send_error(uint errcode,const char *err); bool send_eof(); @@ -2990,7 +3001,7 @@ public: ulonglong max_in_memory_size) { register ulonglong max_elems_in_tree= - (1 + max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size)); + max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size); return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree)); } diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 9ea7facbe41..835e60cd6ba 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -159,6 +159,8 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, } thd->warn_count[(uint) level]++; thd->total_warn_count++; + /* Make sure we also count warnings pushed after calling set_ok_status(). */ + thd->main_da.increment_warning(); DBUG_RETURN(err); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index e23f2f86b82..37cc20a07e7 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2993,6 +2993,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) we are fixing fields from insert list. */ lex->current_select= &lex->select_lex; + + /* Errors during check_insert_fields() should not be ignored. */ + lex->current_select->no_error= FALSE; res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) || check_insert_fields(thd, table_list, *fields, values, !insert_into_view, 1, &map)); @@ -3296,7 +3299,7 @@ bool select_insert::send_eof() /* Write to binlog before commiting transaction. No statement will - be written by the binlog_query() below in RBR mode. All the + be written by the write_to_binlog() below in RBR mode. All the events are in the transaction cache and will be written when ha_autocommit_or_rollback() is issued below. */ @@ -3308,9 +3311,8 @@ bool select_insert::send_eof() thd->clear_error(); else errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); - if (thd->binlog_query(THD::ROW_QUERY_TYPE, - thd->query(), thd->query_length(), - trans_table, FALSE, errcode)) + + if (write_to_binlog(trans_table, errcode)) { table->file->ha_release_auto_increment(); DBUG_RETURN(1); @@ -3384,9 +3386,7 @@ void select_insert::abort() { { int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); /* error of writing binary log is ignored */ - (void) thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(), - thd->query_length(), - transactional_table, FALSE, errcode); + write_to_binlog(transactional_table, errcode); } if (!thd->current_stmt_binlog_row_based && !can_rollback_data()) thd->transaction.all.modified_non_trans_table= TRUE; @@ -3401,6 +3401,103 @@ void select_insert::abort() { DBUG_VOID_RETURN; } +int select_insert::write_to_binlog(bool is_trans, int errcode) +{ + /* It is only for statement mode */ + if (thd->current_stmt_binlog_row_based) + return 0; + + return thd->binlog_query(THD::ROW_QUERY_TYPE, + thd->query(), thd->query_length(), + is_trans, FALSE, errcode); +} + +/* Override the select_insert::write_to_binlog */ +int select_create::write_to_binlog(bool is_trans, int errcode) +{ + /* It is only for statement mode */ + if (thd->current_stmt_binlog_row_based) + return 0; + + /* + WL#5370 Keep the compatibility between 5.1 master and 5.5 slave. + Binlog a 'INSERT ... SELECT' statement only when it has the option + 'IF NOT EXISTS' and the table already exists as a base table. + */ + if ((create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) && + create_info->table_existed) + { + String query; + int result; + + thd->binlog_start_trans_and_stmt(); + /* Binlog the CREATE TABLE IF NOT EXISTS statement */ + result= binlog_show_create_table(&table, 1, 0); + if (result) + return result; + + uint db_len= strlen(create_table->db); + uint table_len= strlen(create_info->alias); + uint select_len= thd->query_length() - thd->lex->create_select_pos; + uint field_len= (table->s->fields - (field - table->field)) * + (MAX_FIELD_NAME + 3); + + /* + pre-allocating memory reduces the times of reallocating memory, + when calling query.appen(). + 40bytes is enough for other words("INSERT IGNORE INTO", etc.). + */ + if (query.real_alloc(40 + db_len + table_len + field_len + select_len)) + return 1; + + if (thd->lex->create_select_in_comment) + query.append(STRING_WITH_LEN("/*! ")); + if (thd->lex->ignore) + query.append(STRING_WITH_LEN("INSERT IGNORE INTO `")); + else if (thd->lex->duplicates == DUP_REPLACE) + query.append(STRING_WITH_LEN("REPLACE INTO `")); + else + query.append(STRING_WITH_LEN("INSERT INTO `")); + + query.append(create_table->db, db_len); + query.append(STRING_WITH_LEN("`.`")); + query.append(create_info->alias, table_len); + query.append(STRING_WITH_LEN("` ")); + + /* + The insert items. + Field is the the rightmost columns that the rows are inster in. + */ + query.append(STRING_WITH_LEN("(")); + for (Field **f= field ; *f ; f++) + { + if (f != field) + query.append(STRING_WITH_LEN(",")); + + query.append(STRING_WITH_LEN("`")); + query.append((*f)->field_name, strlen((*f)->field_name)); + query.append(STRING_WITH_LEN("`")); + } + query.append(STRING_WITH_LEN(") ")); + + /* The SELECT clause*/ + DBUG_ASSERT(thd->lex->create_select_pos); + if (thd->lex->create_select_start_with_brace) + query.append(STRING_WITH_LEN("(")); + if (query.append(thd->query() + thd->lex->create_select_pos, select_len)) + return 1; + + /* + Avoid to use thd->binlog_query() twice, otherwise it will print the unsafe + warning twice. + */ + Query_log_event ev(thd, query.c_ptr_safe(), query.length(), is_trans, + FALSE, errcode); + return mysql_bin_log.write(&ev); + } + else + return select_insert::write_to_binlog(is_trans, errcode); +} /*************************************************************************** CREATE TABLE (SELECT) ... @@ -3650,7 +3747,8 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) !table->s->tmp_table && !ptr->get_create_info()->table_existed) { - if (int error= ptr->binlog_show_create_table(tables, count)) + int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); + if (int error= ptr->binlog_show_create_table(tables, count, errcode)) return error; } return 0; @@ -3691,7 +3789,10 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), create_table->table_name); if (thd->current_stmt_binlog_row_based) - binlog_show_create_table(&(create_table->table), 1); + { + int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); + binlog_show_create_table(&(create_table->table), 1, errcode); + } table= create_table->table; } else @@ -3759,10 +3860,10 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) } int -select_create::binlog_show_create_table(TABLE **tables, uint count) +select_create::binlog_show_create_table(TABLE **tables, uint count, int errcode) { /* - Note 1: In RBR mode, we generate a CREATE TABLE statement for the + Note 1: We generate a CREATE TABLE statement for the created table by calling store_create_info() (behaves as SHOW CREATE TABLE). In the event of an error, nothing should be written to the binary log, even if the table is non-transactional; @@ -3778,7 +3879,6 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) schema that will do a close_thread_tables(), destroying the statement transaction cache. */ - DBUG_ASSERT(thd->current_stmt_binlog_row_based); DBUG_ASSERT(tables && *tables && count > 0); char buf[2048]; @@ -3796,7 +3896,6 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) if (mysql_bin_log.is_open()) { - int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); result= thd->binlog_query(THD::STMT_QUERY_TYPE, query.ptr(), query.length(), /* is_trans */ TRUE, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 87d6403710a..3d5e1cf60bf 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1816,6 +1816,23 @@ typedef struct st_lex : public Query_tables_list */ bool protect_against_global_read_lock; + /* + The following three variables are used in 'CREATE TABLE IF NOT EXISTS ... + SELECT' statement. They are used to binlog the statement. + + create_select_start_with_brace will be set if there is a '(' before + the first SELECT clause + + create_select_pos records the relative position of the SELECT clause + in the whole statement. + + create_select_in_comment will be set if SELECT keyword is in conditional + comment. + */ + bool create_select_start_with_brace; + uint create_select_pos; + bool create_select_in_comment; + st_lex(); virtual ~st_lex() diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 1b7f690259a..a909335bfa7 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -141,6 +141,14 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, bool transactional_table; DBUG_ENTER("mysql_load"); + /* + Bug #34283 + mysqlbinlog leaves tmpfile after termination if binlog contains + load data infile, so in mixed mode we go to row-based for + avoiding the problem. + */ + thd->set_current_stmt_binlog_row_based_if_mixed(); + #ifdef EMBEDDED_LIBRARY read_file_from_client = 0; //server is always in the same process #endif @@ -1139,7 +1147,7 @@ READ_INFO::~READ_INFO() if (need_end_io_cache) ::end_io_cache(&cache); } - my_free((uchar*) buffer,MYF(MY_ALLOW_ZERO_PTR)); + my_free(buffer, MYF(MY_ALLOW_ZERO_PTR)); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0148854165e..db96b6fc9a2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -48,6 +48,9 @@ "FUNCTION" : "PROCEDURE") static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables); +static bool execute_show_status(THD *thd, TABLE_LIST *all_tables); +static bool execute_rename_table(THD *thd, TABLE_LIST *first_table, + TABLE_LIST *all_tables); static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); const char *any_db="*any*"; // Special symbol for check_access @@ -997,7 +1000,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, NET *net= &thd->net; bool error= 0; DBUG_ENTER("dispatch_command"); - DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command)); + DBUG_PRINT("info", ("command: %d", command)); thd->command=command; /* @@ -1125,7 +1128,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, Cast *passwd to an unsigned char, so that it doesn't extend the sign for *passwd > 127 and become 2**32-127 after casting to uint. */ - char db_buff[SAFE_NAME_LEN*2+1]; // buffer to store db in utf8 + char db_buff[SAFE_NAME_LEN+1]; // buffer to store db in utf8 char *db= passwd; char *save_db; /* @@ -1556,7 +1559,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif case COM_STATISTICS: { - STATUS_VAR current_global_status_var; + STATUS_VAR *current_global_status_var; // Big; Don't allocate on stack ulong uptime; #if defined(SAFEMALLOC) || !defined(EMBEDDED_LIBRARY) uint length; @@ -1565,9 +1568,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char buff[250]; uint buff_len= sizeof(buff); + if (!(current_global_status_var= (STATUS_VAR*) + thd->alloc(sizeof(STATUS_VAR)))) + break; general_log_print(thd, command, NullS); status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]); - calc_sum_of_all_status(¤t_global_status_var); + calc_sum_of_all_status(current_global_status_var); if (!(uptime= (ulong) (thd->start_time - server_start_time))) queries_per_second1000= 0; else @@ -1582,8 +1588,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, "Open tables: %u Queries per second avg: %u.%u", uptime, (int) thread_count, (ulong) thd->query_id, - current_global_status_var.long_query_count, - current_global_status_var.opened_tables, + current_global_status_var->long_query_count, + current_global_status_var->opened_tables, refresh_version, cached_open_tables(), (uint) (queries_per_second1000 / 1000), @@ -2285,22 +2291,7 @@ mysql_execute_command(THD *thd) break; case SQLCOM_SHOW_STATUS: { - system_status_var old_status_var= thd->status_var; - thd->initial_status_var= &old_status_var; - if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))) - res= execute_sqlcom_select(thd, all_tables); - /* Don't log SHOW STATUS commands to slow query log */ - thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | - SERVER_QUERY_NO_GOOD_INDEX_USED); - /* - restore status variables, as we don't want 'show status' to cause - changes - */ - pthread_mutex_lock(&LOCK_status); - add_diff_to_status(&global_status_var, &thd->status_var, - &old_status_var); - thd->status_var= old_status_var; - pthread_mutex_unlock(&LOCK_status); + execute_show_status(thd, all_tables); break; } case SQLCOM_SHOW_DATABASES: @@ -2767,6 +2758,25 @@ mysql_execute_command(THD *thd) { TABLE_LIST *duplicate; create_table= lex->unlink_first_table(&link_to_local); + + if (create_table->view) + { + if (create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_TABLE_EXISTS_ERROR, + ER(ER_TABLE_EXISTS_ERROR), + create_info.alias); + my_ok(thd); + } + else + { + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_info.alias); + res= 1; + } + goto end_with_restore_list; + } + if ((duplicate= unique_table(thd, create_table, select_tables, 0))) { update_non_unique_table_error(create_table, "CREATE", duplicate); @@ -3005,31 +3015,7 @@ end_with_restore_list: } case SQLCOM_RENAME_TABLE: { - DBUG_ASSERT(first_table == all_tables && first_table != 0); - TABLE_LIST *table; - for (table= first_table; table; table= table->next_local->next_local) - { - if (check_access(thd, ALTER_ACL | DROP_ACL, table->db, - &table->grant.privilege,0,0, test(table->schema_table)) || - check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db, - &table->next_local->grant.privilege, 0, 0, - test(table->next_local->schema_table))) - goto error; - TABLE_LIST old_list, new_list; - /* - we do not need initialize old_list and new_list because we will - come table[0] and table->next[0] there - */ - old_list= table[0]; - new_list= table->next_local[0]; - if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) || - (!test_all_bits(table->next_local->grant.privilege, - INSERT_ACL | CREATE_ACL) && - check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0))) - goto error; - } - - if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0)) + if (execute_rename_table(thd, first_table, all_tables)) goto error; break; } @@ -5172,6 +5158,62 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) } +static bool execute_show_status(THD *thd, TABLE_LIST *all_tables) +{ + bool res; + system_status_var old_status_var= thd->status_var; + thd->initial_status_var= &old_status_var; + if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))) + res= execute_sqlcom_select(thd, all_tables); + /* Don't log SHOW STATUS commands to slow query log */ + thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | + SERVER_QUERY_NO_GOOD_INDEX_USED); + /* + restore status variables, as we don't want 'show status' to cause + changes + */ + pthread_mutex_lock(&LOCK_status); + add_diff_to_status(&global_status_var, &thd->status_var, + &old_status_var); + thd->status_var= old_status_var; + pthread_mutex_unlock(&LOCK_status); + return res; +} + + +static bool execute_rename_table(THD *thd, TABLE_LIST *first_table, + TABLE_LIST *all_tables) +{ + DBUG_ASSERT(first_table == all_tables && first_table != 0); + TABLE_LIST *table; + for (table= first_table; table; table= table->next_local->next_local) + { + if (check_access(thd, ALTER_ACL | DROP_ACL, table->db, + &table->grant.privilege,0,0, test(table->schema_table)) || + check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db, + &table->next_local->grant.privilege, 0, 0, + test(table->next_local->schema_table))) + return 1; + TABLE_LIST old_list, new_list; + /* + we do not need initialize old_list and new_list because we will + come table[0] and table->next[0] there + */ + old_list= table[0]; + new_list= table->next_local[0]; + if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) || + (!test_all_bits(table->next_local->grant.privilege, + INSERT_ACL | CREATE_ACL) && + check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0))) + return 1; + } + + if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0)) + return 1; + return 0; +} + + #ifndef NO_EMBEDDED_ACCESS_CHECKS /** Check grants for commands which work only with one table. @@ -7957,6 +7999,8 @@ bool parse_sql(THD *thd, Object_creation_ctx *creation_ctx) { bool mysql_parse_status; + DBUG_ENTER("parse_sql"); + DBUG_ASSERT(thd->m_parser_state == NULL); /* Backup creation context. */ @@ -7990,7 +8034,7 @@ bool parse_sql(THD *thd, /* That's it. */ - return mysql_parse_status || thd->is_fatal_error; + DBUG_RETURN(mysql_parse_status || thd->is_fatal_error); } /** diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index c9b73413377..ff5a37233c5 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -3446,8 +3446,7 @@ void my_print_help_inc_plugins(my_option *main_options, uint size) { p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **); - if (!p->plugin->system_vars || - !(opt= construct_help_options(&mem_root, p))) + if (!(opt= construct_help_options(&mem_root, p))) continue; /* Only options with a non-NULL comment are displayed in help text */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index cde5005b038..ffc3686fcd9 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2366,11 +2366,15 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) sl->where= sl->prep_where->copy_andor_structure(thd); sl->where->cleanup(); } + else + sl->where= NULL; if (sl->prep_having) { sl->having= sl->prep_having->copy_andor_structure(thd); sl->having->cleanup(); } + else + sl->having= NULL; DBUG_ASSERT(sl->join == 0); ORDER *order; /* Fix GROUP list */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8381e257e26..65c76c0792f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1129,29 +1129,6 @@ JOIN::optimize() conds=new Item_int((longlong) 0,1); // Always false } - /* - It's necessary to check const part of HAVING cond as there is a - chance that some cond parts may become const items after - make_join_statistics() (for example when Item is a reference to - cost table field from outer join). - - This check is performed only for those conditions which do not use - aggregate functions. In such case temporary table may not be used - and const condition elements may be lost during further having - condition transformation in JOIN::exec. - */ - if (having && const_table_map && !having->with_sum_func) - { - having->update_used_tables(); - having= remove_eq_conds(thd, having, &having_value); - if (having_value == Item::COND_FALSE) - { - having= new Item_int((longlong) 0,1); - zero_result_cause= "Impossible HAVING noticed after reading const tables"; - DBUG_RETURN(0); - } - } - if (make_join_select(this, select, conds)) { zero_result_cause= @@ -1495,6 +1472,15 @@ JOIN::optimize() if (order) { /* + Do we need a temporary table due to the ORDER BY not being equal to + the GROUP BY? The call to test_if_skip_sort_order above tests for the + GROUP BY clause only and hence is not valid in this case. So the + estimated number of rows to be read from the first table is not valid. + We clear it here so that it doesn't show up in EXPLAIN. + */ + if (need_tmp && (select_options & SELECT_DESCRIBE) != 0) + join_tab[const_tables].limit= 0; + /* Force using of tmp table if sorting by a SP or UDF function due to their expensive and probably non-deterministic nature. */ @@ -2407,14 +2393,9 @@ JOIN::destroy() cond_equal= 0; cleanup(1); - /* Cleanup items referencing temporary table columns */ - if (!tmp_all_fields3.is_empty()) - { - List_iterator_fast<Item> it(tmp_all_fields3); - Item *item; - while ((item= it++)) - item->cleanup(); - } + /* Cleanup items referencing temporary table columns */ + cleanup_item_list(tmp_all_fields1); + cleanup_item_list(tmp_all_fields3); if (exec_tmp_table1) free_tmp_table(thd, exec_tmp_table1); if (exec_tmp_table2) @@ -2425,6 +2406,19 @@ JOIN::destroy() DBUG_RETURN(error); } + +void JOIN::cleanup_item_list(List<Item> &items) const +{ + if (!items.is_empty()) + { + List_iterator_fast<Item> it(items); + Item *item; + while ((item= it++)) + item->cleanup(); + } +} + + /** An entry point to single-unit select (a select without UNION). @@ -6632,6 +6626,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (tmp_cond) { JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab; + Item **sel_cond_ref= tab < first_inner_tab ? + &first_inner_tab->on_precond : + &tab->select_cond; /* First add the guards for match variables of all embedding outer join operations. @@ -6654,14 +6651,14 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) tmp_cond->quick_fix_field(); /* Add the predicate to other pushed down predicates */ DBUG_PRINT("info", ("Item_cond_and")); - cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond : - new Item_cond_and(cond_tab->select_cond, - tmp_cond); + *sel_cond_ref= !(*sel_cond_ref) ? + tmp_cond : + new Item_cond_and(*sel_cond_ref, tmp_cond); DBUG_PRINT("info", ("Item_cond_and 0x%lx", - (ulong)cond_tab->select_cond)); - if (!cond_tab->select_cond) - DBUG_RETURN(1); - cond_tab->select_cond->quick_fix_field(); + (ulong)(*sel_cond_ref))); + if (!(*sel_cond_ref)) + DBUG_RETURN(1); + (*sel_cond_ref)->quick_fix_field(); } } first_inner_tab= first_inner_tab->first_upper; @@ -6916,6 +6913,8 @@ bool error_if_full_join(JOIN *join) { if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) { + /* This error should not be ignored. */ + join->select_lex->no_error= FALSE; my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); return(1); @@ -8984,10 +8983,10 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top) /* Flatten nested joins that can be flattened. */ TABLE_LIST *right_neighbor= NULL; - bool fix_name_res= FALSE; li.rewind(); while ((table= li++)) { + bool fix_name_res= FALSE; nested_join= table->nested_join; if (nested_join && !table->on_expr) { @@ -9315,7 +9314,10 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list, DBUG_ENTER("optimize_cond"); if (!conds) + { *cond_value= Item::COND_TRUE; + build_equal_items(join->thd, NULL, NULL, join_list, &join->cond_equal); + } else { /* @@ -11440,22 +11442,22 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) if (error == NESTED_LOOP_NO_MORE_ROWS) error= NESTED_LOOP_OK; + if (table == NULL) // If sending data to client + { + /* + The following will unlock all cursors if the command wasn't an + update command + */ + join->join_free(); // Unlock all cursors + } if (error == NESTED_LOOP_OK) { /* Sic: this branch works even if rc != 0, e.g. when send_data above returns an error. */ - if (!table) // If sending data to client - { - /* - The following will unlock all cursors if the command wasn't an - update command - */ - join->join_free(); // Unlock all cursors - if (join->result->send_eof()) - rc= 1; // Don't send error - } + if (table == NULL && join->result->send_eof()) // If sending data to client + rc= 1; // Don't send error DBUG_PRINT("info",("%ld records output", (long) join->send_records)); } else @@ -11643,7 +11645,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) return (*join_tab->next_select)(join,join_tab+1,end_of_records); int error; - enum_nested_loop_state rc; + enum_nested_loop_state rc= NESTED_LOOP_OK; READ_RECORD *info= &join_tab->read_record; if (join->resume_nested_loop) @@ -11671,11 +11673,16 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) /* Set first_unmatched for the last inner table of this group */ join_tab->last_inner->first_unmatched= join_tab; + if (join_tab->on_precond && !join_tab->on_precond->val_int()) + rc= NESTED_LOOP_NO_MORE_ROWS; } join->thd->row_count= 0; - error= (*join_tab->read_first_record)(join_tab); - rc= evaluate_join_record(join, join_tab, error); + if (rc != NESTED_LOOP_NO_MORE_ROWS) + { + error= (*join_tab->read_first_record)(join_tab); + rc= evaluate_join_record(join, join_tab, error); + } } while (rc == NESTED_LOOP_OK) @@ -11738,6 +11745,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, condition is true => a match is found. */ bool found= 1; + bool use_not_exists_opt= 0; while (join_tab->first_unmatched && found) { /* @@ -11754,7 +11762,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++) { if (tab->table->reginfo.not_exists_optimize) - return NESTED_LOOP_NO_MORE_ROWS; + use_not_exists_opt= 1; /* Check all predicates that has just been activated. */ /* Actually all predicates non-guarded by first_unmatched->found @@ -11787,6 +11795,9 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, join_tab->first_unmatched= first_unmatched; } + if (use_not_exists_opt) + return NESTED_LOOP_NO_MORE_ROWS; + /* It was not just a return to lower loop level when one of the newly activated predicates is evaluated as false @@ -12817,7 +12828,9 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (!end_of_records) { copy_fields(&join->tmp_table_param); - copy_funcs(join->tmp_table_param.items_to_copy); + if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) + DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ + #ifdef TO_BE_DELETED if (!table->uniques) // If not unique handling { @@ -12923,7 +12936,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), memcpy(table->record[0]+key_part->offset, group->buff, 1); } init_tmptable_sum_functions(join->sum_funcs); - copy_funcs(join->tmp_table_param.items_to_copy); + if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) + DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ if ((error=table->file->ha_write_row(table->record[0]))) { if (create_internal_tmp_table_from_heap(join->thd, table, @@ -12963,7 +12977,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), init_tmptable_sum_functions(join->sum_funcs); copy_fields(&join->tmp_table_param); // Groups are copied twice. - copy_funcs(join->tmp_table_param.items_to_copy); + if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) + DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ if (!(error=table->file->ha_write_row(table->record[0]))) join->send_records++; // New group @@ -13050,7 +13065,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (idx < (int) join->send_group_parts) { copy_fields(&join->tmp_table_param); - copy_funcs(join->tmp_table_param.items_to_copy); + if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd)) + DBUG_RETURN(NESTED_LOOP_ERROR); if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1])) DBUG_RETURN(NESTED_LOOP_ERROR); if (join->procedure) @@ -13347,9 +13363,20 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, } +/** + Find shortest key suitable for full table scan. + + @param table Table to scan + @param usable_keys Allowed keys + + @return + MAX_KEY no suitable key found + key index otherwise +*/ + uint find_shortest_key(TABLE *table, const key_map *usable_keys) { - uint min_length= (uint) ~0; + double min_cost= DBL_MAX; uint best= MAX_KEY; if (!usable_keys->is_clear_all()) { @@ -13357,9 +13384,10 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys) { if (usable_keys->is_set(nr)) { - if (table->key_info[nr].key_length < min_length) + double cost= table->file->keyread_time(nr, 1, table->file->records()); + if (cost < min_cost) { - min_length=table->key_info[nr].key_length; + min_cost= cost; best=nr; } } @@ -16117,14 +16145,39 @@ update_sum_func(Item_sum **func_ptr) return 0; } -/** Copy result of functions to record in tmp_table. */ +/** + Copy result of functions to record in tmp_table. -void -copy_funcs(Item **func_ptr) + Uses the thread pointer to check for errors in + some of the val_xxx() methods called by the + save_in_result_field() function. + TODO: make the Item::val_xxx() return error code + + @param func_ptr array of the function Items to copy to the tmp table + @param thd pointer to the current thread for error checking + @retval + FALSE if OK + @retval + TRUE on error +*/ + +bool +copy_funcs(Item **func_ptr, const THD *thd) { Item *func; for (; (func = *func_ptr) ; func_ptr++) + { func->save_in_result_field(1); + /* + Need to check the THD error state because Item::val_xxx() don't + return error code, but can generate errors + TODO: change it for a real status check when Item::val_xxx() + are extended to return status code. + */ + if (thd->is_error()) + return TRUE; + } + return FALSE; } @@ -16964,7 +17017,15 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (tab->select && tab->select->quick) examined_rows= tab->select->quick->records; else if (tab->type == JT_NEXT || tab->type == JT_ALL) - examined_rows= tab->limit ? tab->limit : tab->table->file->records(); + { + if (tab->limit) + examined_rows= tab->limit; + else + { + tab->table->file->info(HA_STATUS_VARIABLE); + examined_rows= tab->table->file->stats.records; + } + } else examined_rows=(ha_rows)join->best_positions[i].records_read; diff --git a/sql/sql_select.h b/sql/sql_select.h index fe3cc1af400..2a9af48f1cd 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -154,7 +154,9 @@ typedef struct st_join_table { TABLE *table; KEYUSE *keyuse; /**< pointer to first used key */ SQL_SELECT *select; - COND *select_cond; + COND *select_cond; + COND *on_precond; /**< part of on condition to check before + accessing the first inner table */ QUICK_SELECT_I *quick; Item **on_expr_ref; /**< pointer to the associated on expression */ COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */ @@ -598,6 +600,7 @@ private: */ bool implicit_grouping; bool make_simple_join(JOIN *join, TABLE *tmp_table); + void cleanup_item_list(List<Item> &items) const; }; @@ -622,7 +625,7 @@ bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, List<Item> &new_list1, List<Item> &new_list2, uint elements, List<Item> &fields); void copy_fields(TMP_TABLE_PARAM *param); -void copy_funcs(Item **func_ptr); +bool copy_funcs(Item **func_ptr, const THD *thd); bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, int error, bool ignore_last_dupp_error); uint find_shortest_key(TABLE *table, const key_map *usable_keys); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 683b0e67929..653428fa793 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3944,7 +3944,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, base_type [(dimension)] [unsigned] [zerofill]. For DATA_TYPE column we extract only base type. */ - tmp_buff= strchr(type.ptr(), '('); + tmp_buff= strchr(type.c_ptr_safe(), '('); if (!tmp_buff) /* if there is no dimention part then check the presence of @@ -6957,13 +6957,16 @@ int finalize_schema_table(st_plugin_int *plugin) ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data; DBUG_ENTER("finalize_schema_table"); - if (schema_table && plugin->plugin->deinit) + if (schema_table) { - DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str)); - if (plugin->plugin->deinit(NULL)) + if (plugin->plugin->deinit) { - DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.", - plugin->name.str)); + DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str)); + if (plugin->plugin->deinit(NULL)) + { + DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.", + plugin->name.str)); + } } my_free(schema_table, MYF(0)); } diff --git a/sql/sql_string.h b/sql/sql_string.h index 9e22f7b6a27..6eb0d74fde9 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -102,7 +102,7 @@ public: inline uint32 alloced_length() const { return Alloced_length;} inline char& operator [] (uint32 i) const { return Ptr[i]; } inline void length(uint32 len) { str_length=len ; } - inline bool is_empty() { return (str_length == 0); } + inline bool is_empty() const { return (str_length == 0); } inline void mark_as_const() { Alloced_length= 0;} inline const char *ptr() const { return Ptr; } inline char *c_ptr() diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 96be7c4437c..3760afc2b1f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3327,6 +3327,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_part_info->length=(uint16) length; /* Use packed keys for long strings on the first column */ if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) && + !((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) && (length >= KEY_DEFAULT_PACK_LENGTH && (sql_field->sql_type == MYSQL_TYPE_STRING || sql_field->sql_type == MYSQL_TYPE_VARCHAR || @@ -4427,9 +4428,6 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, pthread_mutex_unlock(&LOCK_open); } - /* A MERGE table must not come here. */ - DBUG_ASSERT(!table->child_l); - /* REPAIR TABLE ... USE_FRM for temporary tables makes little sense. */ @@ -6886,8 +6884,14 @@ view_err: Workaround InnoDB ending the transaction when the table instance is unlocked/closed (close_cached_table below), otherwise the trx state will differ between the server and storage engine layers. + + We have to unlock LOCK_open here as otherwise we can get deadlock + in wait_if_global_readlock(). This is still safe as we have a + name lock on the table object. */ + VOID(pthread_mutex_unlock(&LOCK_open)); ha_autocommit_or_rollback(thd, 0); + VOID(pthread_mutex_lock(&LOCK_open)); /* Then do a 'simple' rename of the table. First we need to close all diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index e8a382ca8f6..e32bedd80a0 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -498,9 +498,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) thd->in_lock_tables= 1; if (reopen_tables(thd, 1, 1)) { - /* To be safe remove this table from the set of LOCKED TABLES */ - unlink_open_table(thd, tables->table, FALSE); - /* Ignore reopen_tables errors for now. It's better not leave master/slave in a inconsistent state. @@ -1989,6 +1986,7 @@ bool Table_triggers_list::process_triggers(THD *thd, bool err_status; Sub_statement_state statement_state; sp_head *sp_trigger= bodies[event][time_type]; + SELECT_LEX *save_current_select; if (sp_trigger == NULL) return FALSE; @@ -2012,11 +2010,19 @@ bool Table_triggers_list::process_triggers(THD *thd, thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER); + /* + Reset current_select before call execute_trigger() and + restore it after return from one. This way error is set + in case of failure during trigger execution. + */ + save_current_select= thd->lex->current_select; + thd->lex->current_select= NULL; err_status= sp_trigger->execute_trigger(thd, &trigger_table->s->db, &trigger_table->s->table_name, &subject_table_grants[event][time_type]); + thd->lex->current_select= save_current_select; thd->restore_sub_statement_state(&statement_state); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index f6165b8d4b2..33834df3ca6 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1196,56 +1196,6 @@ reopen_tables: } -/** - Implementation of the safe update options during UPDATE IGNORE. This syntax - causes an UPDATE statement to ignore all errors. In safe update mode, - however, we must never ignore the ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE. There - is a special hook in my_message_sql that will otherwise delete all errors - when the IGNORE option is specified. - - In the future, all IGNORE handling should be used with this class and all - traces of the hack outlined below should be removed. - - - The parser detects IGNORE option and sets thd->lex->ignore= 1 - - - In JOIN::optimize, if this is set, then - thd->lex->current_select->no_error gets set. - - - In my_message_sql(), if the flag above is set then any error is - unconditionally converted to a warning. - - We are moving in the direction of using Internal_error_handler subclasses - to do all such error tweaking, please continue this effort if new bugs - appear. - */ -class Safe_dml_handler : public Internal_error_handler { - -private: - bool m_handled_error; - -public: - explicit Safe_dml_handler() : m_handled_error(FALSE) {} - - bool handle_error(uint sql_errno, - const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd) - { - if (level == MYSQL_ERROR::WARN_LEVEL_ERROR && - sql_errno == ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE) - - { - thd->main_da.set_error_status(thd, sql_errno, message); - m_handled_error= TRUE; - return TRUE; - } - return FALSE; - } - - bool handled_error() { return m_handled_error; } - -}; - /* Setup multi-update handling and call SELECT to do the join */ @@ -1275,11 +1225,6 @@ bool mysql_multi_update(THD *thd, List<Item> total_list; - Safe_dml_handler handler; - bool using_handler= thd->options & OPTION_SAFE_UPDATES; - if (using_handler) - thd->push_internal_handler(&handler); - res= mysql_select(thd, &select_lex->ref_pointer_array, table_list, select_lex->with_wild, total_list, @@ -1289,21 +1234,9 @@ bool mysql_multi_update(THD *thd, OPTION_SETUP_TABLES_DONE, result, unit, select_lex); - if (using_handler) - { - Internal_error_handler *top_handler; - top_handler= thd->pop_internal_handler(); - DBUG_ASSERT(&handler == top_handler); - } - DBUG_PRINT("info",("res: %d report_error: %d", res, (int) thd->is_error())); res|= thd->is_error(); - /* - Todo: remove below code and make Safe_dml_handler do error processing - instead. That way we can return the actual error instead of - ER_UNKNOWN_ERROR. - */ - if (unlikely(res) && (!using_handler || !handler.handled_error())) + if (unlikely(res)) { /* If we had a another error reported earlier then this will be ignored */ result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR)); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b06178b5889..f7f1e30c907 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1300,6 +1300,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <table> table_ident table_ident_nodb references xid + table_ident_opt_wild %type <simple_string> remember_name remember_end opt_ident opt_db text_or_password @@ -3886,17 +3887,26 @@ create2a: create3 {} | opt_partitioning create_select ')' - { Select->set_braces(1);} + { + Select->set_braces(1); + Lex->create_select_start_with_brace= TRUE; + } union_opt {} ; create3: /* empty */ {} | opt_duplicate opt_as create_select - { Select->set_braces(0);} + { + Select->set_braces(0); + Lex->create_select_start_with_brace= FALSE; + } union_clause {} | opt_duplicate opt_as '(' create_select ')' - { Select->set_braces(1);} + { + Select->set_braces(1); + Lex->create_select_start_with_brace= TRUE; + } union_opt {} ; @@ -4521,6 +4531,19 @@ create_select: lex->current_select->table_list.save_and_clear(&lex->save_list); mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LIST; + + if (lex->sql_command == SQLCOM_CREATE_TABLE && + (lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)) + { + Lex_input_stream *lip= YYLIP; + + if (lex->spcont) + lex->create_select_pos= lip->get_tok_start() - + lex->sphead->m_tmp_query; + else + lex->create_select_pos= lip->get_tok_start() - lip->get_buf(); + lex->create_select_in_comment= (lip->in_comment == DISCARD_COMMENT); + } } select_options select_item_list { @@ -9621,7 +9644,7 @@ table_alias_ref_list: ; table_alias_ref: - table_ident + table_ident_opt_wild { if (!Select->add_table_to_list(YYTHD, $1, NULL, TL_OPTION_UPDATING | TL_OPTION_ALIAS, @@ -11396,6 +11419,21 @@ table_ident: } ; +table_ident_opt_wild: + ident opt_wild + { + $$= new Table_ident($1); + if ($$ == NULL) + MYSQL_YYABORT; + } + | ident '.' ident opt_wild + { + $$= new Table_ident(YYTHD, $1,$3,0); + if ($$ == NULL) + MYSQL_YYABORT; + } + ; + table_ident_nodb: ident { diff --git a/sql/table.cc b/sql/table.cc index a3c6f07cddf..efbca69e67f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -425,6 +425,11 @@ void free_table_share(TABLE_SHARE *share) key_info->flags= 0; } } + if (share->ha_data_destroy) + { + share->ha_data_destroy(share->ha_data); + share->ha_data_destroy= NULL; + } /* We must copy mem_root from share because share is allocated through it */ memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root)); free_root(&mem_root, MYF(0)); // Free's share @@ -1626,6 +1631,11 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, delete crypted; delete handler_file; hash_free(&share->name_hash); + if (share->ha_data_destroy) + { + share->ha_data_destroy(share->ha_data); + share->ha_data_destroy= NULL; + } open_table_error(share, error, share->open_errno, errarg); DBUG_RETURN(error); diff --git a/sql/table.h b/sql/table.h index d0836bf5b78..828d01f3783 100644 --- a/sql/table.h +++ b/sql/table.h @@ -472,6 +472,7 @@ typedef struct st_table_share /** place to store storage engine specific data */ void *ha_data; + void (*ha_data_destroy)(void *); /* An optional destructor for ha_data. */ /* diff --git a/sql/tztime.cc b/sql/tztime.cc index cd6e63be039..1277383895a 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2259,7 +2259,7 @@ my_tz_find(THD *thd, const String *name) DBUG_PRINT("enter", ("time zone name='%s'", name ? ((String *)name)->c_ptr_safe() : "NULL")); - if (!name) + if (!name || name->is_empty()) DBUG_RETURN(0); VOID(pthread_mutex_lock(&tz_LOCK)); diff --git a/storage/archive/Makefile.am b/storage/archive/Makefile.am index 94e98c468ad..1dbe101c2d6 100644 --- a/storage/archive/Makefile.am +++ b/storage/archive/Makefile.am @@ -33,19 +33,18 @@ DEFS = @DEFS@ noinst_HEADERS = ha_archive.h azlib.h noinst_PROGRAMS = archive_test archive_reader -EXTRA_LTLIBRARIES = ha_archive.la +EXTRA_LTLIBRARIES = libarchive.la ha_archive.la pkgplugin_LTLIBRARIES = @plugin_archive_shared_target@ ha_archive_la_LDFLAGS = -module -rpath $(pkgplugindir) -ha_archive_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN -ha_archive_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_archive_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_archive_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_archive_la_SOURCES = ha_archive.cc azio.c -EXTRA_LIBRARIES = libarchive.a -noinst_LIBRARIES = @plugin_archive_static_target@ -libarchive_a_CXXFLAGS = $(AM_CXXFLAGS) -libarchive_a_CFLAGS = $(AM_CFLAGS) -libarchive_a_SOURCES = ha_archive.cc azio.c +noinst_LTLIBRARIES = @plugin_archive_static_target@ +libarchive_la_CXXFLAGS = $(AM_CXXFLAGS) +libarchive_la_CFLAGS = $(AM_CFLAGS) +libarchive_la_SOURCES = ha_archive.cc azio.c archive_test_SOURCES = archive_test.c azio.c diff --git a/storage/archive/plug.in b/storage/archive/plug.in index 52131b12e6b..d19c29414e3 100644 --- a/storage/archive/plug.in +++ b/storage/archive/plug.in @@ -1,4 +1,4 @@ MYSQL_STORAGE_ENGINE(archive,, [Archive Storage Engine], [Archive Storage Engine], [max,max-no-ndb]) -MYSQL_PLUGIN_STATIC(archive, [libarchive.a]) +MYSQL_PLUGIN_STATIC(archive, [libarchive.la]) MYSQL_PLUGIN_DYNAMIC(archive, [ha_archive.la]) diff --git a/storage/blackhole/Makefile.am b/storage/blackhole/Makefile.am index 2d27261b671..6665898cae7 100644 --- a/storage/blackhole/Makefile.am +++ b/storage/blackhole/Makefile.am @@ -32,19 +32,16 @@ DEFS = @DEFS@ noinst_HEADERS = ha_blackhole.h -EXTRA_LTLIBRARIES = ha_blackhole.la +EXTRA_LTLIBRARIES = libblackhole.la ha_blackhole.la pkgplugin_LTLIBRARIES = @plugin_blackhole_shared_target@ ha_blackhole_la_LDFLAGS=-module -rpath $(pkgplugindir) -ha_blackhole_la_CXXFLAGS=$(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN -ha_blackhole_la_CFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_blackhole_la_CXXFLAGS=-shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_blackhole_la_SOURCES=ha_blackhole.cc -EXTRA_LIBRARIES = libblackhole.a -noinst_LIBRARIES = @plugin_blackhole_static_target@ -libblackhole_a_CXXFLAGS=$(AM_CXXFLAGS) -libblackhole_a_CFLAGS = $(AM_CFLAGS) -libblackhole_a_SOURCES= ha_blackhole.cc +noinst_LTLIBRARIES = @plugin_blackhole_static_target@ +libblackhole_la_CXXFLAGS=$(AM_CXXFLAGS) +libblackhole_la_SOURCES= ha_blackhole.cc EXTRA_DIST = CMakeLists.txt plug.in diff --git a/storage/blackhole/plug.in b/storage/blackhole/plug.in index 725db0facba..2f3b120fa5d 100644 --- a/storage/blackhole/plug.in +++ b/storage/blackhole/plug.in @@ -1,6 +1,6 @@ MYSQL_STORAGE_ENGINE(blackhole,,[Blackhole Storage Engine], [Basic Write-only Read-never tables], [max,max-no-ndb]) MYSQL_PLUGIN_DIRECTORY(blackhole, [storage/blackhole]) -MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.a]) +MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.la]) MYSQL_PLUGIN_DYNAMIC(blackhole, [ha_blackhole.la]) diff --git a/storage/csv/Makefile.am b/storage/csv/Makefile.am index 3a00ae85e20..c711e4020fc 100644 --- a/storage/csv/Makefile.am +++ b/storage/csv/Makefile.am @@ -29,16 +29,15 @@ LDADD = DEFS = @DEFS@ noinst_HEADERS = ha_tina.h transparent_file.h -EXTRA_LTLIBRARIES = ha_csv.la +EXTRA_LTLIBRARIES = libcsv.la ha_csv.la pkglib_LTLIBRARIES = @plugin_csv_shared_target@ ha_csv_la_LDFLAGS = -module -rpath $(MYSQLLIBdir) -ha_csv_la_CXXFLAGS = $(AM_CXXFLAGS) -DMYSQL_PLUGIN +ha_csv_la_CXXFLAGS = -shared $(AM_CXXFLAGS) -DMYSQL_PLUGIN ha_csv_la_SOURCES = transparent_file.cc ha_tina.cc -EXTRA_LIBRARIES = libcsv.a -noinst_LIBRARIES = @plugin_csv_static_target@ -libcsv_a_CXXFLAGS = $(AM_CXXFLAGS) -libcsv_a_SOURCES = transparent_file.cc ha_tina.cc +noinst_LTLIBRARIES = @plugin_csv_static_target@ +libcsv_la_CXXFLAGS = $(AM_CXXFLAGS) +libcsv_la_SOURCES = transparent_file.cc ha_tina.cc EXTRA_DIST = CMakeLists.txt plug.in # Don't update the files from bitkeeper diff --git a/storage/csv/plug.in b/storage/csv/plug.in index bbc69680fcd..4ff32959fa2 100644 --- a/storage/csv/plug.in +++ b/storage/csv/plug.in @@ -1,5 +1,5 @@ MYSQL_STORAGE_ENGINE(csv,, [CSV Storage Engine], [Stores tables in text CSV format]) MYSQL_PLUGIN_DIRECTORY(csv, [storage/csv]) -MYSQL_PLUGIN_STATIC(csv, [libcsv.a]) +MYSQL_PLUGIN_STATIC(csv, [libcsv.la]) MYSQL_PLUGIN_MANDATORY(csv) dnl Used for logging diff --git a/storage/example/Makefile.am b/storage/example/Makefile.am index 1c87adbbb4c..da80f518d13 100644 --- a/storage/example/Makefile.am +++ b/storage/example/Makefile.am @@ -32,19 +32,16 @@ DEFS = @DEFS@ noinst_HEADERS = ha_example.h -EXTRA_LTLIBRARIES = ha_example.la +EXTRA_LTLIBRARIES = libexample.la ha_example.la pkgplugin_LTLIBRARIES = @plugin_example_shared_target@ ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -ha_example_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN -ha_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_example_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_example_la_SOURCES = ha_example.cc -EXTRA_LIBRARIES = libexample.a -noinst_LIBRARIES = @plugin_example_static_target@ -libexample_a_CXXFLAGS = $(AM_CXXFLAGS) -libexample_a_CFLAGS = $(AM_CFLAGS) -libexample_a_SOURCES= ha_example.cc +noinst_LTLIBRARIES = @plugin_example_static_target@ +libexample_la_CXXFLAGS = $(AM_CXXFLAGS) +libexample_la_SOURCES= ha_example.cc EXTRA_DIST = CMakeLists.txt plug.in diff --git a/storage/federated/Makefile.am b/storage/federated/Makefile.am index 8419e0b866e..290fb789a82 100644 --- a/storage/federated/Makefile.am +++ b/storage/federated/Makefile.am @@ -30,19 +30,21 @@ DEFS = @DEFS@ noinst_HEADERS = ha_federated.h -EXTRA_LTLIBRARIES = ha_federated.la +EXTRA_LTLIBRARIES = libfederated.la libfederated_embedded.la ha_federated.la pkgplugin_LTLIBRARIES = @plugin_federated_shared_target@ ha_federated_la_LDFLAGS = -module -rpath $(pkgplugindir) -ha_federated_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN -ha_federated_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_federated_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_federated_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_federated_la_SOURCES = ha_federated.cc $(top_srcdir)/mysys/string.c -EXTRA_LIBRARIES = libfederated.a -noinst_LIBRARIES = @plugin_federated_static_target@ -libfederated_a_CXXFLAGS = $(AM_CXXFLAGS) -libfederated_a_CFLAGS = $(AM_CFLAGS) -libfederated_a_SOURCES= ha_federated.cc +noinst_LTLIBRARIES = @plugin_federated_static_target@ @plugin_federated_embedded_static_target@ +libfederated_la_CXXFLAGS = $(AM_CXXFLAGS) +libfederated_la_SOURCES= ha_federated.cc + +libfederated_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@ +libfederated_embedded_la_CFLAGS = $(AM_CFLAGS) @plugin_embedded_defs@ +libfederated_embedded_la_SOURCES= ha_federated.cc EXTRA_DIST = CMakeLists.txt plug.in diff --git a/storage/federated/plug.in b/storage/federated/plug.in index 714888b2ebf..3db4a35de08 100644 --- a/storage/federated/plug.in +++ b/storage/federated/plug.in @@ -1,5 +1,4 @@ MYSQL_STORAGE_ENGINE(federated,,[Federated Storage Engine], [Connects to tables on remote MySQL servers], []) -MYSQL_PLUGIN_STATIC(federated, [libfederated.a]) +MYSQL_PLUGIN_STATIC(federated, [libfederated.la], [libfederated_embedded.la]) MYSQL_PLUGIN_DYNAMIC(federated, [ha_federated.la]) -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(federated, [ha_federated.cc]) diff --git a/storage/federatedx/Makefile.am b/storage/federatedx/Makefile.am index 1781a53a0b6..d642ec2bb5d 100644 --- a/storage/federatedx/Makefile.am +++ b/storage/federatedx/Makefile.am @@ -17,21 +17,31 @@ DEFS = @DEFS@ noinst_HEADERS = ha_federatedx.h federatedx_probes.h -EXTRA_LTLIBRARIES = ha_federatedx.la +EXTRA_LTLIBRARIES = libfederatedx.la libfederatedx_common.la libfederatedx_embedded.la ha_federatedx.la pkgplugin_LTLIBRARIES = @plugin_federatedx_shared_target@ ha_federatedx_la_LDFLAGS = -module -rpath $(pkgplugindir) -ha_federatedx_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN -ha_federatedx_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_federatedx_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_federatedx_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN -EXTRA_LIBRARIES = libfederatedx.a -noinst_LIBRARIES = @plugin_federatedx_static_target@ -libfederatedx_a_CXXFLAGS = $(AM_CFLAGS) -libfederatedx_a_CFLAGS = $(AM_CFLAGS) -libfederatedx_a_SOURCES= ha_federatedx.cc federatedx_txn.cc \ +noinst_LTLIBRARIES = @plugin_federatedx_static_target@ @plugin_federatedx_embedded_static_target@ +libfederatedx_common_la_CXXFLAGS = $(AM_CXXFLAGS) +libfederatedx_common_la_CFLAGS = $(AM_CFLAGS) +libfederatedx_common_la_SOURCES= federatedx_txn.cc \ federatedx_io.cc federatedx_io_null.cc \ federatedx_io_mysql.cc +libfederatedx_la_CXXFLAGS = $(AM_CFLAGS) +libfederatedx_la_CFLAGS = $(AM_CFLAGS) +libfederatedx_la_LIBADD = libfederatedx_common.la +libfederatedx_la_SOURCES= ha_federatedx.cc + +libfederatedx_embedded_la_CXXFLAGS = $(AM_CFLAGS) @plugin_embedded_defs@ +libfederatedx_embedded_la_CFLAGS = $(AM_CFLAGS) @plugin_embedded_defs@ +libfederatedx_embedded_la_LDFLAGS = $(AM_LDFLAGS) +libfederatedx_embedded_la_LIBADD = libfederatedx_common.la +libfederatedx_embedded_la_SOURCES= ha_federatedx.cc + EXTRA_DIST = CMakeLists.txt plug.in ha_federatedx.h \ federatedx_probes.h diff --git a/storage/federatedx/plug.in b/storage/federatedx/plug.in index 95afe270f4c..4a8a88e7280 100644 --- a/storage/federatedx/plug.in +++ b/storage/federatedx/plug.in @@ -1,5 +1,4 @@ MYSQL_STORAGE_ENGINE(federatedx,,[FederatedX Storage Engine], [FederatedX Storage Engine], [max,max-no-ndb]) MYSQL_PLUGIN_DYNAMIC(federatedx, [ha_federatedx.la]) -MYSQL_PLUGIN_STATIC(federatedx, [libfederatedx.a]) -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(federatedx, [ha_federatedx.cc]) +MYSQL_PLUGIN_STATIC(federatedx, [libfederatedx.la], [libfederatedx_embedded.la]) diff --git a/storage/heap/Makefile.am b/storage/heap/Makefile.am index ec1445dea67..c896442728a 100644 --- a/storage/heap/Makefile.am +++ b/storage/heap/Makefile.am @@ -27,8 +27,11 @@ LDADD = DEFS = @DEFS@ pkglib_LIBRARIES = libheap.a +noinst_LTLIBRARIES = libheap.la libheap_s.la \ + @plugin_heap_embedded_static_target@ +EXTRA_LTLIBRARIES = libheap_embedded.la + noinst_PROGRAMS = hp_test1 hp_test2 -noinst_LIBRARIES = libheap.a hp_test1_LDFLAGS = @NOINST_LDFLAGS@ hp_test1_LDADD = libheap.a \ $(top_builddir)/mysys/libmysys.a \ @@ -40,14 +43,25 @@ hp_test2_LDADD = libheap.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a noinst_HEADERS = heapdef.h ha_heap.h -libheap_a_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \ +libheap_la_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \ hp_rrnd.c hp_scan.c hp_update.c hp_write.c hp_delete.c \ hp_rsame.c hp_create.c hp_rename.c hp_rfirst.c \ hp_rnext.c hp_rlast.c hp_rprev.c hp_clear.c \ hp_rkey.c hp_block.c \ - ha_heap.cc \ hp_hash.c _check.c _rectest.c hp_static.c +libheap_s_la_SOURCES = ha_heap.cc +libheap_s_la_CFLAGS = $(AM_CFLAGS) +libheap_s_la_CXXFLAGS = $(AM_CXXFLAGS) +libheap_s_la_LIBADD = libheap.la +libheap_embedded_la_SOURCES = ha_heap.cc +libheap_embedded_la_LIBADD = libheap.la +libheap_embedded_la_CXXFLAGS = @plugin_embedded_defs@ + +libheap_a_SOURCES= +libheap.a: libheap.la + $(CP) .libs/libheap.a $@ + EXTRA_DIST = CMakeLists.txt plug.in diff --git a/storage/heap/plug.in b/storage/heap/plug.in index 50f31c60f2b..92ec01d3c88 100644 --- a/storage/heap/plug.in +++ b/storage/heap/plug.in @@ -1,7 +1,6 @@ MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine], [Volatile memory based tables]) MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap]) -MYSQL_PLUGIN_STATIC(heap, [libheap.a]) +MYSQL_PLUGIN_STATIC(heap, [libheap_s.la], [libheap_embedded.la]) MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(heap, [ha_heap.cc]) diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 2c93a3a409a..c2bbb98e73d 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -122,9 +122,8 @@ noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \ include/ut0list.ic include/ut0wqueue.h \ include/ha_prototypes.h handler/ha_innodb.h -EXTRA_LIBRARIES= libinnobase.a -noinst_LIBRARIES= @plugin_innobase_static_target@ -libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ +noinst_LTLIBRARIES= @plugin_innobase_static_target@ +libinnobase_la_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \ buf/buf0lru.c buf/buf0rea.c data/data0data.c \ data/data0type.c dict/dict0boot.c \ @@ -156,15 +155,15 @@ libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \ handler/ha_innodb.cc -libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS) -libinnobase_a_CFLAGS= $(AM_CFLAGS) +libinnobase_la_CXXFLAGS= $(AM_CXXFLAGS) +libinnobase_la_CFLAGS= $(AM_CFLAGS) -EXTRA_LTLIBRARIES= ha_innodb.la +EXTRA_LTLIBRARIES= libinnobase.la ha_innodb.la pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@ ha_innodb_la_LDFLAGS= -module -rpath $(pkgplugindir) -ha_innodb_la_CXXFLAGS= $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) -ha_innodb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) +ha_innodb_la_CXXFLAGS= -shared $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) +ha_innodb_la_CFLAGS= -shared $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_innodb_la_SOURCES= $(libinnobase_a_SOURCES) EXTRA_DIST= CMakeLists.txt plug.in \ diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 5e8831b5d5e..b1b59227883 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -2060,7 +2060,6 @@ btr_compress( ulint n_recs; ulint max_ins_size; ulint max_ins_size_reorg; - ulint level; ulint comp; page = btr_cur_get_page(cursor); @@ -2072,7 +2071,6 @@ btr_compress( MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); - level = btr_page_get_level(page, mtr); space = dict_index_get_space(index); left_page_no = btr_page_get_prev(page, mtr); diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index d2a2e4d2157..a7160d74a32 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -3365,7 +3365,9 @@ btr_store_big_rec_extern_fields( page_t* page; ulint space_id; page_t* prev_page; +#ifdef UNIV_SYNC_DEBUG page_t* rec_page; +#endif /* UNIV_SYNC_DEBUG */ ulint prev_page_no; ulint hint_page_no; ulint i; @@ -3460,9 +3462,12 @@ btr_store_big_rec_extern_fields( extern_len -= store_len; - rec_page = buf_page_get(space_id, - buf_frame_get_page_no(data), - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + rec_page = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(space_id, + buf_frame_get_page_no(data), + RW_X_LATCH, &mtr); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(rec_page, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ @@ -3536,10 +3541,11 @@ btr_free_externally_stored_field( X-latch to the index tree */ { page_t* page; +#ifdef UNIV_SYNC_DEBUG page_t* rec_page; +#endif /* UNIV_SYNC_DEBUG */ ulint space_id; ulint page_no; - ulint offset; ulint extern_len; ulint next_page_no; ulint part_len; @@ -3556,9 +3562,12 @@ btr_free_externally_stored_field( for (;;) { mtr_start(&mtr); - rec_page = buf_page_get(buf_frame_get_space_id(data), - buf_frame_get_page_no(data), - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + rec_page = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(buf_frame_get_space_id(data), + buf_frame_get_page_no(data), + RW_X_LATCH, &mtr); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(rec_page, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ @@ -3568,8 +3577,6 @@ btr_free_externally_stored_field( page_no = mach_read_from_4(data + local_len + BTR_EXTERN_PAGE_NO); - offset = mach_read_from_4(data + local_len - + BTR_EXTERN_OFFSET); extern_len = mach_read_from_4(data + local_len + BTR_EXTERN_LEN + 4); diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c index 65b3c90c809..f73e82fb597 100644 --- a/storage/innobase/btr/btr0pcur.c +++ b/storage/innobase/btr/btr0pcur.c @@ -429,7 +429,6 @@ btr_pcur_move_backward_from_page( mtr_t* mtr) /* in: mtr */ { ulint prev_page_no; - ulint space; page_t* page; page_t* prev_page; ulint latch_mode; @@ -465,7 +464,6 @@ btr_pcur_move_backward_from_page( page = btr_pcur_get_page(cursor); prev_page_no = btr_page_get_prev(page, mtr); - space = buf_frame_get_space_id(page); if (btr_pcur_is_before_first_on_page(cursor, mtr) && (prev_page_no != FIL_NULL)) { diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c index 84ad0e27110..97c9f89db72 100644 --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c @@ -1401,7 +1401,6 @@ btr_search_update_hash_on_delete( rec_t* rec; ulint fold; dulint index_id; - ibool found; ulint offsets_[REC_OFFS_NORMAL_SIZE]; mem_heap_t* heap = NULL; *offsets_ = (sizeof offsets_) / sizeof *offsets_; @@ -1433,7 +1432,7 @@ btr_search_update_hash_on_delete( } rw_lock_x_lock(&btr_search_latch); - found = ha_search_and_delete_if_found(table, fold, rec); + ha_search_and_delete_if_found(table, fold, rec); rw_lock_x_unlock(&btr_search_latch); } diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 7533205d695..24fa306c127 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -841,7 +841,6 @@ buf_flush_batch( { buf_block_t* block; ulint page_count = 0; - ulint old_page_count; ulint space; ulint offset; ibool found; @@ -913,15 +912,9 @@ buf_flush_batch( mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); - old_page_count = page_count; - /* Try to flush also all the neighbors */ page_count += buf_flush_try_neighbors( space, offset, flush_type); - /* fprintf(stderr, - "Flush type %lu, page no %lu, neighb %lu\n", - flush_type, offset, - page_count - old_page_count); */ mutex_enter(&(buf_pool->mutex)); diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index d2b59469cdc..b52a94c3348 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -616,8 +616,7 @@ dict_table_get_on_id( { dict_table_t* table; - if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 - || trx->dict_operation_lock_mode == RW_X_LATCH) { + if (trx->dict_operation_lock_mode == RW_X_LATCH) { /* Note: An X latch implies that the transaction already owns the dictionary mutex. */ @@ -2140,7 +2139,7 @@ dict_foreign_add_to_cache( mem_heap_free(foreign->heap); } - return(DB_CANNOT_ADD_CONSTRAINT); + return(DB_FOREIGN_NO_INDEX); } for_in_cache->referenced_table = ref_table; @@ -2184,7 +2183,7 @@ dict_foreign_add_to_cache( mem_heap_free(foreign->heap); } - return(DB_CANNOT_ADD_CONSTRAINT); + return(DB_REFERENCING_NO_INDEX); } for_in_cache->foreign_table = for_table; @@ -3754,7 +3753,6 @@ dict_update_statistics_low( dictionary mutex */ { dict_index_t* index; - ulint size; ulint sum_of_index_sizes = 0; if (table->ibd_file_missing) { @@ -3770,14 +3768,6 @@ dict_update_statistics_low( return; } - /* If we have set a high innodb_force_recovery level, do not calculate - statistics, as a badly corrupted index can cause a crash in it. */ - - if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - - return; - } - /* Find out the sizes of the indexes and how many different values for the key they approximately have */ @@ -3789,26 +3779,48 @@ dict_update_statistics_low( return; } - while (index) { - size = btr_get_size(index, BTR_TOTAL_SIZE); - index->stat_index_size = size; + do { + if (UNIV_LIKELY + (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE + || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO + && (index->type & DICT_CLUSTERED)))) { + ulint size; + size = btr_get_size(index, BTR_TOTAL_SIZE); - sum_of_index_sizes += size; + index->stat_index_size = size; - size = btr_get_size(index, BTR_N_LEAF_PAGES); + sum_of_index_sizes += size; - if (size == 0) { - /* The root node of the tree is a leaf */ - size = 1; - } + size = btr_get_size(index, BTR_N_LEAF_PAGES); - index->stat_n_leaf_pages = size; + if (size == 0) { + /* The root node of the tree is a leaf */ + size = 1; + } + + index->stat_n_leaf_pages = size; + + btr_estimate_number_of_different_key_vals(index); + } else { + /* If we have set a high innodb_force_recovery + level, do not calculate statistics, as a badly + corrupted index can cause a crash in it. + Initialize some bogus index cardinality + statistics, so that the data can be queried in + various means, also via secondary indexes. */ + ulint i; - btr_estimate_number_of_different_key_vals(index); + sum_of_index_sizes++; + index->stat_index_size = index->stat_n_leaf_pages = 1; + + for (i = dict_index_get_n_unique(index); i; ) { + index->stat_n_diff_key_vals[i--] = 1; + } + } index = dict_table_get_next_index(index); - } + } while (index); index = dict_table_get_first_index(table); diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index d5e7600f4d0..625956600c0 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -864,16 +864,27 @@ err_exit: err = dict_load_indexes(table, heap); + /* Initialize table foreign_child value. Its value could be + changed when dict_load_foreigns() is called below */ + table->fk_max_recusive_level = 0; + /* If the force recovery flag is set, we open the table irrespective of the error condition, since the user may want to dump data from the clustered index. However we load the foreign key information only if all indexes were loaded. */ if (err == DB_SUCCESS) { - err = dict_load_foreigns(table->name, TRUE); + err = dict_load_foreigns(table->name, TRUE, TRUE); + + if (err != DB_SUCCESS) { + dict_table_remove_from_cache(table); + table = NULL; + } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } + + table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { @@ -1095,8 +1106,12 @@ dict_load_foreign( /* out: DB_SUCCESS or error code */ const char* id, /* in: foreign constraint id as a null-terminated string */ - ibool check_charsets) + ibool check_charsets, /* in: TRUE=check charset compatibility */ + ibool check_recursive) + /* in: Whether to record the foreign table + parent count to avoid unlimited recursive + load of chained foreign tables */ { dict_foreign_t* foreign; dict_table_t* sys_foreign; @@ -1110,6 +1125,8 @@ dict_load_foreign( ulint len; ulint n_fields_and_type; mtr_t mtr; + dict_table_t* for_table; + dict_table_t* ref_table; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1194,11 +1211,54 @@ dict_load_foreign( dict_load_foreign_cols(id, foreign); - /* If the foreign table is not yet in the dictionary cache, we - have to load it so that we are able to make type comparisons - in the next function call. */ - - dict_table_get_low(foreign->foreign_table_name); + ref_table = dict_table_check_if_in_cache_low( + foreign->referenced_table_name); + + /* We could possibly wind up in a deep recursive calls if + we call dict_table_get_low() again here if there + is a chain of tables concatenated together with + foreign constraints. In such case, each table is + both a parent and child of the other tables, and + act as a "link" in such table chains. + To avoid such scenario, we would need to check the + number of ancesters the current table has. If that + exceeds DICT_FK_MAX_CHAIN_LEN, we will stop loading + the child table. + Foreign constraints are loaded in a Breath First fashion, + that is, the index on FOR_NAME is scanned first, and then + index on REF_NAME. So foreign constrains in which + current table is a child (foreign table) are loaded first, + and then those constraints where current table is a + parent (referenced) table. + Thus we could check the parent (ref_table) table's + reference count (fk_max_recusive_level) to know how deep the + recursive call is. If the parent table (ref_table) is already + loaded, and its fk_max_recusive_level is larger than + DICT_FK_MAX_CHAIN_LEN, we will stop the recursive loading + by skipping loading the child table. It will not affect foreign + constraint check for DMLs since child table will be loaded + at that time for the constraint check. */ + if (!ref_table + || ref_table->fk_max_recusive_level < DICT_FK_MAX_RECURSIVE_LOAD) { + + /* If the foreign table is not yet in the dictionary cache, we + have to load it so that we are able to make type comparisons + in the next function call. */ + + for_table = dict_table_get_low(foreign->foreign_table_name); + + if (for_table && ref_table && check_recursive) { + /* This is to record the longest chain of ancesters + this table has, if the parent has more ancesters + than this table has, record it after add 1 (for this + parent */ + if (ref_table->fk_max_recusive_level + >= for_table->fk_max_recusive_level) { + for_table->fk_max_recusive_level = + ref_table->fk_max_recusive_level + 1; + } + } + } /* Note that there may already be a foreign constraint object in the dictionary cache for this constraint: then the following @@ -1223,6 +1283,8 @@ dict_load_foreigns( /*===============*/ /* out: DB_SUCCESS or error code */ const char* table_name, /* in: table name */ + ibool check_recursive,/* in: Whether to check recursive + load of tables chained by FK */ ibool check_charsets) /* in: TRUE=check charset compatibility */ { @@ -1324,7 +1386,7 @@ loop: /* Load the foreign constraint definition to the dictionary cache */ - err = dict_load_foreign(id, check_charsets); + err = dict_load_foreign(id, check_charsets, check_recursive); if (err != DB_SUCCESS) { btr_pcur_close(&pcur); @@ -1352,6 +1414,11 @@ load_next_index: mtr_start(&mtr); + /* Switch to scan index on REF_NAME, fk_max_recusive_level + already been updated when scanning FOR_NAME index, no need to + update again */ + check_recursive = FALSE; + goto start_load; } diff --git a/storage/innobase/eval/eval0eval.c b/storage/innobase/eval/eval0eval.c index cbc47ec508f..52e9923fc05 100644 --- a/storage/innobase/eval/eval0eval.c +++ b/storage/innobase/eval/eval0eval.c @@ -367,18 +367,13 @@ eval_notfound( /*==========*/ func_node_t* func_node) /* in: function node */ { - que_node_t* arg1; - que_node_t* arg2; sym_node_t* cursor; sel_node_t* sel_node; ibool ibool_val; - arg1 = func_node->args; - arg2 = que_node_get_next(arg1); - ut_ad(func_node->func == PARS_NOTFOUND_TOKEN); - cursor = arg1; + cursor = func_node->args; ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL); diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 3810fefd3cb..6ca8381ebdf 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -966,6 +966,8 @@ try_again: HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(name), space, 0 == strcmp(name, space->name)); if (space != NULL) { + ibool success; + ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Warning: trying to init to the" @@ -1002,9 +1004,10 @@ try_again: namesake_id = space->id; - mutex_exit(&(system->mutex)); + success = fil_space_free(namesake_id, FALSE); + ut_a(success); - fil_space_free(namesake_id); + mutex_exit(&(system->mutex)); goto try_again; } @@ -1128,6 +1131,33 @@ fil_assign_new_space_id(void) } /*********************************************************************** +Check if the space id exists in the cache, complain to stderr if the +space id cannot be found. */ +static +fil_space_t* +fil_space_search( +/*=============*/ + /* out: file space instance*/ + ulint id) /* in: space id */ +{ + fil_space_t* space; + + ut_ad(mutex_own(&fil_system->mutex)); + + HASH_SEARCH(hash, fil_system->spaces, id, space, space->id == id); + + if (space == NULL) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: trying to remove tablespace %lu" + " from the cache but\n" + "InnoDB: it is not there.\n", (ulong) id); + } + + return(space); +} + +/*********************************************************************** Frees a space object from the tablespace memory cache. Closes the files in the chain but does not delete them. There must not be any pending i/o's or flushes on the files. */ @@ -1135,27 +1165,21 @@ flushes on the files. */ ibool fil_space_free( /*===========*/ - /* out: TRUE if success */ - ulint id) /* in: space id */ + /* out: TRUE if success */ + ulint id, /* in: space id */ + ibool x_latched) /* in: TRUE if caller has space->latch + in X mode */ { fil_system_t* system = fil_system; fil_space_t* space; fil_space_t* namespace; fil_node_t* fil_node; - mutex_enter(&(system->mutex)); + ut_ad(mutex_own(&fil_system->mutex)); - HASH_SEARCH(hash, system->spaces, id, space, space->id == id); - - if (!space) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: trying to remove tablespace %lu" - " from the cache but\n" - "InnoDB: it is not there.\n", (ulong) id); - - mutex_exit(&(system->mutex)); + space = fil_space_search(id); + if (space == NULL) { return(FALSE); } @@ -1191,7 +1215,9 @@ fil_space_free( ut_a(0 == UT_LIST_GET_LEN(space->chain)); - mutex_exit(&(system->mutex)); + if (x_latched) { + rw_lock_x_unlock(&space->latch); + } rw_lock_free(&(space->latch)); @@ -2048,6 +2074,19 @@ try_again: path = mem_strdup(space->name); mutex_exit(&(system->mutex)); + + /* Important: We rely on the data dictionary mutex to ensure + that a race is not possible here. It should serialize the tablespace + drop/free. We acquire an X latch only to avoid a race condition + when accessing the tablespace instance via: + + fsp_get_available_space_in_free_extents(). + + There our main motivation is to reduce the contention on the + dictionary mutex and not correctness. */ + + rw_lock_x_lock(&space->latch); + #ifndef UNIV_HOTBACKUP /* Invalidate in the buffer pool all pages belonging to the tablespace. Since we have set space->is_being_deleted = TRUE, readahead @@ -2060,7 +2099,11 @@ try_again: #endif /* printf("Deleting tablespace %s id %lu\n", space->name, id); */ - success = fil_space_free(id); + mutex_enter(&system->mutex); + + success = fil_space_free(id, TRUE); + + mutex_exit(&system->mutex); if (success) { success = os_file_delete(path); @@ -2068,6 +2111,8 @@ try_again: if (!success) { success = os_file_delete_if_exists(path); } + } else { + rw_lock_x_unlock(&space->latch); } if (success) { @@ -4569,3 +4614,28 @@ fil_page_get_type( return(mach_read_from_2(page + FIL_PAGE_TYPE)); } + +/*********************************************************************** +Returns TRUE if a single-table tablespace is being deleted. */ + +ibool +fil_tablespace_is_being_deleted( +/*============================*/ + /* out: TRUE if space is being deleted */ + ulint id) /* in: space id */ +{ + fil_space_t* space; + ibool is_being_deleted; + + mutex_enter(&fil_system->mutex); + + HASH_SEARCH(hash, fil_system->spaces, id, space, space->id == id); + + ut_a(space != NULL); + + is_being_deleted = space->is_being_deleted; + + mutex_exit(&fil_system->mutex); + + return(is_being_deleted); +} diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c index 1ec1c262a52..1f033c4b140 100644 --- a/storage/innobase/fsp/fsp0fsp.c +++ b/storage/innobase/fsp/fsp0fsp.c @@ -2842,12 +2842,61 @@ fsp_get_available_space_in_free_extents( ut_ad(!mutex_own(&kernel_mutex)); + /* The convoluted mutex acquire is to overcome latching order + issues: The problem is that the fil_mutex is at a lower level + than the tablespace latch and the buffer pool mutex. We have to + first prevent any operations on the file system by acquiring the + dictionary mutex. Then acquire the tablespace latch to obey the + latching order and then release the dictionary mutex. That way we + ensure that the tablespace instance can't be freed while we are + examining its contents (see fil_space_free()). + + However, there is one further complication, we release the fil_mutex + when we need to invalidate the the pages in the buffer pool and we + reacquire the fil_mutex when deleting and freeing the tablespace + instance in fil0fil.c. Here we need to account for that situation + too. */ + + dict_mutex_enter_for_mysql(); + + /* At this stage there is no guarantee that the tablespace even + exists in the cache. */ + + if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) { + + dict_mutex_exit_for_mysql(); + + return(ULLINT_UNDEFINED); + } + mtr_start(&mtr); latch = fil_space_get_latch(space); + /* This should ensure that the tablespace instance can't be freed + by another thread. However, the tablespace pages can still be freed + from the buffer pool. We need to check for that again. */ + mtr_x_lock(latch, &mtr); + dict_mutex_exit_for_mysql(); + + /* At this point it is possible for the tablespace to be deleted and + its pages removed from the buffer pool. We need to check for that + situation. However, the tablespace instance can't be deleted because + our latching above should ensure that. */ + + if (fil_tablespace_is_being_deleted(space)) { + + mtr_commit(&mtr); + + return(ULLINT_UNDEFINED); + } + + /* From here on even if the user has dropped the tablespace, the + pages _must_ still exist in the buffer pool and the tablespace + instance _must be in the file system hash table. */ + space_header = fsp_get_space_header(space, &mtr); size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, &mtr); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d10fcb8d31e..32973aaf541 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -707,7 +707,9 @@ convert_error_code_to_mysql( return(HA_ERR_ROW_IS_REFERENCED); - } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) { + } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT + || error == (int) DB_FOREIGN_NO_INDEX + || error == (int) DB_REFERENCING_NO_INDEX) { return(HA_ERR_CANNOT_ADD_FOREIGN); @@ -763,6 +765,16 @@ convert_error_code_to_mysql( my_error(ER_QUERY_INTERRUPTED, MYF(0)); return(-1); + } else if (error == DB_FOREIGN_EXCEED_MAX_CASCADE) { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_ROW_IS_REFERENCED, + "InnoDB: Cannot delete/update " + "rows with cascading foreign key " + "constraints that exceed max " + "depth of %d. Please " + "drop extra constraints and try " + "again", DICT_FK_MAX_RECURSIVE_LOAD); + return(-1); } else { return(-1); // Unknown error } @@ -2710,12 +2722,19 @@ ha_innobase::innobase_initialize_autoinc() err = row_search_max_autoinc(index, col_name, &read_auto_inc); switch (err) { - case DB_SUCCESS: + case DB_SUCCESS: { + ulonglong col_max_value; + + col_max_value = innobase_get_int_col_max_value(field); + /* At the this stage we do not know the increment - or the offset, so use a default increment of 1. */ - auto_inc = read_auto_inc + 1; - break; + nor the offset, so use a default increment of 1. */ + auto_inc = innobase_next_autoinc( + read_auto_inc, 1, 1, col_max_value); + + break; + } case DB_RECORD_NOT_FOUND: ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: MySQL and InnoDB data " @@ -2941,8 +2960,6 @@ retry: /* Init table lock structure */ thr_lock_data_init(&share->lock,&lock,(void*) 0); - info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); - /* Only if the table has an AUTOINC column. */ if (prebuilt->table != NULL && table->found_next_number_field != NULL) { dict_table_autoinc_lock(prebuilt->table); @@ -2959,6 +2976,8 @@ retry: dict_table_autoinc_unlock(prebuilt->table); } + info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); + DBUG_RETURN(0); } @@ -5964,7 +5983,6 @@ innobase_drop_database( trx_t* parent_trx; trx_t* trx; char* ptr; - int error; char* namebuf; THD* thd = current_thd; @@ -6002,7 +6020,7 @@ innobase_drop_database( trx->check_foreigns = FALSE; } - error = row_drop_database_for_mysql(namebuf, trx); + row_drop_database_for_mysql(namebuf, trx); my_free(namebuf, MYF(0)); /* Flush the log to reduce probability that the .frm files and @@ -6018,13 +6036,7 @@ innobase_drop_database( innobase_commit_low(trx); trx_free_for_mysql(trx); -#ifdef NO_LONGER_INTERESTED_IN_DROP_DB_ERROR - error = convert_error_code_to_mysql(error, NULL); - - return(error); -#else return; -#endif } /************************************************************************* @@ -6099,6 +6111,8 @@ ha_innobase::rename_table( innobase_commit_low(trx); trx_free_for_mysql(trx); + switch (error) { + case DB_DUPLICATE_KEY: /* Add a special case to handle the Duplicated Key error and return DB_ERROR instead. This is to avoid a possible SIGSEGV error from mysql error @@ -6111,10 +6125,28 @@ ha_innobase::rename_table( the dup key error here is due to an existing table whose name is the one we are trying to rename to) and return the generic error code. */ - if (error == (int) DB_DUPLICATE_KEY) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to); error = DB_ERROR; + break; + case DB_FOREIGN_NO_INDEX: + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_CANNOT_ADD_FOREIGN, + "Alter or rename of table '%s' failed" + " because the new table is a child table" + " in a FK relationship and it does not" + " have an index that contains foreign" + " keys as its prefix columns.", norm_to); + break; + case DB_REFERENCING_NO_INDEX: + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_CANNOT_ADD_FOREIGN, + "Alter or rename of table '%s' failed" + " because the new table is a parent table" + " in a FK relationship and it does not" + " have an index that contains foreign" + " keys as its prefix columns.", norm_to); + break; } error = convert_error_code_to_mysql(error, NULL); @@ -6343,8 +6375,6 @@ ha_innobase::info( dict_index_t* index; ha_rows rec_per_key; ib_longlong n_rows; - ulong j; - ulong i; char path[FN_REFLEN]; os_file_stat_t stat_info; @@ -6354,16 +6384,6 @@ ha_innobase::info( statistics calculation on tables, because that may crash the server if an index is badly corrupted. */ - if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - - /* We return success (0) instead of HA_ERR_CRASHED, - because we want MySQL to process this query and not - stop, like it would do if it received the error code - HA_ERR_CRASHED. */ - - DBUG_RETURN(0); - } - /* We do not know if MySQL can call this function before calling external_lock(). To be safe, update the thd of the current table handle. */ @@ -6458,25 +6478,24 @@ ha_innobase::info( acquiring latches inside InnoDB, we do not call it if we are asked by MySQL to avoid locking. Another reason to avoid the call is that it uses quite a lot of CPU. - See Bug#38185. - We do not update delete_length if no locking is requested - so the "old" value can remain. delete_length is initialized - to 0 in the ha_statistics' constructor. */ - if (!(flag & HA_STATUS_NO_LOCK)) { - - /* lock the data dictionary to avoid races with - ibd_file_missing and tablespace_discarded */ - row_mysql_lock_data_dictionary(prebuilt->trx); - - /* ib_table->space must be an existent tablespace */ - if (!ib_table->ibd_file_missing - && !ib_table->tablespace_discarded) { - - stats.delete_length = - fsp_get_available_space_in_free_extents( - ib_table->space) * 1024; - } else { + See Bug#38185. */ + if (flag & HA_STATUS_NO_LOCK) { + /* We do not update delete_length if no + locking is requested so the "old" value can + remain. delete_length is initialized to 0 in + the ha_statistics' constructor. */ + } else if (UNIV_UNLIKELY + (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) { + /* Avoid accessing the tablespace if + innodb_crash_recovery is set to a high value. */ + stats.delete_length = 0; + } else { + ullint avail_space; + + avail_space = fsp_get_available_space_in_free_extents( + ib_table->space); + if (avail_space == ULLINT_UNDEFINED) { THD* thd; thd = ha_thd(); @@ -6493,9 +6512,9 @@ ha_innobase::info( ib_table->name); stats.delete_length = 0; + } else { + stats.delete_length = avail_space * 1024; } - - row_mysql_unlock_data_dictionary(prebuilt->trx); } stats.check_time = 0; @@ -6508,6 +6527,7 @@ ha_innobase::info( } if (flag & HA_STATUS_CONST) { + ulong i = 0; index = dict_table_get_first_index_noninline(ib_table); if (prebuilt->clust_index_was_generated) { @@ -6515,6 +6535,8 @@ ha_innobase::info( } for (i = 0; i < table->s->keys; i++) { + ulong j; + if (index == NULL) { sql_print_error("Table %s contains fewer " "indexes inside InnoDB than " @@ -6571,6 +6593,11 @@ ha_innobase::info( } } + if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { + + goto func_exit; + } + if (flag & HA_STATUS_ERRKEY) { ut_a(prebuilt->trx); ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N); @@ -6583,6 +6610,7 @@ ha_innobase::info( stats.auto_increment_value = innobase_peek_autoinc(); } +func_exit: prebuilt->trx->op_info = (char*)""; DBUG_RETURN(0); @@ -7525,12 +7553,9 @@ innodb_show_status( mutex_exit_noninline(&srv_monitor_file_mutex); - bool result = FALSE; + stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), + STRING_WITH_LEN(""), str, flen); - if (stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), - STRING_WITH_LEN(""), str, flen)) { - result= TRUE; - } my_free(str, MYF(0)); DBUG_RETURN(FALSE); @@ -7814,16 +7839,17 @@ ha_innobase::store_lock( && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) && (sql_command == SQLCOM_INSERT_SELECT || sql_command == SQLCOM_UPDATE - || sql_command == SQLCOM_CREATE_TABLE)) { + || sql_command == SQLCOM_CREATE_TABLE + || sql_command == SQLCOM_SET_OPTION)) { /* If we either have innobase_locks_unsafe_for_binlog option set or this session is using READ COMMITTED isolation level and isolation level of the transaction is not set to serializable and MySQL is doing INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or - CREATE ... SELECT... without FOR UPDATE or - IN SHARE MODE in select, then we use consistent - read for select. */ + CREATE ... SELECT... or SET ... = (SELECT ...) + without FOR UPDATE or IN SHARE MODE in select, + then we use consistent read for select. */ prebuilt->select_lock_type = LOCK_NONE; prebuilt->stored_select_lock_type = LOCK_NONE; diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index 2be6005622d..bab6fa46370 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -73,6 +73,15 @@ Created 5/24/1996 Heikki Tuuri a later version of the engine. */ #define DB_INTERRUPTED 49 /* the query has been interrupted with "KILL QUERY N;" */ +#define DB_FOREIGN_EXCEED_MAX_CASCADE 50/* Foreign key constraint related + cascading delete/update exceeds + maximum allowed depth */ +#define DB_FOREIGN_NO_INDEX 51 /* the child (foreign) table does not + have an index that contains the + foreign keys as its prefix columns */ +#define DB_REFERENCING_NO_INDEX 52 /* the parent (referencing) table does + not have an index that contains the + foreign keys as its prefix columns */ /* The following are partial failure codes */ #define DB_FAIL 1000 diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index e76f23d0767..369d354c520 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -588,6 +588,22 @@ dict_table_is_comp_noninline( /* out: TRUE if table uses the compact page format */ const dict_table_t* table); /* in: table */ +/*********************************************************************//** +Obtain exclusive locks on all index trees of the table. This is to prevent +accessing index trees while InnoDB is updating internal metadata for +operations such as truncate tables. */ +UNIV_INLINE +void +dict_table_x_lock_indexes( +/*======================*/ + dict_table_t* table); /* in: table */ +/*********************************************************************//** +Release the exclusive locks on all index tree. */ +UNIV_INLINE +void +dict_table_x_unlock_indexes( +/*========================*/ + dict_table_t* table); /* in: table */ /************************************************************************ Checks if a column is in the ordering columns of the clustered index of a table. Column prefixes are treated like whole columns. */ diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 7d38cbcd1fa..5cdbdbeb03d 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -298,6 +298,48 @@ dict_table_is_comp( return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT)); } +/*********************************************************************//** +Obtain exclusive locks on all index trees of the table. This is to prevent +accessing index trees while InnoDB is updating internal metadata for +operations such as truncate tables. */ +UNIV_INLINE +void +dict_table_x_lock_indexes( +/*======================*/ + dict_table_t* table) /* in: table */ +{ + dict_index_t* index; + + ut_a(table); + ut_ad(mutex_own(&(dict_sys->mutex))); + + /* Loop through each index of the table and lock them */ + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_lock(dict_index_get_lock(index)); + } +} + +/*********************************************************************//** +Release the exclusive locks on all index tree. */ +UNIV_INLINE +void +dict_table_x_unlock_indexes( +/*========================*/ + dict_table_t* table) /* in: table */ +{ + dict_index_t* index; + + ut_a(table); + ut_ad(mutex_own(&(dict_sys->mutex))); + + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_unlock(dict_index_get_lock(index)); + } +} /************************************************************************ Gets the number of fields in the internal representation of an index, including fields added by the dictionary system. */ diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index 7e19c2eb3c0..eb6083e06f9 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -82,6 +82,8 @@ dict_load_foreigns( /*===============*/ /* out: DB_SUCCESS or error code */ const char* table_name, /* in: table name */ + ibool check_recursive,/* in: Whether to check recursive + load of tables chained by FK */ ibool check_charsets);/* in: TRUE=check charsets compatibility */ /************************************************************************ diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index ac28fdb1bae..2f2a7441478 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -283,6 +283,21 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */ #define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 #define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 +/** Tables could be chained together with Foreign key constraint. When +first load the parent table, we would load all of its descedents. +This could result in rescursive calls and out of stack error eventually. +DICT_FK_MAX_RECURSIVE_LOAD defines the maximum number of recursive loads, +when exceeded, the child table will not be loaded. It will be loaded when +the foreign constraint check needs to be run. */ +#define DICT_FK_MAX_RECURSIVE_LOAD 250 + +/** Similarly, when tables are chained together with foreign key constraints +with on cascading delete/update clause, delete from parent table could +result in recursive cascading calls. This defines the maximum number of +such cascading deletes/updates allowed. When exceeded, the delete from +parent table will fail, and user has to drop excessive foreign constraint +before proceeds. */ +#define FK_MAX_CASCADE_DEL 300 /* Data structure for a database table */ struct dict_table_struct{ @@ -339,6 +354,12 @@ struct dict_table_struct{ NOT allowed until this count gets to zero; MySQL does NOT itself check the number of open handles at drop */ + unsigned fk_max_recusive_level:8; + /*!< maximum recursive level we support when + loading tables chained together with FK + constraints. If exceeds this level, we will + stop loading child table into memory along with + its parent table */ ulint n_foreign_key_checks_running; /* count of how many foreign key check operations are currently being performed diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 251d6c22547..7e85a0b412b 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -202,8 +202,10 @@ the chain but does not delete them. */ ibool fil_space_free( /*===========*/ - /* out: TRUE if success */ - ulint id); /* in: space id */ + /* out: TRUE if success */ + ulint id, /* in: space id */ + ibool x_latched); /* in: TRUE if caller has space->latch + in X mode */ /*********************************************************************** Returns the size of the space in pages. The tablespace must be cached in the memory cache. */ @@ -710,6 +712,14 @@ fil_page_get_type( written to page, the return value not defined */ byte* page); /* in: file page */ +/*********************************************************************** +Returns TRUE if a single-table tablespace is being deleted. */ + +ibool +fil_tablespace_is_being_deleted( +/*============================*/ + /* out: TRUE if space is being deleted */ + ulint id); /* in: space id */ typedef struct fil_space_struct fil_space_t; diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index 8fbf5330c89..71f4cfdfb8f 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -367,6 +367,9 @@ struct que_thr_struct{ thus far */ ulint lock_state; /* lock state of thread (table or row) */ + ulint fk_cascade_depth; /*!< maximum cascading call depth + supported for foreign key constraint + related delete/updates */ }; #define QUE_THR_MAGIC_N 8476583 diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 97d022d284e..ce5d8a092bf 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -234,6 +234,12 @@ typedef unsigned long long int ullint; /* Maximum value for a ulint */ #define ULINT_MAX ((ulint)(-2)) +/* THe 'undefined' value for ullint */ +#define ULLINT_UNDEFINED ((ullint)(-1)) + +/* Maximum value for a ullint */ +#define ULLINT_MAX ((ullint)(-2)) + /* This 'ibool' type is used within Innobase. Remember that different included headers may define 'bool' differently. Do not assume that 'bool' is a ulint! */ #define ibool ulint diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic index 625c378489a..dc4c0d62f56 100644 --- a/storage/innobase/include/ut0rnd.ic +++ b/storage/innobase/include/ut0rnd.ic @@ -67,9 +67,6 @@ ut_rnd_gen_ulint(void) /* out: the 'random' number */ { ulint rnd; - ulint n_bits; - - n_bits = 8 * sizeof(ulint); ut_rnd_ulint_counter = UT_RND1 * ut_rnd_ulint_counter + UT_RND2; diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 04240960b3a..57df99fb401 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4296,7 +4296,6 @@ lock_print_info_all_transactions( lock_t* lock; ulint space; ulint page_no; - page_t* page; ibool load_page_first = TRUE; ulint nth_trx = 0; ulint nth_lock = 0; @@ -4410,8 +4409,7 @@ loop: mtr_start(&mtr); - page = buf_page_get_with_no_latch( - space, page_no, &mtr); + buf_page_get_with_no_latch(space, page_no, &mtr); mtr_commit(&mtr); diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index e6524eeefbf..6e1ca58cb15 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -400,10 +400,8 @@ recv_synchronize_groups( dulint start_lsn; dulint end_lsn; dulint recovered_lsn; - dulint limit_lsn; recovered_lsn = recv_sys->recovered_lsn; - limit_lsn = recv_sys->limit_lsn; /* Read the last recovered log block to the recovery system buffer: the block is always incomplete */ @@ -2506,7 +2504,9 @@ recv_recovery_from_checkpoint_start( dulint old_scanned_lsn; dulint group_scanned_lsn; dulint contiguous_lsn; +#ifdef UNIV_LOG_ARCHIVE dulint archived_lsn; +#endif /* UNIV_LOG_ARCHIVE */ ulint capacity; byte* buf; byte log_hdr_buf[LOG_FILE_HDR_SIZE]; @@ -2552,7 +2552,9 @@ recv_recovery_from_checkpoint_start( checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO); +#ifdef UNIV_LOG_ARCHIVE archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN); +#endif /* UNIV_LOG_ARCHIVE */ /* Read the first log file header to print a note if this is a recovery from a restored InnoDB Hot Backup */ diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 3396d1adf2f..a995aee5fab 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -1314,8 +1314,6 @@ try_again: int create_flag; ibool retry; const char* mode_str = NULL; - const char* type_str = NULL; - const char* purpose_str = NULL; try_again: ut_a(name); @@ -1335,26 +1333,9 @@ try_again: ut_error; } - if (type == OS_LOG_FILE) { - type_str = "LOG"; - } else if (type == OS_DATA_FILE) { - type_str = "DATA"; - } else { - ut_error; - } + ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE); + ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL); - if (purpose == OS_FILE_AIO) { - purpose_str = "AIO"; - } else if (purpose == OS_FILE_NORMAL) { - purpose_str = "NORMAL"; - } else { - ut_error; - } - -#if 0 - fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n", - name, mode_str, type_str, purpose_str); -#endif #ifdef O_SYNC /* We let O_SYNC only affect log files; note that we map O_DSYNC to O_SYNC because the datasync options seemed to corrupt files in 2001 diff --git a/storage/innobase/plug.in.disabled b/storage/innobase/plug.in.disabled index de7302dd6cc..b18950b9c7a 100644 --- a/storage/innobase/plug.in.disabled +++ b/storage/innobase/plug.in.disabled @@ -1,7 +1,7 @@ MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine], [Transactional Tables using InnoDB], [max,max-no-ndb]) MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase]) -MYSQL_PLUGIN_STATIC(innobase, [libinnobase.a]) +MYSQL_PLUGIN_STATIC(innobase, [libinnobase.la]) MYSQL_PLUGIN_DYNAMIC(innobase, [ha_innodb.la]) MYSQL_PLUGIN_ACTIONS(innobase, [ AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) diff --git a/storage/innobase/que/que0que.c b/storage/innobase/que/que0que.c index bf83f28f04e..1a76823ca4d 100644 --- a/storage/innobase/que/que0que.c +++ b/storage/innobase/que/que0que.c @@ -802,13 +802,11 @@ que_thr_dec_refer_count( { que_fork_t* fork; trx_t* trx; - sess_t* sess; ulint fork_type; ibool stopped; fork = thr->common.parent; trx = thr_get_trx(thr); - sess = trx->sess; mutex_enter(&kernel_mutex); @@ -1292,18 +1290,13 @@ que_run_threads_low( que_thr_t* thr) /* in: query thread */ { que_thr_t* next_thr; - ulint cumul_resource; ulint loop_count; ut_ad(thr->state == QUE_THR_RUNNING); ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS); ut_ad(!mutex_own(&kernel_mutex)); - /* cumul_resource counts how much resources the OS thread (NOT the - query thread) has spent in this function */ - loop_count = QUE_MAX_LOOPS_WITHOUT_CHECK; - cumul_resource = 0; loop: /* Check that there is enough space in the log to accommodate possible log entries by this query step; if the operation can touch diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 4a834c4efc2..c5a3a2da9e2 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -555,6 +555,12 @@ handle_new_error: "forcing-recovery.html" " for help.\n", stderr); + } else if (err == DB_FOREIGN_EXCEED_MAX_CASCADE) { + fprintf(stderr, "InnoDB: Cannot delete/update rows with" + " cascading foreign key constraints that exceed max" + " depth of %lu\n" + "Please drop excessive foreign constraints" + " and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD); } else { fprintf(stderr, "InnoDB: unknown error code %lu\n", (ulong) err); @@ -1406,11 +1412,15 @@ row_update_for_mysql( run_again: thr->run_node = node; thr->prev_node = node; + thr->fk_cascade_depth = 0; row_upd_step(thr); err = trx->error_state; + /* Reset fk_cascade_depth back to 0 */ + thr->fk_cascade_depth = 0; + if (err != DB_SUCCESS) { que_thr_stop_for_mysql(thr); @@ -1447,7 +1457,12 @@ run_again: srv_n_rows_updated++; } - row_update_statistics_if_needed(prebuilt->table); + /* We update table statistics only if it is a DELETE or UPDATE + that changes indexed columns, UPDATEs that change only non-indexed + columns would not affect statistics. */ + if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { + row_update_statistics_if_needed(prebuilt->table); + } trx->op_info = ""; @@ -1597,12 +1612,27 @@ row_update_cascade_for_mysql( trx_t* trx; trx = thr_get_trx(thr); + + /* Increment fk_cascade_depth to record the recursive call depth on + a single update/delete that affects multiple tables chained + together with foreign key relations. */ + thr->fk_cascade_depth++; + + if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) { + return (DB_FOREIGN_EXCEED_MAX_CASCADE); + } run_again: thr->run_node = node; thr->prev_node = node; row_upd_step(thr); + /* The recursive call for cascading update/delete happens + in above row_upd_step(), reset the counter once we come + out of the recursive call, so it does not accumulate for + different row deletes */ + thr->fk_cascade_depth = 0; + err = trx->error_state; /* Note that the cascade node is a subnode of another InnoDB @@ -2129,7 +2159,7 @@ row_table_add_foreign_constraints( if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ - err = dict_load_foreigns(name, TRUE); + err = dict_load_foreigns(name, FALSE, TRUE); } if (err != DB_SUCCESS) { @@ -2814,6 +2844,15 @@ row_truncate_table_for_mysql( trx->table_id = table->id; + /* Lock all index trees for this table, as we will + truncate the table/index and possibly change their metadata. + All DML/DDL are blocked by table level lock, with + a few exceptions such as queries into information schema + about the table, MySQL could try to access index stats + for this kind of query, we need to use index locks to + sync up */ + dict_table_x_lock_indexes(table); + /* scan SYS_INDEXES for all indexes of the table */ heap = mem_heap_create(800); @@ -2886,6 +2925,10 @@ next_rec: mem_heap_free(heap); + /* Done with index truncation, release index tree locks, + subsequent work relates to table level metadata change */ + dict_table_x_unlock_indexes(table); + new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); info = pars_info_create(); @@ -3878,7 +3921,8 @@ end: an ALTER, not in a RENAME. */ err = dict_load_foreigns( - new_name, old_is_tmp ? trx->check_foreigns : TRUE); + new_name, FALSE, + old_is_tmp ? trx->check_foreigns : TRUE); if (err != DB_SUCCESS) { ut_print_timestamp(stderr); diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c index 1fef47da13f..deec3b0a454 100644 --- a/storage/innobase/row/row0purge.c +++ b/storage/innobase/row/row0purge.c @@ -667,7 +667,7 @@ row_purge_step( err = row_purge(node, thr); - ut_ad(err == DB_SUCCESS); + ut_a(err == DB_SUCCESS); return(thr); } diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 06a19ba7979..ecb2c492706 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -3259,6 +3259,7 @@ row_search_for_mysql( mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; + ibool table_lock_waited = FALSE; *offsets_ = (sizeof offsets_) / sizeof *offsets_; @@ -3599,6 +3600,44 @@ shortcut_fails_too_big_rec: clust_index = dict_table_get_first_index(index->table); + /* Do some start-of-statement preparations */ + + if (!prebuilt->sql_stat_start) { + /* No need to set an intention lock or assign a read view */ + + if (trx->read_view == NULL + && prebuilt->select_lock_type == LOCK_NONE) { + + fputs("InnoDB: Error: MySQL is trying to" + " perform a consistent read\n" + "InnoDB: but the read view is not assigned!\n", + stderr); + trx_print(stderr, trx, 600); + fputc('\n', stderr); + ut_error; + } + } else if (prebuilt->select_lock_type == LOCK_NONE) { + /* This is a consistent read */ + /* Assign a read view for the query */ + + trx_assign_read_view(trx); + prebuilt->sql_stat_start = FALSE; + } else { +wait_table_again: + err = lock_table(0, index->table, + prebuilt->select_lock_type == LOCK_S + ? LOCK_IS : LOCK_IX, thr); + + if (err != DB_SUCCESS) { + + table_lock_waited = TRUE; + goto lock_table_wait; + } + prebuilt->sql_stat_start = FALSE; + } + + /* Open or restore index cursor position */ + if (UNIV_LIKELY(direction != 0)) { ibool need_to_process = sel_restore_position_for_mysql( &same_user_rec, BTR_SEARCH_LEAF, @@ -3674,42 +3713,6 @@ shortcut_fails_too_big_rec: } } - if (!prebuilt->sql_stat_start) { - /* No need to set an intention lock or assign a read view */ - - if (trx->read_view == NULL - && prebuilt->select_lock_type == LOCK_NONE) { - - fputs("InnoDB: Error: MySQL is trying to" - " perform a consistent read\n" - "InnoDB: but the read view is not assigned!\n", - stderr); - trx_print(stderr, trx, 600); - fputc('\n', stderr); - ut_a(0); - } - } else if (prebuilt->select_lock_type == LOCK_NONE) { - /* This is a consistent read */ - /* Assign a read view for the query */ - - trx_assign_read_view(trx); - prebuilt->sql_stat_start = FALSE; - } else { - ulint lock_mode; - if (prebuilt->select_lock_type == LOCK_S) { - lock_mode = LOCK_IS; - } else { - lock_mode = LOCK_IX; - } - err = lock_table(0, index->table, lock_mode, thr); - - if (err != DB_SUCCESS) { - - goto lock_wait_or_error; - } - prebuilt->sql_stat_start = FALSE; - } - rec_loop: /*-------------------------------------------------------------*/ /* PHASE 4: Look for matching records in a loop */ @@ -4408,6 +4411,7 @@ lock_wait_or_error: btr_pcur_store_position(pcur, &mtr); +lock_table_wait: mtr_commit(&mtr); mtr_has_extra_clust_latch = FALSE; @@ -4425,6 +4429,14 @@ lock_wait_or_error: thr->lock_state = QUE_THR_LOCK_NOLOCK; mtr_start(&mtr); + /* Table lock waited, go try to obtain table lock + again */ + if (table_lock_waited) { + table_lock_waited = FALSE; + + goto wait_table_again; + } + sel_restore_position_for_mysql(&same_user_rec, BTR_SEARCH_LEAF, pcur, moves_up, &mtr); diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c index 68139da116e..a3333fcc536 100644 --- a/storage/innobase/row/row0umod.c +++ b/storage/innobase/row/row0umod.c @@ -89,12 +89,17 @@ row_undo_mod_clust_low( btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; +#ifdef UNIV_DEBUG ibool success; +#endif /* UNIV_DEBUG */ pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); - success = btr_pcur_restore_position(mode, pcur, mtr); +#ifdef UNIV_DEBUG + success = +#endif /* UNIV_DEBUG */ + btr_pcur_restore_position(mode, pcur, mtr); ut_ad(success); diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index c91cc449b96..034b7010410 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -2037,7 +2037,9 @@ row_upd_in_place_in_select( upd_node_t* node; btr_pcur_t* pcur; btr_cur_t* btr_cur; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; *offsets_ = (sizeof offsets_) / sizeof *offsets_; @@ -2074,8 +2076,11 @@ row_upd_in_place_in_select( ut_ad(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE); ut_ad(node->select_will_do_update); - err = btr_cur_update_in_place(BTR_NO_LOCKING_FLAG, btr_cur, - node->update, node->cmpl_info, - thr, mtr); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + btr_cur_update_in_place(BTR_NO_LOCKING_FLAG, btr_cur, + node->update, node->cmpl_info, + thr, mtr); ut_ad(err == DB_SUCCESS); } diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c index 03d9a2f1203..f4adfa855df 100644 --- a/storage/innobase/row/row0vers.c +++ b/storage/innobase/row/row0vers.c @@ -59,7 +59,9 @@ row_vers_impl_x_locked_off_kernel( trx_t* trx; ulint vers_del; ulint rec_del; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ mtr_t mtr; ulint comp; @@ -152,9 +154,12 @@ row_vers_impl_x_locked_off_kernel( heap2 = heap; heap = mem_heap_create(1024); - err = trx_undo_prev_version_build(clust_rec, &mtr, version, - clust_index, clust_offsets, - heap, &prev_version); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + trx_undo_prev_version_build(clust_rec, &mtr, version, + clust_index, clust_offsets, + heap, &prev_version); mem_heap_free(heap2); /* free version and clust_offsets */ if (prev_version) { diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index f0f300d918e..9e09efc82b2 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -249,9 +249,10 @@ trx_purge_add_update_undo_to_history( trx_undo_t* undo; trx_rseg_t* rseg; trx_rsegf_t* rseg_header; +#ifdef UNIV_DEBUG trx_usegf_t* seg_header; +#endif /* UNIV_DEBUG */ trx_ulogf_t* undo_header; - trx_upagef_t* page_header; ulint hist_size; undo = trx->update_undo; @@ -265,8 +266,9 @@ trx_purge_add_update_undo_to_history( rseg_header = trx_rsegf_get(rseg->space, rseg->page_no, mtr); undo_header = undo_page + undo->hdr_offset; +#ifdef UNIV_DEBUG seg_header = undo_page + TRX_UNDO_SEG_HDR; - page_header = undo_page + TRX_UNDO_PAGE_HDR; +#endif /* UNIV_DEBUG */ if (undo->state != TRX_UNDO_CACHED) { /* The undo log segment will not be reused */ @@ -594,7 +596,6 @@ trx_purge_rseg_get_next_history_log( { page_t* undo_page; trx_ulogf_t* log_hdr; - trx_usegf_t* seg_hdr; fil_addr_t prev_log_addr; dulint trx_no; ibool del_marks; @@ -615,7 +616,6 @@ trx_purge_rseg_get_next_history_log( undo_page = trx_undo_page_get_s_latched(rseg->space, rseg->last_page_no, &mtr); log_hdr = undo_page + rseg->last_offset; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; /* Increase the purge page count by one for every handled log */ @@ -1004,12 +1004,8 @@ trx_purge_rec_release( /*==================*/ trx_undo_inf_t* cell) /* in: storage cell */ { - trx_undo_arr_t* arr; - mutex_enter(&(purge_sys->mutex)); - arr = purge_sys->arr; - trx_purge_arr_remove_info(cell); mutex_exit(&(purge_sys->mutex)); diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index 8934fe87c7e..285e30796a5 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -713,13 +713,8 @@ trx_undo_arr_remove_info( dulint undo_no)/* in: undo number */ { trx_undo_inf_t* cell; - ulint n_used; - ulint n; ulint i; - n_used = arr->n_used; - n = 0; - for (i = 0;; i++) { cell = trx_undo_arr_get_nth_info(arr, i); diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index f732aca93f5..137771b71ed 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -165,7 +165,9 @@ trx_sys_create_doublewrite_buf(void) { page_t* page; page_t* page2; +#ifdef UNIV_SYNC_DEBUG page_t* new_page; +#endif /* UNIV_SYNC_DEBUG */ byte* doublewrite; byte* fseg_header; ulint page_no; @@ -271,8 +273,11 @@ start_again: the page position in the tablespace, then the page has not been written to in doublewrite. */ - new_page = buf_page_get(TRX_SYS_SPACE, page_no, - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + new_page = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(TRX_SYS_SPACE, page_no, + RW_X_LATCH, &mtr); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(new_page, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 545226a5994..21f75e0818f 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -1827,7 +1827,6 @@ trx_prepare_off_kernel( /*===================*/ trx_t* trx) /* in: transaction */ { - page_t* update_hdr_page; trx_rseg_t* rseg; ibool must_flush_log = FALSE; dulint lsn; @@ -1863,7 +1862,7 @@ trx_prepare_off_kernel( } if (trx->update_undo) { - update_hdr_page = trx_undo_set_state_at_prepare( + trx_undo_set_state_at_prepare( trx, trx->update_undo, &mtr); } diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index deb6c85e6e3..4547ee9ea64 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1012,14 +1012,11 @@ trx_undo_truncate_end( ulint last_page_no; trx_undo_rec_t* rec; trx_undo_rec_t* trunc_here; - trx_rseg_t* rseg; mtr_t mtr; ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(mutex_own(&(trx->rseg->mutex))); - rseg = trx->rseg; - for (;;) { mtr_start(&mtr); @@ -1798,7 +1795,6 @@ trx_undo_set_state_at_prepare( mtr_t* mtr) /* in: mtr */ { trx_usegf_t* seg_hdr; - trx_upagef_t* page_hdr; trx_ulogf_t* undo_header; page_t* undo_page; ulint offset; @@ -1815,7 +1811,6 @@ trx_undo_set_state_at_prepare( undo_page = trx_undo_page_get(undo->space, undo->hdr_page_no, mtr); seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; /*------------------------------*/ undo->state = TRX_UNDO_PREPARED; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 3e802360d23..c185215e65f 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,51 @@ +2010-10-11 The InnoDB Team + * row/row0sel.c + Fix Bug #57345 btr_pcur_store_position abort for load with + concurrent lock/unlock tables + +2010-10-06 The InnoDB Team + * row/row0mysql.c, innodb_bug57255.result, innodb_bug57255.test + Fix Bug #Cascade Delete results in "Got error -1 from storage engine" + +2010-09-27 The InnoDB Team + + * row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test: + Fix Bug #56716 InnoDB locks a record gap without locking the table + +2010-09-06 The InnoDB Team + * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result + Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery + +2010-08-24 The InnoDB Team + + * handler/ha_innodb.c, dict/dict0dict.c: + Fix Bug #55832 selects crash too easily when innodb_force_recovery>3 + +2010-08-03 The InnoDB Team + + * include/dict0dict.h, include/dict0dict.ic, row/row0mysql.c: + Fix bug #54678, InnoDB, TRUNCATE, ALTER, I_S SELECT, crash or deadlock + +2010-08-03 The InnoDB Team + + * dict/dict0load.c, handler/ha_innodb.cc, include/db0err.h, + include/dict0load.h, include/dict0mem.h, include/que0que.h, + row/row0merge.c, row/row0mysql.c: + Fix Bug#54582 stack overflow when opening many tables linked + with foreign keys at once + +2010-08-03 The InnoDB Team + + * include/ut0mem.h, ut/ut0mem.c: + Fix Bug #55627 segv in ut_free pars_lexer_close innobase_shutdown + innodb-use-sys-malloc=0 + +2010-08-01 The InnoDB Team + + * handler/ha_innodb.cc + Fix Bug #55382 Assignment with SELECT expressions takes unexpected + S locks in READ COMMITTED + 2010-07-27 The InnoDB Team * include/mem0pool.h, mem/mem0mem.c, mem/mem0pool.c, srv/srv0start.c: diff --git a/storage/innodb_plugin/Makefile.am b/storage/innodb_plugin/Makefile.am index f11e5db01f4..1b02b4eceb8 100644 --- a/storage/innodb_plugin/Makefile.am +++ b/storage/innodb_plugin/Makefile.am @@ -228,9 +228,8 @@ noinst_HEADERS= \ include/ut0wqueue.h \ mem/mem0dbg.c -EXTRA_LIBRARIES= libinnobase.a -noinst_LIBRARIES= @plugin_innodb_plugin_static_target@ -libinnobase_a_SOURCES= \ +noinst_LTLIBRARIES= @plugin_innodb_plugin_static_target@ +libinnobase_la_SOURCES= \ btr/btr0btr.c \ btr/btr0cur.c \ btr/btr0pcur.c \ @@ -325,16 +324,16 @@ libinnobase_a_SOURCES= \ ut/ut0vec.c \ ut/ut0wqueue.c -libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS) -libinnobase_a_CFLAGS= $(AM_CFLAGS) +libinnobase_la_CXXFLAGS= $(AM_CXXFLAGS) +libinnobase_la_CFLAGS= $(AM_CFLAGS) -EXTRA_LTLIBRARIES= ha_innodb_plugin.la +EXTRA_LTLIBRARIES= libinnobase.la ha_innodb_plugin.la pkgplugin_LTLIBRARIES= @plugin_innodb_plugin_shared_target@ ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir) -ha_innodb_plugin_la_CXXFLAGS= $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) -ha_innodb_plugin_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) -ha_innodb_plugin_la_SOURCES= $(libinnobase_a_SOURCES) +ha_innodb_plugin_la_CXXFLAGS= -shared $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) +ha_innodb_plugin_la_CFLAGS= -shared $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) +ha_innodb_plugin_la_SOURCES= $(libinnobase_la_SOURCES) EXTRA_DIST= CMakeLists.txt plug.in \ pars/make_bison.sh pars/make_flex.sh \ diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index 02677e0a71c..29cd470e650 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -1895,7 +1895,6 @@ btr_page_split_and_insert( buf_block_t* left_block; buf_block_t* right_block; buf_block_t* insert_block; - page_t* insert_page; page_cur_t* page_cursor; rec_t* first_rec; byte* buf = 0; /* remove warning */ @@ -2153,8 +2152,6 @@ insert_empty: insert_block = right_block; } - insert_page = buf_block_get_frame(insert_block); - /* 7. Reposition the cursor for insert and try insertion */ page_cursor = btr_cur_get_page_cur(cursor); @@ -2166,8 +2163,12 @@ insert_empty: #ifdef UNIV_ZIP_DEBUG { + page_t* insert_page + = buf_block_get_frame(insert_block); + page_zip_des_t* insert_page_zip = buf_block_get_page_zip(insert_block); + ut_a(!insert_page_zip || page_zip_validate(insert_page_zip, insert_page)); } @@ -2560,7 +2561,6 @@ btr_compress( ulint n_recs; ulint max_ins_size; ulint max_ins_size_reorg; - ulint level; block = btr_cur_get_block(cursor); page = btr_cur_get_page(cursor); @@ -2570,7 +2570,6 @@ btr_compress( ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); - level = btr_page_get_level(page, mtr); space = dict_index_get_space(index); zip_size = dict_table_zip_size(index->table); diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 7fa7d42320a..9812e91e8a5 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -1836,7 +1836,6 @@ btr_cur_optimistic_update( page_t* page; page_zip_des_t* page_zip; rec_t* rec; - rec_t* orig_rec; ulint max_size; ulint new_rec_size; ulint old_rec_size; @@ -1850,7 +1849,7 @@ btr_cur_optimistic_update( block = btr_cur_get_block(cursor); page = buf_block_get_frame(block); - orig_rec = rec = btr_cur_get_rec(cursor); + rec = btr_cur_get_rec(cursor); index = cursor->index; ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); @@ -3484,9 +3483,10 @@ btr_cur_set_ownership_of_extern_field( Marks not updated extern fields as not-owned by this record. The ownership is transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. */ +to free the field. +@return TRUE if BLOB ownership was transferred */ UNIV_INTERN -void +ibool btr_cur_mark_extern_inherited_fields( /*=================================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed @@ -3500,13 +3500,14 @@ btr_cur_mark_extern_inherited_fields( ulint n; ulint j; ulint i; + ibool change_ownership = FALSE; ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); if (!rec_offs_any_extern(offsets)) { - return; + return(FALSE); } n = rec_offs_n_fields(offsets); @@ -3529,10 +3530,14 @@ btr_cur_mark_extern_inherited_fields( btr_cur_set_ownership_of_extern_field( page_zip, rec, index, offsets, i, FALSE, mtr); + + change_ownership = TRUE; updated: ; } } + + return(change_ownership); } /*******************************************************************//** @@ -4279,12 +4284,17 @@ btr_free_externally_stored_field( } for (;;) { +#ifdef UNIV_SYNC_DEBUG buf_block_t* rec_block; +#endif /* UNIV_SYNC_DEBUG */ buf_block_t* ext_block; mtr_start(&mtr); - rec_block = buf_page_get(page_get_space_id( +#ifdef UNIV_SYNC_DEBUG + rec_block = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(page_get_space_id( page_align(field_ref)), rec_zip_size, page_get_page_no( diff --git a/storage/innodb_plugin/btr/btr0pcur.c b/storage/innodb_plugin/btr/btr0pcur.c index 658901208ef..056896c7927 100644 --- a/storage/innodb_plugin/btr/btr0pcur.c +++ b/storage/innodb_plugin/btr/btr0pcur.c @@ -452,7 +452,6 @@ btr_pcur_move_backward_from_page( mtr_t* mtr) /*!< in: mtr */ { ulint prev_page_no; - ulint space; page_t* page; buf_block_t* prev_block; ulint latch_mode; @@ -488,7 +487,6 @@ btr_pcur_move_backward_from_page( page = btr_pcur_get_page(cursor); prev_page_no = btr_page_get_prev(page, mtr); - space = buf_block_get_space(btr_pcur_get_block(cursor)); if (prev_page_no == FIL_NULL) { } else if (btr_pcur_is_before_first_on_page(cursor)) { diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c index ac7248fef20..035fdbb61d2 100644 --- a/storage/innodb_plugin/btr/btr0sea.c +++ b/storage/innodb_plugin/btr/btr0sea.c @@ -1495,7 +1495,6 @@ btr_search_update_hash_on_delete( rec_t* rec; ulint fold; dulint index_id; - ibool found; ulint offsets_[REC_OFFS_NORMAL_SIZE]; mem_heap_t* heap = NULL; rec_offs_init(offsets_); @@ -1528,7 +1527,7 @@ btr_search_update_hash_on_delete( } rw_lock_x_lock(&btr_search_latch); - found = ha_search_and_delete_if_found(table, fold, rec); + ha_search_and_delete_if_found(table, fold, rec); rw_lock_x_unlock(&btr_search_latch); } @@ -1734,6 +1733,7 @@ function_exit: } } +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /********************************************************************//** Validates the search system. @return TRUE if ok */ @@ -1897,3 +1897,4 @@ btr_search_validate(void) return(ok); } +#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c index d8c0497fa1e..747ce65879d 100644 --- a/storage/innodb_plugin/buf/buf0flu.c +++ b/storage/innodb_plugin/buf/buf0flu.c @@ -128,10 +128,15 @@ buf_flush_delete_from_flush_rbt( buf_page_t* bpage) /*!< in: bpage to be removed. */ { +#ifdef UNIV_DEBUG ibool ret = FALSE; +#endif /* UNIV_DEBUG */ ut_ad(buf_pool_mutex_own()); - ret = rbt_delete(buf_pool->flush_rbt, &bpage); +#ifdef UNIV_DEBUG + ret = +#endif /* UNIV_DEBUG */ + rbt_delete(buf_pool->flush_rbt, &bpage); ut_ad(ret); } @@ -1266,7 +1271,6 @@ buf_flush_batch( { buf_page_t* bpage; ulint page_count = 0; - ulint old_page_count; ulint space; ulint offset; @@ -1338,15 +1342,9 @@ flush_next: buf_pool_mutex_exit(); - old_page_count = page_count; - /* Try to flush also all the neighbors */ page_count += buf_flush_try_neighbors( space, offset, flush_type); - /* fprintf(stderr, - "Flush type %lu, page no %lu, neighb %lu\n", - flush_type, offset, - page_count - old_page_count); */ buf_pool_mutex_enter(); goto flush_next; diff --git a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/dict0crea.c index 09353c45c8c..e63f8bc3e6a 100644 --- a/storage/innodb_plugin/dict/dict0crea.c +++ b/storage/innodb_plugin/dict/dict0crea.c @@ -627,7 +627,6 @@ dict_create_index_tree_step( { dict_index_t* index; dict_table_t* sys_indexes; - dict_table_t* table; dtuple_t* search_tuple; ulint zip_size; btr_pcur_t pcur; @@ -636,7 +635,6 @@ dict_create_index_tree_step( ut_ad(mutex_own(&(dict_sys->mutex))); index = node->index; - table = node->table; sys_indexes = dict_sys->sys_indexes; diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index fe4e058e122..a3575c283cd 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -568,8 +568,7 @@ dict_table_get_on_id( { dict_table_t* table; - if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 - || trx->dict_operation_lock_mode == RW_X_LATCH) { + if (trx->dict_operation_lock_mode == RW_X_LATCH) { /* Note: An X latch implies that the transaction already owns the dictionary mutex. */ @@ -4192,7 +4191,6 @@ dict_update_statistics_low( dictionary mutex */ { dict_index_t* index; - ulint size; ulint sum_of_index_sizes = 0; if (table->ibd_file_missing) { @@ -4207,14 +4205,6 @@ dict_update_statistics_low( return; } - /* If we have set a high innodb_force_recovery level, do not calculate - statistics, as a badly corrupted index can cause a crash in it. */ - - if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - - return; - } - /* Find out the sizes of the indexes and how many different values for the key they approximately have */ @@ -4226,26 +4216,48 @@ dict_update_statistics_low( return; } - while (index) { - size = btr_get_size(index, BTR_TOTAL_SIZE); - index->stat_index_size = size; + do { + if (UNIV_LIKELY + (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE + || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO + && dict_index_is_clust(index)))) { + ulint size; + size = btr_get_size(index, BTR_TOTAL_SIZE); - sum_of_index_sizes += size; + index->stat_index_size = size; - size = btr_get_size(index, BTR_N_LEAF_PAGES); + sum_of_index_sizes += size; - if (size == 0) { - /* The root node of the tree is a leaf */ - size = 1; - } + size = btr_get_size(index, BTR_N_LEAF_PAGES); - index->stat_n_leaf_pages = size; + if (size == 0) { + /* The root node of the tree is a leaf */ + size = 1; + } - btr_estimate_number_of_different_key_vals(index); + index->stat_n_leaf_pages = size; + + btr_estimate_number_of_different_key_vals(index); + } else { + /* If we have set a high innodb_force_recovery + level, do not calculate statistics, as a badly + corrupted index can cause a crash in it. + Initialize some bogus index cardinality + statistics, so that the data can be queried in + various means, also via secondary indexes. */ + ulint i; + + sum_of_index_sizes++; + index->stat_index_size = index->stat_n_leaf_pages = 1; + + for (i = dict_index_get_n_unique(index); i; ) { + index->stat_n_diff_key_vals[i--] = 1; + } + } index = dict_table_get_next_index(index); - } + } while (index); index = dict_table_get_first_index(table); @@ -4429,7 +4441,6 @@ dict_index_print_low( { ib_int64_t n_vals; ulint i; - const char* type_string; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -4444,14 +4455,6 @@ dict_index_print_low( dict_index_stat_mutex_exit(index); - if (dict_index_is_clust(index)) { - type_string = "clustered index"; - } else if (dict_index_is_unique(index)) { - type_string = "unique index"; - } else { - type_string = "secondary index"; - } - fprintf(stderr, " INDEX: name %s, id %lu %lu, fields %lu/%lu," " uniq %lu, type %lu\n" diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index 3c495d21786..b046fb32b0b 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -1009,16 +1009,27 @@ err_exit: err = dict_load_indexes(table, heap); + /* Initialize table foreign_child value. Its value could be + changed when dict_load_foreigns() is called below */ + table->fk_max_recusive_level = 0; + /* If the force recovery flag is set, we open the table irrespective of the error condition, since the user may want to dump data from the clustered index. However we load the foreign key information only if all indexes were loaded. */ if (err == DB_SUCCESS) { - err = dict_load_foreigns(table->name, TRUE); + err = dict_load_foreigns(table->name, TRUE, TRUE); + + if (err != DB_SUCCESS) { + dict_table_remove_from_cache(table); + table = NULL; + } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } + + table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { @@ -1072,6 +1083,8 @@ dict_load_table_on_id( ut_ad(mutex_own(&(dict_sys->mutex))); + table = NULL; + /* NOTE that the operation of this function is protected by the dictionary mutex, and therefore no deadlocks can occur with other dictionary operations. */ @@ -1098,15 +1111,17 @@ dict_load_table_on_id( BTR_SEARCH_LEAF, &pcur, &mtr); rec = btr_pcur_get_rec(&pcur); - if (!btr_pcur_is_on_user_rec(&pcur) - || rec_get_deleted_flag(rec, 0)) { + if (!btr_pcur_is_on_user_rec(&pcur)) { /* Not found */ + goto func_exit; + } - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap); - - return(NULL); + /* Find the first record that is not delete marked */ + while (rec_get_deleted_flag(rec, 0)) { + if (!btr_pcur_move_to_next_user_rec(&pcur, &mtr)) { + goto func_exit; + } + rec = btr_pcur_get_rec(&pcur); } /*---------------------------------------------------*/ @@ -1119,19 +1134,14 @@ dict_load_table_on_id( /* Check if the table id in record is the one searched for */ if (ut_dulint_cmp(table_id, mach_read_from_8(field)) != 0) { - - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap); - - return(NULL); + goto func_exit; } /* Now we get the table name from the record */ field = rec_get_nth_field_old(rec, 1, &len); /* Load the table definition to memory */ table = dict_load_table(mem_heap_strdupl(heap, (char*) field, len)); - +func_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); @@ -1241,8 +1251,12 @@ dict_load_foreign( /*==============*/ const char* id, /*!< in: foreign constraint id as a null-terminated string */ - ibool check_charsets) + ibool check_charsets, /*!< in: TRUE=check charset compatibility */ + ibool check_recursive) + /*!< in: Whether to record the foreign table + parent count to avoid unlimited recursive + load of chained foreign tables */ { dict_foreign_t* foreign; dict_table_t* sys_foreign; @@ -1256,6 +1270,8 @@ dict_load_foreign( ulint len; ulint n_fields_and_type; mtr_t mtr; + dict_table_t* for_table; + dict_table_t* ref_table; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1340,11 +1356,54 @@ dict_load_foreign( dict_load_foreign_cols(id, foreign); - /* If the foreign table is not yet in the dictionary cache, we - have to load it so that we are able to make type comparisons - in the next function call. */ - - dict_table_get_low(foreign->foreign_table_name); + ref_table = dict_table_check_if_in_cache_low( + foreign->referenced_table_name); + + /* We could possibly wind up in a deep recursive calls if + we call dict_table_get_low() again here if there + is a chain of tables concatenated together with + foreign constraints. In such case, each table is + both a parent and child of the other tables, and + act as a "link" in such table chains. + To avoid such scenario, we would need to check the + number of ancesters the current table has. If that + exceeds DICT_FK_MAX_CHAIN_LEN, we will stop loading + the child table. + Foreign constraints are loaded in a Breath First fashion, + that is, the index on FOR_NAME is scanned first, and then + index on REF_NAME. So foreign constrains in which + current table is a child (foreign table) are loaded first, + and then those constraints where current table is a + parent (referenced) table. + Thus we could check the parent (ref_table) table's + reference count (fk_max_recusive_level) to know how deep the + recursive call is. If the parent table (ref_table) is already + loaded, and its fk_max_recusive_level is larger than + DICT_FK_MAX_CHAIN_LEN, we will stop the recursive loading + by skipping loading the child table. It will not affect foreign + constraint check for DMLs since child table will be loaded + at that time for the constraint check. */ + if (!ref_table + || ref_table->fk_max_recusive_level < DICT_FK_MAX_RECURSIVE_LOAD) { + + /* If the foreign table is not yet in the dictionary cache, we + have to load it so that we are able to make type comparisons + in the next function call. */ + + for_table = dict_table_get_low(foreign->foreign_table_name); + + if (for_table && ref_table && check_recursive) { + /* This is to record the longest chain of ancesters + this table has, if the parent has more ancesters + than this table has, record it after add 1 (for this + parent */ + if (ref_table->fk_max_recusive_level + >= for_table->fk_max_recusive_level) { + for_table->fk_max_recusive_level = + ref_table->fk_max_recusive_level + 1; + } + } + } /* Note that there may already be a foreign constraint object in the dictionary cache for this constraint: then the following @@ -1369,6 +1428,8 @@ ulint dict_load_foreigns( /*===============*/ const char* table_name, /*!< in: table name */ + ibool check_recursive,/*!< in: Whether to check recursive + load of tables chained by FK */ ibool check_charsets) /*!< in: TRUE=check charset compatibility */ { @@ -1470,7 +1531,7 @@ loop: /* Load the foreign constraint definition to the dictionary cache */ - err = dict_load_foreign(id, check_charsets); + err = dict_load_foreign(id, check_charsets, check_recursive); if (err != DB_SUCCESS) { btr_pcur_close(&pcur); @@ -1498,6 +1559,11 @@ load_next_index: mtr_start(&mtr); + /* Switch to scan index on REF_NAME, fk_max_recusive_level + already been updated when scanning FOR_NAME index, no need to + update again */ + check_recursive = FALSE; + goto start_load; } diff --git a/storage/innodb_plugin/eval/eval0eval.c b/storage/innodb_plugin/eval/eval0eval.c index 589b0fa1576..dcd416adeee 100644 --- a/storage/innodb_plugin/eval/eval0eval.c +++ b/storage/innodb_plugin/eval/eval0eval.c @@ -384,18 +384,13 @@ eval_notfound( /*==========*/ func_node_t* func_node) /*!< in: function node */ { - que_node_t* arg1; - que_node_t* arg2; sym_node_t* cursor; sel_node_t* sel_node; ibool ibool_val; - arg1 = func_node->args; - arg2 = que_node_get_next(arg1); - ut_ad(func_node->func == PARS_NOTFOUND_TOKEN); - cursor = arg1; + cursor = func_node->args; ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL); diff --git a/storage/innodb_plugin/ha/ha0ha.c b/storage/innodb_plugin/ha/ha0ha.c index f9e798012f8..7f11917de0a 100644 --- a/storage/innodb_plugin/ha/ha0ha.c +++ b/storage/innodb_plugin/ha/ha0ha.c @@ -354,6 +354,7 @@ ha_remove_all_nodes_to_page( #endif } +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /*************************************************************//** Validates a given range of the cells in hash table. @return TRUE if ok */ @@ -400,6 +401,7 @@ ha_validate( return(ok); } +#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ /*************************************************************//** Prints info of a hash table. */ diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 2adaabd0480..e6305d8e38a 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -767,6 +767,19 @@ convert_error_code_to_mysql( case DB_INTERRUPTED: my_error(ER_QUERY_INTERRUPTED, MYF(0)); /* fall through */ + + case DB_FOREIGN_EXCEED_MAX_CASCADE: + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_ROW_IS_REFERENCED, + "InnoDB: Cannot delete/update " + "rows with cascading foreign key " + "constraints that exceed max " + "depth of %d. Please " + "drop extra constraints and try " + "again", DICT_FK_MAX_RECURSIVE_LOAD); + + /* fall through */ + case DB_ERROR: default: return(-1); /* unspecified error */ @@ -3348,12 +3361,19 @@ ha_innobase::innobase_initialize_autoinc() err = row_search_max_autoinc(index, col_name, &read_auto_inc); switch (err) { - case DB_SUCCESS: + case DB_SUCCESS: { + ulonglong col_max_value; + + col_max_value = innobase_get_int_col_max_value(field); + /* At the this stage we do not know the increment - or the offset, so use a default increment of 1. */ - auto_inc = read_auto_inc + 1; - break; + nor the offset, so use a default increment of 1. */ + auto_inc = innobase_next_autoinc( + read_auto_inc, 1, 1, col_max_value); + + break; + } case DB_RECORD_NOT_FOUND: ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: MySQL and InnoDB data " @@ -3648,8 +3668,6 @@ retry: dict_table_get_format(prebuilt->table)); } - info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); - /* Only if the table has an AUTOINC column. */ if (prebuilt->table != NULL && table->found_next_number_field != NULL) { dict_table_autoinc_lock(prebuilt->table); @@ -3666,6 +3684,8 @@ retry: dict_table_autoinc_unlock(prebuilt->table); } + info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); + DBUG_RETURN(0); } @@ -7008,7 +7028,6 @@ innobase_drop_database( ulint len = 0; trx_t* trx; char* ptr; - int error; char* namebuf; THD* thd = current_thd; @@ -7051,7 +7070,7 @@ innobase_drop_database( #else trx = innobase_trx_allocate(thd); #endif - error = row_drop_database_for_mysql(namebuf, trx); + row_drop_database_for_mysql(namebuf, trx); my_free(namebuf, MYF(0)); /* Flush the log to reduce probability that the .frm files and @@ -7512,28 +7531,15 @@ ha_innobase::info( dict_index_t* index; ha_rows rec_per_key; ib_int64_t n_rows; - ulong j; - ulong i; char path[FN_REFLEN]; os_file_stat_t stat_info; - DBUG_ENTER("info"); /* If we are forcing recovery at a high level, we will suppress statistics calculation on tables, because that may crash the server if an index is badly corrupted. */ - if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - - /* We return success (0) instead of HA_ERR_CRASHED, - because we want MySQL to process this query and not - stop, like it would do if it received the error code - HA_ERR_CRASHED. */ - - DBUG_RETURN(0); - } - /* We do not know if MySQL can call this function before calling external_lock(). To be safe, update the thd of the current table handle. */ @@ -7628,12 +7634,18 @@ ha_innobase::info( acquiring latches inside InnoDB, we do not call it if we are asked by MySQL to avoid locking. Another reason to avoid the call is that it uses quite a lot of CPU. - See Bug#38185. - We do not update delete_length if no locking is requested - so the "old" value can remain. delete_length is initialized - to 0 in the ha_statistics' constructor. */ - if (!(flag & HA_STATUS_NO_LOCK)) { - + See Bug#38185. */ + if (flag & HA_STATUS_NO_LOCK) { + /* We do not update delete_length if no + locking is requested so the "old" value can + remain. delete_length is initialized to 0 in + the ha_statistics' constructor. */ + } else if (UNIV_UNLIKELY + (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) { + /* Avoid accessing the tablespace if + innodb_crash_recovery is set to a high value. */ + stats.delete_length = 0; + } else { /* lock the data dictionary to avoid races with ibd_file_missing and tablespace_discarded */ row_mysql_lock_data_dictionary(prebuilt->trx); @@ -7678,6 +7690,7 @@ ha_innobase::info( } if (flag & HA_STATUS_CONST) { + ulong i; /* Verify the number of index in InnoDB and MySQL matches up. If prebuilt->clust_index_was_generated holds, InnoDB defines GEN_CLUST_INDEX internally */ @@ -7694,6 +7707,7 @@ ha_innobase::info( } for (i = 0; i < table->s->keys; i++) { + ulong j; /* We could get index quickly through internal index mapping with the index translation table. The identity of index (match up index name with @@ -7759,6 +7773,11 @@ ha_innobase::info( } } + if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { + + goto func_exit; + } + if (flag & HA_STATUS_ERRKEY) { const dict_index_t* err_index; @@ -7779,6 +7798,7 @@ ha_innobase::info( stats.auto_increment_value = innobase_peek_autoinc(); } +func_exit: prebuilt->trx->op_info = (char*)""; DBUG_RETURN(0); @@ -8848,12 +8868,9 @@ innodb_show_status( mutex_exit(&srv_monitor_file_mutex); - bool result = FALSE; + stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), + STRING_WITH_LEN(""), str, flen); - if (stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), - STRING_WITH_LEN(""), str, flen)) { - result= TRUE; - } my_free(str, MYF(0)); DBUG_RETURN(FALSE); @@ -9236,7 +9253,8 @@ ha_innobase::store_lock( && (sql_command == SQLCOM_INSERT_SELECT || sql_command == SQLCOM_REPLACE_SELECT || sql_command == SQLCOM_UPDATE - || sql_command == SQLCOM_CREATE_TABLE)) { + || sql_command == SQLCOM_CREATE_TABLE + || sql_command == SQLCOM_SET_OPTION)) { /* If we either have innobase_locks_unsafe_for_binlog option set or this session is using READ COMMITTED @@ -9244,9 +9262,9 @@ ha_innobase::store_lock( is not set to serializable and MySQL is doing INSERT INTO...SELECT or REPLACE INTO...SELECT or UPDATE ... = (SELECT ...) or CREATE ... - SELECT... without FOR UPDATE or IN SHARE - MODE in select, then we use consistent read - for select. */ + SELECT... or SET ... = (SELECT ...) without + FOR UPDATE or IN SHARE MODE in select, + then we use consistent read for select. */ prebuilt->select_lock_type = LOCK_NONE; prebuilt->stored_select_lock_type = LOCK_NONE; diff --git a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc index 524fe696de2..9ad2d656365 100644 --- a/storage/innodb_plugin/handler/i_s.cc +++ b/storage/innodb_plugin/handler/i_s.cc @@ -1012,6 +1012,7 @@ trx_i_s_common_fill_table( deadlock occurs between the mysqld server and mysql client, see http://bugs.mysql.com/29900 ; when that bug is resolved we can enable the DBUG_RETURN(ret) above */ + ret++; // silence a gcc46 warning DBUG_RETURN(0); #endif } diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h index 7dc2eb63cf5..e151fdcb563 100644 --- a/storage/innodb_plugin/include/btr0cur.h +++ b/storage/innodb_plugin/include/btr0cur.h @@ -468,9 +468,10 @@ btr_estimate_number_of_different_key_vals( Marks not updated extern fields as not-owned by this record. The ownership is transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. */ +to free the field. +@return TRUE if BLOB ownership was transferred */ UNIV_INTERN -void +ibool btr_cur_mark_extern_inherited_fields( /*=================================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed diff --git a/storage/innodb_plugin/include/btr0sea.h b/storage/innodb_plugin/include/btr0sea.h index 20a2be7f877..6493689a969 100644 --- a/storage/innodb_plugin/include/btr0sea.h +++ b/storage/innodb_plugin/include/btr0sea.h @@ -180,6 +180,7 @@ btr_search_update_hash_on_delete( btr_cur_t* cursor);/*!< in: cursor which was positioned on the record to delete using btr_cur_search_..., the record is not yet deleted */ +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /********************************************************************//** Validates the search system. @return TRUE if ok */ @@ -187,6 +188,9 @@ UNIV_INTERN ibool btr_search_validate(void); /*======================*/ +#else +# define btr_search_validate() TRUE +#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ /** Flag: has the search system been enabled? Protected by btr_search_latch and btr_search_enabled_mutex. */ diff --git a/storage/innodb_plugin/include/db0err.h b/storage/innodb_plugin/include/db0err.h index c841c2b4afe..c7fa6d2a444 100644 --- a/storage/innodb_plugin/include/db0err.h +++ b/storage/innodb_plugin/include/db0err.h @@ -94,6 +94,9 @@ enum db_err { DB_PRIMARY_KEY_IS_NULL, /* a column in the PRIMARY KEY was found to be NULL */ + DB_FOREIGN_EXCEED_MAX_CASCADE, /* Foreign key constraint related + cascading delete/update exceeds + maximum allowed depth */ /* The following are partial failure codes */ DB_FAIL = 1000, diff --git a/storage/innodb_plugin/include/dict0dict.h b/storage/innodb_plugin/include/dict0dict.h index 3a1bee4cd89..5ffa59538c8 100644 --- a/storage/innodb_plugin/include/dict0dict.h +++ b/storage/innodb_plugin/include/dict0dict.h @@ -680,6 +680,22 @@ ulint dict_table_zip_size( /*================*/ const dict_table_t* table); /*!< in: table */ +/*********************************************************************//** +Obtain exclusive locks on all index trees of the table. This is to prevent +accessing index trees while InnoDB is updating internal metadata for +operations such as truncate tables. */ +UNIV_INLINE +void +dict_table_x_lock_indexes( +/*======================*/ + dict_table_t* table); /*!< in: table */ +/*********************************************************************//** +Release the exclusive locks on all index tree. */ +UNIV_INLINE +void +dict_table_x_unlock_indexes( +/*========================*/ + dict_table_t* table); /*!< in: table */ /********************************************************************//** Checks if a column is in the ordering columns of the clustered index of a table. Column prefixes are treated like whole columns. diff --git a/storage/innodb_plugin/include/dict0dict.ic b/storage/innodb_plugin/include/dict0dict.ic index 46e78df8272..1704e9c2d71 100644 --- a/storage/innodb_plugin/include/dict0dict.ic +++ b/storage/innodb_plugin/include/dict0dict.ic @@ -452,6 +452,48 @@ dict_table_zip_size( return(dict_table_flags_to_zip_size(table->flags)); } +/*********************************************************************//** +Obtain exclusive locks on all index trees of the table. This is to prevent +accessing index trees while InnoDB is updating internal metadata for +operations such as truncate tables. */ +UNIV_INLINE +void +dict_table_x_lock_indexes( +/*======================*/ + dict_table_t* table) /*!< in: table */ +{ + dict_index_t* index; + + ut_a(table); + ut_ad(mutex_own(&(dict_sys->mutex))); + + /* Loop through each index of the table and lock them */ + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_lock(dict_index_get_lock(index)); + } +} + +/*********************************************************************//** +Release the exclusive locks on all index tree. */ +UNIV_INLINE +void +dict_table_x_unlock_indexes( +/*========================*/ + dict_table_t* table) /*!< in: table */ +{ + dict_index_t* index; + + ut_a(table); + ut_ad(mutex_own(&(dict_sys->mutex))); + + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_unlock(dict_index_get_lock(index)); + } +} /********************************************************************//** Gets the number of fields in the internal representation of an index, including fields added by the dictionary system. diff --git a/storage/innodb_plugin/include/dict0load.h b/storage/innodb_plugin/include/dict0load.h index 60b8c1fb632..f41882019d5 100644 --- a/storage/innodb_plugin/include/dict0load.h +++ b/storage/innodb_plugin/include/dict0load.h @@ -97,6 +97,8 @@ ulint dict_load_foreigns( /*===============*/ const char* table_name, /*!< in: table name */ + ibool check_recursive,/*!< in: Whether to check recursive + load of tables chained by FK */ ibool check_charsets);/*!< in: TRUE=check charsets compatibility */ /********************************************************************//** diff --git a/storage/innodb_plugin/include/dict0mem.h b/storage/innodb_plugin/include/dict0mem.h index 2fce1e00927..19782c2e76a 100644 --- a/storage/innodb_plugin/include/dict0mem.h +++ b/storage/innodb_plugin/include/dict0mem.h @@ -112,6 +112,21 @@ ROW_FORMAT=REDUNDANT. */ in table->flags. */ /* @} */ +/** Tables could be chained together with Foreign key constraint. When +first load the parent table, we would load all of its descedents. +This could result in rescursive calls and out of stack error eventually. +DICT_FK_MAX_RECURSIVE_LOAD defines the maximum number of recursive loads, +when exceeded, the child table will not be loaded. It will be loaded when +the foreign constraint check needs to be run. */ +#define DICT_FK_MAX_RECURSIVE_LOAD 250 + +/** Similarly, when tables are chained together with foreign key constraints +with on cascading delete/update clause, delete from parent table could +result in recursive cascading calls. This defines the maximum number of +such cascading deletes/updates allowed. When exceeded, the delete from +parent table will fail, and user has to drop excessive foreign constraint +before proceeds. */ +#define FK_MAX_CASCADE_DEL 300 /**********************************************************************//** Creates a table memory object. @@ -434,6 +449,12 @@ struct dict_table_struct{ NOT allowed until this count gets to zero; MySQL does NOT itself check the number of open handles at drop */ + unsigned fk_max_recusive_level:8; + /*!< maximum recursive level we support when + loading tables chained together with FK + constraints. If exceeds this level, we will + stop loading child table into memory along with + its parent table */ ulint n_foreign_key_checks_running; /*!< count of how many foreign key check operations are currently being performed diff --git a/storage/innodb_plugin/include/ha0ha.h b/storage/innodb_plugin/include/ha0ha.h index 1ffbd3440aa..3299000bf3c 100644 --- a/storage/innodb_plugin/include/ha0ha.h +++ b/storage/innodb_plugin/include/ha0ha.h @@ -186,6 +186,7 @@ ha_remove_all_nodes_to_page( hash_table_t* table, /*!< in: hash table */ ulint fold, /*!< in: fold value */ const page_t* page); /*!< in: buffer page */ +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /*************************************************************//** Validates a given range of the cells in hash table. @return TRUE if ok */ @@ -196,6 +197,7 @@ ha_validate( hash_table_t* table, /*!< in: hash table */ ulint start_index, /*!< in: start index */ ulint end_index); /*!< in: end index */ +#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ /*************************************************************//** Prints info of a hash table. */ UNIV_INTERN diff --git a/storage/innodb_plugin/include/os0sync.h b/storage/innodb_plugin/include/os0sync.h index 0c22162b900..f32e7ab710a 100644 --- a/storage/innodb_plugin/include/os0sync.h +++ b/storage/innodb_plugin/include/os0sync.h @@ -330,7 +330,7 @@ amount of increment. */ Returns the old value of *ptr, atomically sets *ptr to new_val */ # define os_atomic_test_and_set_byte(ptr, new_val) \ - __sync_lock_test_and_set(ptr, new_val) + __sync_lock_test_and_set(ptr, (byte) new_val) #elif defined(HAVE_IB_SOLARIS_ATOMICS) diff --git a/storage/innodb_plugin/include/que0que.h b/storage/innodb_plugin/include/que0que.h index 39f8d07af89..84b83208416 100644 --- a/storage/innodb_plugin/include/que0que.h +++ b/storage/innodb_plugin/include/que0que.h @@ -381,6 +381,9 @@ struct que_thr_struct{ thus far */ ulint lock_state; /*!< lock state of thread (table or row) */ + ulint fk_cascade_depth; /*!< maximum cascading call depth + supported for foreign key constraint + related delete/updates */ }; #define QUE_THR_MAGIC_N 8476583 diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index 991625d6a8a..0bb4b744d05 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 11 +#define INNODB_VERSION_BUGFIX 13 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; diff --git a/storage/innodb_plugin/include/ut0mem.h b/storage/innodb_plugin/include/ut0mem.h index cf41cba4643..f14606be966 100644 --- a/storage/innodb_plugin/include/ut0mem.h +++ b/storage/innodb_plugin/include/ut0mem.h @@ -113,7 +113,8 @@ ut_test_malloc( ulint n); /*!< in: try to allocate this many bytes */ #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** -Frees a memory block allocated with ut_malloc. */ +Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is +a nop. */ UNIV_INTERN void ut_free( diff --git a/storage/innodb_plugin/include/ut0rnd.ic b/storage/innodb_plugin/include/ut0rnd.ic index c3dbd86923c..a33813037ea 100644 --- a/storage/innodb_plugin/include/ut0rnd.ic +++ b/storage/innodb_plugin/include/ut0rnd.ic @@ -85,9 +85,6 @@ ut_rnd_gen_ulint(void) /*==================*/ { ulint rnd; - ulint n_bits; - - n_bits = 8 * sizeof(ulint); ut_rnd_ulint_counter = UT_RND1 * ut_rnd_ulint_counter + UT_RND2; diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c index a727d6be768..c1d12dad413 100644 --- a/storage/innodb_plugin/log/log0recv.c +++ b/storage/innodb_plugin/log/log0recv.c @@ -559,10 +559,8 @@ recv_synchronize_groups( ib_uint64_t start_lsn; ib_uint64_t end_lsn; ib_uint64_t recovered_lsn; - ib_uint64_t limit_lsn; recovered_lsn = recv_sys->recovered_lsn; - limit_lsn = recv_sys->limit_lsn; /* Read the last recovered log block to the recovery system buffer: the block is always incomplete */ @@ -2891,7 +2889,9 @@ recv_recovery_from_checkpoint_start_func( ib_uint64_t old_scanned_lsn; ib_uint64_t group_scanned_lsn; ib_uint64_t contiguous_lsn; +#ifdef UNIV_LOG_ARCHIVE ib_uint64_t archived_lsn; +#endif /* UNIV_LOG_ARCHIVE */ byte* buf; byte log_hdr_buf[LOG_FILE_HDR_SIZE]; ulint err; @@ -2946,7 +2946,9 @@ recv_recovery_from_checkpoint_start_func( checkpoint_lsn = mach_read_ull(buf + LOG_CHECKPOINT_LSN); checkpoint_no = mach_read_ull(buf + LOG_CHECKPOINT_NO); +#ifdef UNIV_LOG_ARCHIVE archived_lsn = mach_read_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN); +#endif /* UNIV_LOG_ARCHIVE */ /* Read the first log file header to print a note if this is a recovery from a restored InnoDB Hot Backup */ diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index 9f937b9def2..6a0d6ea5363 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -1367,8 +1367,6 @@ try_again: int create_flag; ibool retry; const char* mode_str = NULL; - const char* type_str = NULL; - const char* purpose_str = NULL; try_again: ut_a(name); @@ -1388,26 +1386,9 @@ try_again: ut_error; } - if (type == OS_LOG_FILE) { - type_str = "LOG"; - } else if (type == OS_DATA_FILE) { - type_str = "DATA"; - } else { - ut_error; - } + ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE); + ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL); - if (purpose == OS_FILE_AIO) { - purpose_str = "AIO"; - } else if (purpose == OS_FILE_NORMAL) { - purpose_str = "NORMAL"; - } else { - ut_error; - } - -#if 0 - fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n", - name, mode_str, type_str, purpose_str); -#endif #ifdef O_SYNC /* We let O_SYNC only affect log files; note that we map O_DSYNC to O_SYNC because the datasync options seemed to corrupt files in 2001 diff --git a/storage/innodb_plugin/que/que0que.c b/storage/innodb_plugin/que/que0que.c index 2fe046fa9b8..b616b3d9c14 100644 --- a/storage/innodb_plugin/que/que0que.c +++ b/storage/innodb_plugin/que/que0que.c @@ -1284,18 +1284,13 @@ que_run_threads_low( que_thr_t* thr) /*!< in: query thread */ { que_thr_t* next_thr; - ulint cumul_resource; ulint loop_count; ut_ad(thr->state == QUE_THR_RUNNING); ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS); ut_ad(!mutex_own(&kernel_mutex)); - /* cumul_resource counts how much resources the OS thread (NOT the - query thread) has spent in this function */ - loop_count = QUE_MAX_LOOPS_WITHOUT_CHECK; - cumul_resource = 0; loop: /* Check that there is enough space in the log to accommodate possible log entries by this query step; if the operation can touch diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 56a68b58225..05d77ad7f19 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -2395,7 +2395,7 @@ row_merge_rename_tables( goto err_exit; } - err = dict_load_foreigns(old_name, TRUE); + err = dict_load_foreigns(old_name, FALSE, TRUE); if (err != DB_SUCCESS) { err_exit: diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index feeb7fc80b7..9cabea507fb 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -576,6 +576,13 @@ handle_new_error: "InnoDB: " REFMAN "forcing-recovery.html" " for help.\n", stderr); break; + case DB_FOREIGN_EXCEED_MAX_CASCADE: + fprintf(stderr, "InnoDB: Cannot delete/update rows with" + " cascading foreign key constraints that exceed max" + " depth of %lu\n" + "Please drop excessive foreign constraints" + " and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD); + break; default: fprintf(stderr, "InnoDB: unknown error code %lu\n", (ulong) err); @@ -1381,11 +1388,15 @@ row_update_for_mysql( run_again: thr->run_node = node; thr->prev_node = node; + thr->fk_cascade_depth = 0; row_upd_step(thr); err = trx->error_state; + /* Reset fk_cascade_depth back to 0 */ + thr->fk_cascade_depth = 0; + if (err != DB_SUCCESS) { que_thr_stop_for_mysql(thr); @@ -1422,7 +1433,12 @@ run_again: srv_n_rows_updated++; } - row_update_statistics_if_needed(prebuilt->table); + /* We update table statistics only if it is a DELETE or UPDATE + that changes indexed columns, UPDATEs that change only non-indexed + columns would not affect statistics. */ + if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { + row_update_statistics_if_needed(prebuilt->table); + } trx->op_info = ""; @@ -1576,12 +1592,27 @@ row_update_cascade_for_mysql( trx_t* trx; trx = thr_get_trx(thr); + + /* Increment fk_cascade_depth to record the recursive call depth on + a single update/delete that affects multiple tables chained + together with foreign key relations. */ + thr->fk_cascade_depth++; + + if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) { + return (DB_FOREIGN_EXCEED_MAX_CASCADE); + } run_again: thr->run_node = node; thr->prev_node = node; row_upd_step(thr); + /* The recursive call for cascading update/delete happens + in above row_upd_step(), reset the counter once we come + out of the recursive call, so it does not accumulate for + different row deletes */ + thr->fk_cascade_depth = 0; + err = trx->error_state; /* Note that the cascade node is a subnode of another InnoDB @@ -2056,7 +2087,7 @@ row_table_add_foreign_constraints( name, reject_fks); if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ - err = dict_load_foreigns(name, TRUE); + err = dict_load_foreigns(name, FALSE, TRUE); } if (err != DB_SUCCESS) { @@ -2749,6 +2780,15 @@ row_truncate_table_for_mysql( trx->table_id = table->id; + /* Lock all index trees for this table, as we will + truncate the table/index and possibly change their metadata. + All DML/DDL are blocked by table level lock, with + a few exceptions such as queries into information schema + about the table, MySQL could try to access index stats + for this kind of query, we need to use index locks to + sync up */ + dict_table_x_lock_indexes(table); + if (table->space && !table->dir_path_of_temp_table) { /* Discard and create the single-table tablespace. */ ulint space = table->space; @@ -2765,6 +2805,7 @@ row_truncate_table_for_mysql( || fil_create_new_single_table_tablespace( space, table->name, FALSE, flags, FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) { + dict_table_x_unlock_indexes(table); ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: TRUNCATE TABLE %s failed to" @@ -2868,6 +2909,10 @@ next_rec: mem_heap_free(heap); + /* Done with index truncation, release index tree locks, + subsequent work relates to table level metadata change */ + dict_table_x_unlock_indexes(table); + dict_hdr_get_new_id(&new_id, NULL, NULL); info = pars_info_create(); @@ -3915,7 +3960,7 @@ end: an ALTER, not in a RENAME. */ err = dict_load_foreigns( - new_name, !old_is_tmp || trx->check_foreigns); + new_name, FALSE, !old_is_tmp || trx->check_foreigns); if (err != DB_SUCCESS) { ut_print_timestamp(stderr); diff --git a/storage/innodb_plugin/row/row0purge.c b/storage/innodb_plugin/row/row0purge.c index 835af990672..31b255cf2d4 100644 --- a/storage/innodb_plugin/row/row0purge.c +++ b/storage/innodb_plugin/row/row0purge.c @@ -684,7 +684,9 @@ row_purge_step( que_thr_t* thr) /*!< in: query thread */ { purge_node_t* node; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ ut_ad(thr); @@ -692,7 +694,10 @@ row_purge_step( ut_ad(que_node_get_type(node) == QUE_NODE_PURGE); - err = row_purge(node, thr); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + row_purge(node, thr); ut_ad(err == DB_SUCCESS); diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index 76c144e5a8c..cc7a7a6fe9b 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -2690,7 +2690,6 @@ row_sel_store_mysql_rec( ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->default_rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); - ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { mem_heap_free(prebuilt->blob_heap); @@ -3357,6 +3356,7 @@ row_search_for_mysql( mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; + ibool table_lock_waited = FALSE; rec_offs_init(offsets_); @@ -3611,6 +3611,7 @@ row_search_for_mysql( row_sel_try_search_shortcut_for_mysql(). The latch will not be released until mtr_commit(&mtr). */ + ut_ad(!rec_get_deleted_flag(rec, comp)); if (!row_sel_store_mysql_rec(buf, prebuilt, rec, offsets)) { @@ -3719,6 +3720,44 @@ release_search_latch_if_needed: clust_index = dict_table_get_first_index(index->table); + /* Do some start-of-statement preparations */ + + if (!prebuilt->sql_stat_start) { + /* No need to set an intention lock or assign a read view */ + + if (trx->read_view == NULL + && prebuilt->select_lock_type == LOCK_NONE) { + + fputs("InnoDB: Error: MySQL is trying to" + " perform a consistent read\n" + "InnoDB: but the read view is not assigned!\n", + stderr); + trx_print(stderr, trx, 600); + fputc('\n', stderr); + ut_error; + } + } else if (prebuilt->select_lock_type == LOCK_NONE) { + /* This is a consistent read */ + /* Assign a read view for the query */ + + trx_assign_read_view(trx); + prebuilt->sql_stat_start = FALSE; + } else { +wait_table_again: + err = lock_table(0, index->table, + prebuilt->select_lock_type == LOCK_S + ? LOCK_IS : LOCK_IX, thr); + + if (err != DB_SUCCESS) { + + table_lock_waited = TRUE; + goto lock_table_wait; + } + prebuilt->sql_stat_start = FALSE; + } + + /* Open or restore index cursor position */ + if (UNIV_LIKELY(direction != 0)) { ibool need_to_process = sel_restore_position_for_mysql( &same_user_rec, BTR_SEARCH_LEAF, @@ -3794,42 +3833,6 @@ release_search_latch_if_needed: } } - if (!prebuilt->sql_stat_start) { - /* No need to set an intention lock or assign a read view */ - - if (trx->read_view == NULL - && prebuilt->select_lock_type == LOCK_NONE) { - - fputs("InnoDB: Error: MySQL is trying to" - " perform a consistent read\n" - "InnoDB: but the read view is not assigned!\n", - stderr); - trx_print(stderr, trx, 600); - fputc('\n', stderr); - ut_a(0); - } - } else if (prebuilt->select_lock_type == LOCK_NONE) { - /* This is a consistent read */ - /* Assign a read view for the query */ - - trx_assign_read_view(trx); - prebuilt->sql_stat_start = FALSE; - } else { - ulint lock_mode; - if (prebuilt->select_lock_type == LOCK_S) { - lock_mode = LOCK_IS; - } else { - lock_mode = LOCK_IX; - } - err = lock_table(0, index->table, lock_mode, thr); - - if (err != DB_SUCCESS) { - - goto lock_wait_or_error; - } - prebuilt->sql_stat_start = FALSE; - } - rec_loop: /*-------------------------------------------------------------*/ /* PHASE 4: Look for matching records in a loop */ @@ -4238,7 +4241,7 @@ no_gap_lock: rec = old_vers; } - } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) { + } else { /* We are looking into a non-clustered index, and to get the right version of the record we have to look also into the clustered index: this @@ -4246,8 +4249,12 @@ no_gap_lock: information via the clustered index record. */ ut_ad(index != clust_index); + ut_ad(!dict_index_is_clust(index)); - goto requires_clust_rec; + if (!lock_sec_rec_cons_read_sees( + rec, trx->read_view)) { + goto requires_clust_rec; + } } } @@ -4370,8 +4377,13 @@ requires_clust_rec: ULINT_UNDEFINED, &heap); result_rec = rec; } + + /* result_rec can legitimately be delete-marked + now that it has been established that it points to a + clustered index record that exists in the read view. */ } else { result_rec = rec; + ut_ad(!rec_get_deleted_flag(rec, comp)); } /* We found a qualifying record 'result_rec'. At this point, @@ -4550,6 +4562,7 @@ lock_wait_or_error: btr_pcur_store_position(pcur, &mtr); +lock_table_wait: mtr_commit(&mtr); mtr_has_extra_clust_latch = FALSE; @@ -4567,6 +4580,14 @@ lock_wait_or_error: thr->lock_state = QUE_THR_LOCK_NOLOCK; mtr_start(&mtr); + /* Table lock waited, go try to obtain table lock + again */ + if (table_lock_waited) { + table_lock_waited = FALSE; + + goto wait_table_again; + } + sel_restore_position_for_mysql(&same_user_rec, BTR_SEARCH_LEAF, pcur, moves_up, &mtr); diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c index 8464b0f95cc..5998dadd16d 100644 --- a/storage/innodb_plugin/row/row0umod.c +++ b/storage/innodb_plugin/row/row0umod.c @@ -114,12 +114,17 @@ row_undo_mod_clust_low( btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; +#ifdef UNIV_DEBUG ibool success; +#endif /* UNIV_DEBUG */ pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); - success = btr_pcur_restore_position(mode, pcur, mtr); +#ifdef UNIV_DEBUG + success = +#endif /* UNIV_DEBUG */ + btr_pcur_restore_position(mode, pcur, mtr); ut_ad(success); diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 397b117c067..04c3139fcc7 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -1598,6 +1598,7 @@ row_upd_clust_rec_by_insert( dict_table_t* table; dtuple_t* entry; ulint err; + ibool change_ownership = FALSE; ut_ad(node); ut_ad(dict_index_is_clust(index)); @@ -1630,9 +1631,9 @@ row_upd_clust_rec_by_insert( index = dict_table_get_first_index(table); offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); - btr_cur_mark_extern_inherited_fields( - btr_cur_get_page_zip(btr_cur), - rec, index, offsets, node->update, mtr); + change_ownership = btr_cur_mark_extern_inherited_fields( + btr_cur_get_page_zip(btr_cur), rec, index, offsets, + node->update, mtr); if (check_ref) { /* NOTE that the following call loses the position of pcur ! */ @@ -1661,10 +1662,11 @@ row_upd_clust_rec_by_insert( row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id); - if (node->upd_ext) { + if (change_ownership) { /* If we return from a lock wait, for example, we may have extern fields marked as not-owned in entry (marked in the - if-branch above). We must unmark them. */ + if-branch above). We must unmark them, take the ownership + back. */ btr_cur_unmark_dtuple_extern_fields(entry); diff --git a/storage/innodb_plugin/row/row0vers.c b/storage/innodb_plugin/row/row0vers.c index a4fbb5289aa..b6d35363f08 100644 --- a/storage/innodb_plugin/row/row0vers.c +++ b/storage/innodb_plugin/row/row0vers.c @@ -71,7 +71,9 @@ row_vers_impl_x_locked_off_kernel( warning */ trx_t* trx; ulint rec_del; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ mtr_t mtr; ulint comp; @@ -169,9 +171,12 @@ row_vers_impl_x_locked_off_kernel( heap2 = heap; heap = mem_heap_create(1024); - err = trx_undo_prev_version_build(clust_rec, &mtr, version, - clust_index, clust_offsets, - heap, &prev_version); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + trx_undo_prev_version_build(clust_rec, &mtr, version, + clust_index, clust_offsets, + heap, &prev_version); mem_heap_free(heap2); /* free version and clust_offsets */ if (prev_version == NULL) { diff --git a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c index abbfa3d7f81..1a70750083a 100644 --- a/storage/innodb_plugin/trx/trx0purge.c +++ b/storage/innodb_plugin/trx/trx0purge.c @@ -304,9 +304,10 @@ trx_purge_add_update_undo_to_history( trx_undo_t* undo; trx_rseg_t* rseg; trx_rsegf_t* rseg_header; +#ifdef UNIV_DEBUG trx_usegf_t* seg_header; +#endif /* UNIV_DEBUG */ trx_ulogf_t* undo_header; - trx_upagef_t* page_header; ulint hist_size; undo = trx->update_undo; @@ -321,8 +322,9 @@ trx_purge_add_update_undo_to_history( rseg->page_no, mtr); undo_header = undo_page + undo->hdr_offset; +#ifdef UNIV_DEBUG seg_header = undo_page + TRX_UNDO_SEG_HDR; - page_header = undo_page + TRX_UNDO_PAGE_HDR; +#endif /* UNIV_DEBUG */ if (undo->state != TRX_UNDO_CACHED) { /* The undo log segment will not be reused */ @@ -655,7 +657,6 @@ trx_purge_rseg_get_next_history_log( { page_t* undo_page; trx_ulogf_t* log_hdr; - trx_usegf_t* seg_hdr; fil_addr_t prev_log_addr; trx_id_t trx_no; ibool del_marks; @@ -676,7 +677,6 @@ trx_purge_rseg_get_next_history_log( undo_page = trx_undo_page_get_s_latched(rseg->space, rseg->zip_size, rseg->last_page_no, &mtr); log_hdr = undo_page + rseg->last_offset; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; /* Increase the purge page count by one for every handled log */ @@ -1068,12 +1068,8 @@ trx_purge_rec_release( /*==================*/ trx_undo_inf_t* cell) /*!< in: storage cell */ { - trx_undo_arr_t* arr; - mutex_enter(&(purge_sys->mutex)); - arr = purge_sys->arr; - trx_purge_arr_remove_info(cell); mutex_exit(&(purge_sys->mutex)); diff --git a/storage/innodb_plugin/trx/trx0roll.c b/storage/innodb_plugin/trx/trx0roll.c index c925478cdf4..1a43e419214 100644 --- a/storage/innodb_plugin/trx/trx0roll.c +++ b/storage/innodb_plugin/trx/trx0roll.c @@ -740,13 +740,8 @@ trx_undo_arr_remove_info( undo_no_t undo_no)/*!< in: undo number */ { trx_undo_inf_t* cell; - ulint n_used; - ulint n; ulint i; - n_used = arr->n_used; - n = 0; - for (i = 0;; i++) { cell = trx_undo_arr_get_nth_info(arr, i); diff --git a/storage/innodb_plugin/trx/trx0sys.c b/storage/innodb_plugin/trx/trx0sys.c index 410c55f132d..6eb356947cc 100644 --- a/storage/innodb_plugin/trx/trx0sys.c +++ b/storage/innodb_plugin/trx/trx0sys.c @@ -241,7 +241,9 @@ trx_sys_create_doublewrite_buf(void) { buf_block_t* block; buf_block_t* block2; +#ifdef UNIV_SYNC_DEBUG buf_block_t* new_block; +#endif /* UNIV_SYNC_DEBUG */ byte* doublewrite; byte* fseg_header; ulint page_no; @@ -344,8 +346,11 @@ start_again: the page position in the tablespace, then the page has not been written to in doublewrite. */ - new_block = buf_page_get(TRX_SYS_SPACE, 0, page_no, - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + new_block = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(TRX_SYS_SPACE, 0, page_no, + RW_X_LATCH, &mtr); buf_block_dbg_add_level(new_block, SYNC_NO_ORDER_CHECK); diff --git a/storage/innodb_plugin/trx/trx0trx.c b/storage/innodb_plugin/trx/trx0trx.c index 9722bb59a5e..ee744fd58b1 100644 --- a/storage/innodb_plugin/trx/trx0trx.c +++ b/storage/innodb_plugin/trx/trx0trx.c @@ -1805,7 +1805,6 @@ trx_prepare_off_kernel( /*===================*/ trx_t* trx) /*!< in: transaction */ { - page_t* update_hdr_page; trx_rseg_t* rseg; ib_uint64_t lsn = 0; mtr_t mtr; @@ -1838,7 +1837,7 @@ trx_prepare_off_kernel( } if (trx->update_undo) { - update_hdr_page = trx_undo_set_state_at_prepare( + trx_undo_set_state_at_prepare( trx, trx->update_undo, &mtr); } diff --git a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c index 3bb1b1cdf6c..c8a4b15e48b 100644 --- a/storage/innodb_plugin/trx/trx0undo.c +++ b/storage/innodb_plugin/trx/trx0undo.c @@ -1066,14 +1066,11 @@ trx_undo_truncate_end( ulint last_page_no; trx_undo_rec_t* rec; trx_undo_rec_t* trunc_here; - trx_rseg_t* rseg; mtr_t mtr; ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(mutex_own(&(trx->rseg->mutex))); - rseg = trx->rseg; - for (;;) { mtr_start(&mtr); @@ -1868,7 +1865,6 @@ trx_undo_set_state_at_prepare( mtr_t* mtr) /*!< in: mtr */ { trx_usegf_t* seg_hdr; - trx_upagef_t* page_hdr; trx_ulogf_t* undo_header; page_t* undo_page; ulint offset; @@ -1886,7 +1882,6 @@ trx_undo_set_state_at_prepare( undo->hdr_page_no, mtr); seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; /*------------------------------*/ undo->state = TRX_UNDO_PREPARED; @@ -1938,7 +1933,8 @@ trx_undo_update_cleanup( UT_LIST_ADD_FIRST(undo_list, rseg->update_undo_cached, undo); } else { - ut_ad(undo->state == TRX_UNDO_TO_PURGE); + ut_ad(undo->state == TRX_UNDO_TO_PURGE + || undo->state == TRX_UNDO_TO_FREE); trx_undo_mem_free(undo); } diff --git a/storage/innodb_plugin/ut/ut0mem.c b/storage/innodb_plugin/ut/ut0mem.c index 35a325b9ccd..bf55e4273b6 100644 --- a/storage/innodb_plugin/ut/ut0mem.c +++ b/storage/innodb_plugin/ut/ut0mem.c @@ -290,7 +290,8 @@ ut_test_malloc( #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** -Frees a memory block allocated with ut_malloc. */ +Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is +a nop. */ UNIV_INTERN void ut_free( @@ -300,7 +301,9 @@ ut_free( #ifndef UNIV_HOTBACKUP ut_mem_block_t* block; - if (UNIV_LIKELY(srv_use_sys_malloc)) { + if (ptr == NULL) { + return; + } else if (UNIV_LIKELY(srv_use_sys_malloc)) { free(ptr); return; } diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt index 22e0211f052..fe6570d9c03 100644 --- a/storage/maria/CMakeLists.txt +++ b/storage/maria/CMakeLists.txt @@ -65,9 +65,8 @@ TARGET_LINK_LIBRARIES(maria_read_log maria myisam mysys dbug strings zlib wsock3 ADD_EXECUTABLE(maria_pack maria_pack.c) TARGET_LINK_LIBRARIES(maria_pack maria myisam mysys dbug strings zlib wsock32) -ADD_EXECUTABLE(maria_dump_log ma_loghandler.c unittest/ma_loghandler_examples.c) +ADD_EXECUTABLE(maria_dump_log maria_dump_log.c unittest/ma_loghandler_examples.c) TARGET_LINK_LIBRARIES(maria_dump_log maria myisam mysys dbug strings zlib wsock32) -SET_TARGET_PROPERTIES(maria_dump_log PROPERTIES COMPILE_FLAGS "-DMARIA_DUMP_LOG") ADD_EXECUTABLE(ma_test1 ma_test1.c) TARGET_LINK_LIBRARIES(ma_test1 maria myisam mysys dbug strings zlib wsock32) diff --git a/storage/maria/Makefile.am b/storage/maria/Makefile.am index d38abe01bdc..5e78614f0ca 100644 --- a/storage/maria/Makefile.am +++ b/storage/maria/Makefile.am @@ -34,6 +34,9 @@ EXTRA_DIST = ma_test_all.sh ma_test_all.res ma_test_big.sh \ ma_ft_stem.c CMakeLists.txt plug.in ma_test_recovery pkgdata_DATA = pkglib_LIBRARIES = libmaria.a +noinst_LTLIBRARIES = libmaria.la libmaria_s.la \ + @plugin_maria_embedded_static_target@ +EXTRA_LTLIBRARIES = libmaria_embedded.la bin_PROGRAMS = maria_chk maria_pack maria_ftdump maria_read_log \ maria_dump_log maria_chk_DEPENDENCIES= $(LIBRARIES) @@ -58,13 +61,12 @@ maria_read_log_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ maria_dump_log_DEPENDENCIES=$(LIBRARIES) ma_loghandler.c -maria_dump_log_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ +maria_dump_log_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.la \ $(top_builddir)/storage/myisam/libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -maria_dump_log_SOURCES= ma_loghandler.c unittest/ma_loghandler_examples.c -maria_dump_log_CPPFLAGS= -DMARIA_DUMP_LOG +maria_dump_log_SOURCES= maria_dump_log.c unittest/ma_loghandler_examples.c noinst_PROGRAMS = ma_test1 ma_test2 ma_test3 ma_rt_test ma_sp_test noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \ ma_sp_defs.h ma_fulltext.h ma_ftdefs.h ma_ft_test1.h \ @@ -112,7 +114,7 @@ ma_sp_test_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -libmaria_a_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \ +libmaria_la_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \ ma_rnext.c ma_rnext_same.c \ ma_search.c ma_page.c ma_key_recover.c ma_key.c \ ma_locking.c ma_state.c \ @@ -134,8 +136,20 @@ libmaria_a_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \ ma_sp_key.c ma_control_file.c ma_loghandler.c \ ma_pagecache.c ma_pagecaches.c \ ma_checkpoint.c ma_recovery.c ma_commit.c \ - ma_pagecrc.c ma_recovery_util.c \ - ha_maria.cc + ma_pagecrc.c ma_recovery_util.c + +libmaria_s_la_SOURCES = ha_maria.cc +libmaria_s_la_CXXFLAGS = $(AM_CXXFLAGS) +libmaria_s_la_LIBADD = libmaria.la +libmaria_embedded_la_SOURCES = ha_maria.cc +libmaria_embedded_la_LIBADD = libmaria.la +libmaria_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@ + +libmaria_a_SOURCES= +libmaria.a: libmaria.la + $(CP) .libs/libmaria.a $@ + + CLEANFILES = test?.MA? FT?.MA? isam.log ma_test_all ma_rt_test.MA? sp_test.MA? maria_log_control maria_log.0000* SUFFIXES = .sh diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index a611915b7f4..6852e84fc65 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1043,14 +1043,14 @@ int ha_maria::write_row(uchar * buf) int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) { - if (!file) - return HA_ADMIN_INTERNAL_ERROR; int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MARIA_SHARE *share= file->s; const char *old_proc_info= thd_proc_info(thd, "Checking table"); TRN *old_trn= file->trn; + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "check"; @@ -1144,9 +1144,12 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt) { int error= 0; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MARIA_SHARE *share= file->s; + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "analyze"; @@ -1281,7 +1284,10 @@ int ha_maria::backup(THD * thd, HA_CHECK_OPT *check_opt) err: { - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "backup"; @@ -1297,10 +1303,10 @@ err: int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt) { int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); ha_rows start_records; - if (!file) + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; maria_chk_init(¶m); @@ -1310,6 +1316,7 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt) T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM | (check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT)); param.sort_buffer_length= THDVAR(thd, sort_buffer_size); + param.backup_time= check_opt->start_time; start_records= file->state->records; while ((error= repair(thd, ¶m, 0)) && param.retry_repair) { @@ -1352,11 +1359,11 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt) int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt) { int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); TRN *old_trn; MARIA_SHARE *share= file->s; - if (!file) + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; old_trn= file->trn; @@ -1382,9 +1389,9 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt) int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt) { int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); - if (!file) + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; maria_chk_init(¶m); @@ -1623,7 +1630,10 @@ int ha_maria::assign_to_keycache(THD * thd, HA_CHECK_OPT *check_opt) if (error != HA_ADMIN_OK) { /* Send error to user */ - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "assign_to_keycache"; @@ -1684,7 +1694,10 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt) errmsg= buf; } - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "preload_keys"; @@ -1792,8 +1805,12 @@ int ha_maria::enable_indexes(uint mode) else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) { THD *thd= current_thd; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + const char *save_proc_info= thd_proc_info(thd, "Creating index"); + maria_chk_init(¶m); param.op_name= "recreating_index"; param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK | @@ -2006,14 +2023,16 @@ bool ha_maria::check_and_repair(THD *thd) check_opt.init(); - if (file->s->state.changed & STATE_MOVED) + error= 1; + if ((file->s->state.changed & + (STATE_CRASHED | STATE_CRASHED_ON_REPAIR | STATE_MOVED)) == + STATE_MOVED) { - sql_print_information("Zerofilling table: '%s'", table->s->path.str); + sql_print_information("Zerofilling moved table: '%s'", + table->s->path.str); if (!(error= zerofill(thd, &check_opt))) DBUG_RETURN(0); } - else - error= 1; /* if we got this far - the table is crashed. @@ -3273,6 +3292,8 @@ static int ha_maria_init(void *p) /* We can only test for sub paths if my_symlink.c is using realpath */ maria_test_invalid_symlink= test_if_data_home_dir; #endif + if (res) + maria_hton= 0; return res ? HA_ERR_INITIALIZATION : 0; } diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index ff23c408931..7e68437de2b 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -147,6 +147,12 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share, DBUG_ASSERT(bitmap->file.write_callback != 0); DBUG_PRINT("info", ("bitmap->non_flushable: %u", bitmap->non_flushable)); + /* + Mark that a bitmap page has been written to page cache and we have + to flush it during checkpoint. + */ + bitmap->changed_not_flushed= 1; + if ((bitmap->non_flushable == 0) #ifdef WRONG_BITMAP_FLUSH || 1 @@ -221,7 +227,8 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file) The +1 is to add the bitmap page, as this doesn't have to be covered */ bitmap->pages_covered= aligned_bit_blocks * 16 + 1; - bitmap->flush_all_requested= bitmap->non_flushable= 0; + bitmap->flush_all_requested= 0; + bitmap->non_flushable= 0; /* Update size for bits */ /* TODO; Make this dependent of the row size */ @@ -305,8 +312,8 @@ my_bool _ma_bitmap_flush(MARIA_SHARE *share) pthread_mutex_lock(&share->bitmap.bitmap_lock); if (share->bitmap.changed) { - share->bitmap.changed= 0; res= write_changed_bitmap(share, &share->bitmap); + share->bitmap.changed= 0; } pthread_mutex_unlock(&share->bitmap.bitmap_lock); } @@ -347,9 +354,9 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share) MARIA_FILE_BITMAP *bitmap= &share->bitmap; DBUG_ENTER("_ma_bitmap_flush_all"); pthread_mutex_lock(&bitmap->bitmap_lock); - if (bitmap->changed) + if (bitmap->changed || bitmap->changed_not_flushed) { - bitmap->flush_all_requested= TRUE; + bitmap->flush_all_requested++; #ifndef WRONG_BITMAP_FLUSH while (bitmap->non_flushable > 0) { @@ -357,6 +364,7 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share) pthread_cond_wait(&bitmap->bitmap_cond, &bitmap->bitmap_lock); } #endif + DBUG_ASSERT(bitmap->flush_all_requested == 1); /* Bitmap is in a flushable state: its contents in memory are reflected by log records (complete REDO-UNDO groups) and all bitmap pages are @@ -384,7 +392,8 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share) &bitmap->pages_covered) & PCFLUSH_PINNED_AND_ERROR) res= TRUE; - bitmap->flush_all_requested= FALSE; + bitmap->changed_not_flushed= FALSE; + bitmap->flush_all_requested--; /* Some well-behaved threads may be waiting for flush_all_requested to become false, wake them up. @@ -398,6 +407,70 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share) /** + @brief Lock bitmap from being used by another thread + + @fn _ma_bitmap_lock() + @param share Table's share + + @notes + This is a temporary solution for allowing someone to delete an inserted + duplicate-key row while someone else is doing concurrent inserts. + This is ok for now as duplicate key errors are not that common. + + In the future we will add locks for row-pages to ensure two threads doesn't + work at the same time on the same page. +*/ + +void _ma_bitmap_lock(MARIA_SHARE *share) +{ + MARIA_FILE_BITMAP *bitmap= &share->bitmap; + DBUG_ENTER("_ma_bitmap_lock"); + + if (!share->now_transactional) + DBUG_VOID_RETURN; + + pthread_mutex_lock(&bitmap->bitmap_lock); + bitmap->flush_all_requested++; + while (bitmap->non_flushable) + { + DBUG_PRINT("info", ("waiting for bitmap to be flushable")); + pthread_cond_wait(&bitmap->bitmap_cond, &bitmap->bitmap_lock); + } + /* + Ensure that _ma_bitmap_flush_all() and _ma_bitmap_lock() are blocked. + ma_bitmap_flushable() is blocked thanks to 'flush_all_requested'. + */ + bitmap->non_flushable= 1; + pthread_mutex_unlock(&bitmap->bitmap_lock); + DBUG_VOID_RETURN; +} + +/** + @brief Unlock bitmap after _ma_bitmap_lock() + + @fn _ma_bitmap_unlock() + @param share Table's share +*/ + +void _ma_bitmap_unlock(MARIA_SHARE *share) +{ + MARIA_FILE_BITMAP *bitmap= &share->bitmap; + DBUG_ENTER("_ma_bitmap_unlock"); + + if (!share->now_transactional) + DBUG_VOID_RETURN; + DBUG_ASSERT(bitmap->flush_all_requested > 0 && bitmap->non_flushable == 1); + + pthread_mutex_lock(&bitmap->bitmap_lock); + bitmap->flush_all_requested--; + bitmap->non_flushable= 0; + pthread_mutex_unlock(&bitmap->bitmap_lock); + pthread_cond_broadcast(&bitmap->bitmap_cond); + DBUG_VOID_RETURN; +} + + +/** @brief Unpin all pinned bitmap pages @param share Table's share @@ -419,7 +492,7 @@ static void _ma_bitmap_unpin_all(MARIA_SHARE *share) while (pinned_page-- != page_link) pagecache_unlock_by_link(share->pagecache, pinned_page->link, pinned_page->unlock, PAGECACHE_UNPIN, - LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, TRUE, TRUE); + LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, FALSE, TRUE); bitmap->pinned_pages.elements= 0; DBUG_VOID_RETURN; } @@ -626,11 +699,12 @@ static void _ma_print_bitmap_changes(MARIA_FILE_BITMAP *bitmap) { uchar *pos, *end, *org_pos; ulong page; + DBUG_ENTER("_ma_print_bitmap_changes"); end= bitmap->map + bitmap->used_size; DBUG_LOCK_FILE; - fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n", - (ulong) bitmap->page); + fprintf(DBUG_FILE,"\nBitmap page changes at page: %lu bitmap: 0x%lx\n", + (ulong) bitmap->page, (long) bitmap->map); page= (ulong) bitmap->page+1; for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ; @@ -659,6 +733,7 @@ static void _ma_print_bitmap_changes(MARIA_FILE_BITMAP *bitmap) fputc('\n', DBUG_FILE); DBUG_UNLOCK_FILE; memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size); + DBUG_VOID_RETURN; } @@ -870,6 +945,7 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap, { uint page, offset, tmp; uchar *data; + DBUG_ENTER("fill_block"); /* For each 6 bytes we have 6*8/3= 16 patterns */ page= ((uint) (best_data - bitmap->map)) / 6 * 16 + best_pos; @@ -895,6 +971,7 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap, int2store(data, tmp); bitmap->changed= 1; DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap);); + DBUG_VOID_RETURN; } @@ -1009,7 +1086,11 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size, DBUG_PRINT("enter", ("size: %u", size)); LINT_INIT(best_pos); - DBUG_ASSERT(size <= FULL_PAGE_SIZE(bitmap->block_size)); + /* + We have to add DIR_ENTRY_SIZE here as this is not part of the data size + See call to allocate_tail() in find_tail(). + */ + DBUG_ASSERT(size <= MAX_TAIL_SIZE(bitmap->block_size) + DIR_ENTRY_SIZE); for (; data < end; data += 6) { @@ -1503,6 +1584,8 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size, MARIA_BITMAP_BLOCK *block; uchar *data; uint offset, tmp, offset_page; + DBUG_ENTER("use_head"); + DBUG_ASSERT(page % bitmap->pages_covered); block= dynamic_element(&info->bitmap_blocks, block_position, @@ -1525,6 +1608,7 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size, int2store(data, tmp); bitmap->changed= 1; DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap);); + DBUG_VOID_RETURN; } @@ -1725,7 +1809,7 @@ my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row, row_length= find_where_to_split_row(share, row, extents_length, max_page_size); - full_page_size= FULL_PAGE_SIZE(share->block_size); + full_page_size= MAX_TAIL_SIZE(share->block_size); position= 0; if (head_length - row_length <= full_page_size) position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */ diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index f582bfb3b97..fd02e2ac0ec 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -742,8 +742,8 @@ static my_bool enough_free_entries(uchar *buff, uint block_size, @return 1 There is room for more entries on the page */ -static my_bool enough_free_entries_on_page(MARIA_SHARE *share, - uchar *page_buff) +my_bool enough_free_entries_on_page(MARIA_SHARE *share, + uchar *page_buff) { enum en_page_type page_type; page_type= (enum en_page_type) (page_buff[PAGE_TYPE_OFFSET] & @@ -1716,7 +1716,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info, MARIA_PINNED_PAGE page_link; MARIA_SHARE *share= info->s; DBUG_ENTER("get_head_or_tail_page"); - DBUG_PRINT("enter", ("length: %u", length)); + DBUG_PRINT("enter", ("page_type: %u length: %u", page_type, length)); block_size= share->block_size; if (block->org_bitmap_value == 0) /* Empty block */ @@ -1993,19 +1993,6 @@ static my_bool write_tail(MARIA_HA *info, /* Keep BLOCKUSED_USE_ORG_BITMAP */ block->used|= BLOCKUSED_USED | BLOCKUSED_TAIL; - /* Increase data file size, if extended */ - position= (my_off_t) block->page * block_size; - if (share->state.state.data_file_length <= position) - { - /* - We are modifying a state member before writing the UNDO; this is a WAL - violation. But for data_file_length this is ok, as long as we change - data_file_length after writing any log record (FILE_ID/REDO/UNDO) (see - collect_tables()). - */ - _ma_set_share_data_file_length(share, position + block_size); - } - if (block_is_read) { /* Current page link is last element in pinned_pages */ @@ -2021,17 +2008,33 @@ static my_bool write_tail(MARIA_HA *info, page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK; res= 0; } - else if (!(res= pagecache_write(share->pagecache, - &info->dfile, block->page, 0, - row_pos.buff,share->page_type, - PAGECACHE_LOCK_READ, - PAGECACHE_PIN, - PAGECACHE_WRITE_DELAY, &page_link.link, - LSN_IMPOSSIBLE))) + else { - page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK; - page_link.changed= 1; - push_dynamic(&info->pinned_pages, (void*) &page_link); + if (!(res= pagecache_write(share->pagecache, + &info->dfile, block->page, 0, + row_pos.buff,share->page_type, + PAGECACHE_LOCK_READ, + PAGECACHE_PIN, + PAGECACHE_WRITE_DELAY, &page_link.link, + LSN_IMPOSSIBLE))) + { + page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK; + page_link.changed= 1; + push_dynamic(&info->pinned_pages, (void*) &page_link); + } + + /* Increase data file size, if extended */ + position= (my_off_t) block->page * block_size; + if (share->state.state.data_file_length <= position) + { + /* + We are modifying a state member before writing the UNDO; this is a WAL + violation. But for data_file_length this is ok, as long as we change + data_file_length after writing any log record (FILE_ID/REDO/UNDO) (see + collect_tables()). + */ + _ma_set_share_data_file_length(share, position + block_size); + } } DBUG_RETURN(res); } @@ -2068,7 +2071,7 @@ static my_bool write_full_pages(MARIA_HA *info, uint data_size= FULL_PAGE_SIZE(block_size); uchar *buff= info->keyread_buff; uint page_count, sub_blocks; - my_off_t position; + my_off_t position, max_position; DBUG_ENTER("write_full_pages"); DBUG_PRINT("enter", ("length: %lu page: %lu page_count: %lu", (ulong) length, (ulong) block->page, @@ -2080,9 +2083,7 @@ static my_bool write_full_pages(MARIA_HA *info, page_count= block->page_count; sub_blocks= block->sub_blocks; - position= (my_off_t) (page + page_count) * block_size; - if (share->state.state.data_file_length < position) - _ma_set_share_data_file_length(share, position); + max_position= (my_off_t) (page + page_count) * block_size; /* Increase data file size, if extended */ @@ -2105,8 +2106,7 @@ static my_bool write_full_pages(MARIA_HA *info, (ulong) block->page, (ulong) block->page_count)); position= (page + page_count + 1) * block_size; - if (share->state.state.data_file_length < position) - _ma_set_share_data_file_length(share, position); + set_if_bigger(max_position, position); } lsn_store(buff, lsn); buff[PAGE_TYPE_OFFSET]= (uchar) BLOB_PAGE; @@ -2134,6 +2134,8 @@ static my_bool write_full_pages(MARIA_HA *info, page++; DBUG_ASSERT(block->used & BLOCKUSED_USED); } + if (share->state.state.data_file_length < max_position) + _ma_set_share_data_file_length(share, max_position); DBUG_RETURN(0); } @@ -2823,6 +2825,10 @@ static my_bool write_block_record(MARIA_HA *info, data+= diff_length; head_length= share->base.min_block_length; } + /* + If this is a redo entry (ie, undo_lsn != LSN_ERROR) then we should have + written exactly head_length bytes (same as original record). + */ DBUG_ASSERT(undo_lsn == LSN_ERROR || head_length == row_pos->length); int2store(row_pos->dir + 2, head_length); /* update empty space at start of block */ @@ -3117,11 +3123,6 @@ static my_bool write_block_record(MARIA_HA *info, } #endif - /* Increase data file size, if extended */ - position= (my_off_t) head_block->page * block_size; - if (share->state.state.data_file_length <= position) - _ma_set_share_data_file_length(share, position + block_size); - if (head_block_is_read) { MARIA_PINNED_PAGE *page_link; @@ -3150,6 +3151,11 @@ static my_bool write_block_record(MARIA_HA *info, page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK; page_link.changed= 1; push_dynamic(&info->pinned_pages, (void*) &page_link); + + /* Increase data file size, if extended */ + position= (my_off_t) head_block->page * block_size; + if (share->state.state.data_file_length <= position) + _ma_set_share_data_file_length(share, position + block_size); } if (share->now_transactional && (tmp_data_used || blob_full_pages_exists)) @@ -3588,7 +3594,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info) MARIA_SHARE *share= info->s; DBUG_ENTER("_ma_write_abort_block_record"); - _ma_bitmap_flushable(info, 1); + _ma_bitmap_lock(share); /* Lock bitmap from other insert threads */ if (delete_head_or_tail(info, ma_recordpos_to_page(info->cur_row.lastpos), ma_recordpos_to_dir_entry(info->cur_row.lastpos), 1, @@ -3626,7 +3632,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info) &lsn, (void*) 0)) res= 1; } - _ma_bitmap_flushable(info, -1); + _ma_bitmap_unlock(share); _ma_unpin_all_pages_and_finalize_row(info, lsn); DBUG_RETURN(res); } @@ -5158,6 +5164,7 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info) info->scan.number_of_rows= 0; info->scan.bitmap_pos= info->scan.bitmap_end; info->scan.bitmap_page= (pgcache_page_no_t) 0 - share->bitmap.pages_covered; + info->scan.max_page= share->state.state.data_file_length / share->block_size; /* We need to flush what's in memory (bitmap.map) to page cache otherwise, as we are going to read bitmaps from page cache in table scan (see @@ -5359,6 +5366,11 @@ restart_bitmap_scan: page= (info->scan.bitmap_page + 1 + (data - info->scan.bitmap_buff) / 6 * 16 + bit_pos - 1); info->scan.row_base_page= ma_recordpos(page, 0); + if (page >= info->scan.max_page) + { + DBUG_PRINT("info", ("Found end of file")); + DBUG_RETURN((my_errno= HA_ERR_END_OF_FILE)); + } if (!(pagecache_read(share->pagecache, &info->dfile, page, 0, info->scan.page_buff, @@ -6238,7 +6250,10 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, /* Skip errors when reading outside of file and uninitialized pages */ if (!new_page || (my_errno != HA_ERR_FILE_TOO_SHORT && my_errno != HA_ERR_WRONG_CRC)) + { + DBUG_PRINT("error", ("Error %d when reading page", (int) my_errno)); goto err; + } /* Create new page */ buff= pagecache_block_link_to_buffer(page_link.link); buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE; @@ -6266,7 +6281,13 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, changed to new type. */ if (!new_page) + { + DBUG_PRINT("error", + ("Found page of wrong type: %u, should have been %u", + (uint) (buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK), + page_type)); goto crashed_file; + } make_empty_page(info, buff, page_type, 0); empty_space= block_size - PAGE_HEADER_SIZE - PAGE_SUFFIX_SIZE; (void) extend_directory(page_type == HEAD_PAGE ? info: 0, buff, @@ -7152,6 +7173,7 @@ my_bool _ma_apply_undo_row_update(MARIA_HA *info, LSN undo_lsn, header+= HA_CHECKSUM_STORE_SIZE; } length_on_head_page= uint2korr(header); + set_if_bigger(length_on_head_page, share->base.min_block_length); header+= 2; extent_count= pagerange_korr(header); header+= PAGERANGE_STORE_SIZE; diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h index 16dedc93b28..a5858880dd0 100644 --- a/storage/maria/ma_blockrec.h +++ b/storage/maria/ma_blockrec.h @@ -176,6 +176,7 @@ my_bool _ma_compare_block_record(register MARIA_HA *info, void _ma_compact_block_page(uchar *buff, uint block_size, uint rownr, my_bool extend_block, TrID min_read_from, uint min_row_length); +my_bool enough_free_entries_on_page(MARIA_SHARE *share, uchar *page_buff); TRANSLOG_ADDRESS maria_page_get_lsn(uchar *page, pgcache_page_no_t page_no, uchar* data_ptr); @@ -216,6 +217,8 @@ uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap, void _ma_bitmap_delete_all(MARIA_SHARE *share); int _ma_bitmap_create_first(MARIA_SHARE *share); void _ma_bitmap_flushable(MARIA_HA *info, int non_flushable_inc); +void _ma_bitmap_lock(MARIA_SHARE *share); +void _ma_bitmap_unlock(MARIA_SHARE *share); void _ma_bitmap_set_pagecache_callbacks(PAGECACHE_FILE *file, MARIA_SHARE *share); #ifndef DBUG_OFF @@ -280,7 +283,8 @@ my_bool write_hook_for_commit(enum translog_record_type type, TRN *trn, MARIA_HA *tbl_info, LSN *lsn, void *hook_arg); void _ma_block_get_status(void *param, my_bool concurrent_insert); -void _ma_block_get_status_no_versioning(void *param, my_bool concurrent_ins); +my_bool _ma_block_start_trans(void* param); +my_bool _ma_block_start_trans_no_versioning(void *param); void _ma_block_update_status(void *param); void _ma_block_restore_status(void *param); my_bool _ma_block_check_status(void *param); diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index fa1933913d4..fcf01385e97 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -1760,7 +1760,7 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record, _ma_check_print_error(param, "Page %9s: Row: %3d has an extent with " "wrong information in bitmap: " - "Page %9s Page_type: %d Bitmap: %d", + "Page: %9s Page_type: %d Bitmap: %d", llstr(page, llbuff), row, llstr(extent_page, llbuff2), page_type, bitmap_pattern); @@ -2743,7 +2743,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, new_file= -1; change_data_file_descriptor(info, -1); if (maria_change_to_newfile(share->data_file_name.str, MARIA_NAME_DEXT, - DATA_TMP_EXT, + DATA_TMP_EXT, param->backup_time, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0)) | sync_dir) || @@ -3059,7 +3059,7 @@ int maria_sort_index(HA_CHECK *param, register MARIA_HA *info, char *name) pthread_mutex_unlock(&share->intern_lock); VOID(my_close(new_file,MYF(MY_WME))); if (maria_change_to_newfile(share->index_file_name.str, MARIA_NAME_IEXT, - INDEX_TMP_EXT, sync_dir) || + INDEX_TMP_EXT, 0, sync_dir) || _ma_open_keyfile(share)) goto err2; info->lock_type= F_UNLCK; /* Force maria_readinfo to lock */ @@ -3376,7 +3376,7 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info, case TAIL_PAGE: { uint max_entry= (uint) buff[DIR_COUNT_OFFSET]; - uint offset, dir_start; + uint offset, dir_start, empty_space; uchar *dir; if (zero_lsn) @@ -3389,9 +3389,13 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info, is_head_page ? ~(TrID) 0 : 0, is_head_page ? share->base.min_block_length : 0); + /* compactation may have increased free space */ + empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET); + if (!enough_free_entries_on_page(share, buff)) + empty_space= 0; /* Page is full */ if (_ma_bitmap_set(info, page, is_head_page, - uint2korr(buff + EMPTY_SPACE_OFFSET))) + empty_space)) goto err; /* Zerofill the not used part */ @@ -3488,20 +3492,15 @@ int maria_zerofill(HA_CHECK *param, MARIA_HA *info, const char *name) */ int maria_change_to_newfile(const char * filename, const char * old_ext, - const char * new_ext, myf MyFlags) + const char * new_ext, time_t backup_time, + myf MyFlags) { char old_filename[FN_REFLEN],new_filename[FN_REFLEN]; -#ifdef USE_RAID - if (raid_chunks) - return my_raid_redel(fn_format(old_filename,filename,"",old_ext,2+4), - fn_format(new_filename,filename,"",new_ext,2+4), - raid_chunks, - MYF(MY_WME | MY_LINK_WARNING | MyFlags)); -#endif /* Get real path to filename */ (void) fn_format(old_filename,filename,"",old_ext,2+4+32); return my_redel(old_filename, fn_format(new_filename,old_filename,"",new_ext,2+4), + backup_time, MYF(MY_WME | MY_LINK_WARNING | MyFlags)); } /* maria_change_to_newfile */ @@ -3871,7 +3870,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, } change_data_file_descriptor(info, -1); if (maria_change_to_newfile(share->data_file_name.str, MARIA_NAME_DEXT, - DATA_TMP_EXT, + DATA_TMP_EXT, param->backup_time, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0)) | sync_dir) || @@ -4405,8 +4404,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, goto err; } } - share->state.state.data_file_length= share->state.state.data_file_length= - sort_param->filepos; + share->state.state.data_file_length= sort_param->filepos; /* Only whole records */ share->state.version= (ulong) time((time_t*) 0); /* @@ -4497,7 +4495,7 @@ err: my_close(new_file,MYF(0)); info->dfile.file= new_file= -1; if (maria_change_to_newfile(share->data_file_name.str, MARIA_NAME_DEXT, - DATA_TMP_EXT, + DATA_TMP_EXT, param->backup_time, MYF((param->testflag & T_BACKUP_DATA ? MY_REDEL_MAKE_BACKUP : 0) | sync_dir)) || diff --git a/storage/maria/ma_dbug.c b/storage/maria/ma_dbug.c index ea69975ad4b..24389fce321 100644 --- a/storage/maria/ma_dbug.c +++ b/storage/maria/ma_dbug.c @@ -137,6 +137,7 @@ void _ma_print_keydata(FILE *stream, register HA_KEYSEG *keyseg, key=end; break; } +#endif case HA_KEYTYPE_BIT: { uint i; @@ -146,8 +147,6 @@ void _ma_print_keydata(FILE *stream, register HA_KEYSEG *keyseg, key= end; break; } - -#endif case HA_KEYTYPE_VARTEXT1: /* VARCHAR and TEXT */ case HA_KEYTYPE_VARTEXT2: /* VARCHAR and TEXT */ case HA_KEYTYPE_VARBINARY1: /* VARBINARY and BLOB */ diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c index 2420cac0e93..5c04f358b14 100644 --- a/storage/maria/ma_delete.c +++ b/storage/maria/ma_delete.c @@ -489,7 +489,10 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag, } if (ret_value == 0 && anc_page->size > share->max_index_block_size) { - /* parent buffer got too big ; We have to split the page */ + /* + parent buffer got too big ; We have to split the page. + The | 2 is there to force write of anc page below + */ save_flag= 3; ret_value= _ma_split_page(info, key, anc_page, share->max_index_block_size, @@ -595,6 +598,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key, endpos= leaf_page->buff+ leaf_page->size; if (ret_value == 1) { + /* underflow writes "next_page" to disk */ ret_value= underflow(info, keyinfo, leaf_page, &next_page, endpos); if (ret_value == 0 && leaf_page->size > @@ -608,6 +612,9 @@ static int del(MARIA_HA *info, MARIA_KEY *key, } else { + if (_ma_write_keypage(&next_page, PAGECACHE_LOCK_LEFT_WRITELOCKED, + DFLT_INIT_HITS)) + goto err; DBUG_PRINT("test",("Inserting of key when deleting")); if (!_ma_get_last_key(&tmp_key, leaf_page, endpos)) goto err; @@ -702,7 +709,8 @@ static int del(MARIA_HA *info, MARIA_KEY *key, if (share->now_transactional && _ma_log_add(anc_page, a_length, - key_start, s_temp.changed_length, s_temp.move_length, 1)) + key_start, s_temp.changed_length, s_temp.move_length, 1, + KEY_OP_DEBUG_LOG_ADD_2)) goto err; DBUG_RETURN(new_leaf_length <= @@ -971,7 +979,8 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, anc_key_inserted.move_length, key_deleted.changed_length), anc_key_inserted.move_length - - key_deleted.move_length, 1)) + key_deleted.move_length, 1, + KEY_OP_DEBUG_LOG_ADD_3)) goto err; /* @@ -1211,7 +1220,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, anc_key_inserted.move_length, key_deleted.changed_length), anc_key_inserted.move_length - - key_deleted.move_length, 1)) + key_deleted.move_length, 1,KEY_OP_DEBUG_LOG_ADD_4)) goto err; /* @@ -1449,25 +1458,23 @@ my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos, enum en_key_debug debug_marker __attribute__((unused))) { LSN lsn; - uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 2 + 3 + 3 + 6 + 3 + 7]; + uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 5+ 2 + 3 + 3 + 6 + 3 + 7]; uchar *log_pos; LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 7]; uint translog_parts, current_size, extra_length; uint offset= (uint) (key_pos - ma_page->buff); MARIA_HA *info= ma_page->info; MARIA_SHARE *share= info->s; - my_off_t page; + my_off_t page= ma_page->pos / share->block_size; DBUG_ENTER("_ma_log_delete"); DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d", - (ulong) (ma_page->pos / share->block_size), - changed_length, move_length)); + (ulong) page, changed_length, move_length)); DBUG_ASSERT(share->now_transactional && move_length); DBUG_ASSERT(offset + changed_length <= ma_page->size); DBUG_ASSERT(ma_page->org_size - move_length + append_length == ma_page->size); DBUG_ASSERT(move_length <= ma_page->org_size - share->keypage_header); /* Store address of new root page */ - page= ma_page->pos / share->block_size; page_store(log_data + FILEID_STORE_SIZE, page); log_pos= log_data+ FILEID_STORE_SIZE + PAGE_STORE_SIZE; current_size= ma_page->org_size; @@ -1475,6 +1482,11 @@ my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos, #ifdef EXTRA_DEBUG_KEY_CHANGES *log_pos++= KEY_OP_DEBUG; *log_pos++= debug_marker; + + *log_pos++= KEY_OP_DEBUG_2; + int2store(log_pos, ma_page->org_size); + int2store(log_pos+2, ma_page->size); + log_pos+=4; #endif /* Store keypage_flag */ diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c index 95fc88ca3db..6de5253a2dd 100644 --- a/storage/maria/ma_key_recover.c +++ b/storage/maria/ma_key_recover.c @@ -321,15 +321,14 @@ my_bool _ma_log_prefix(MARIA_PAGE *ma_page, uint changed_length, uchar *log_pos; uchar *buff= ma_page->buff; LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4]; - pgcache_page_no_t page; MARIA_HA *info= ma_page->info; + pgcache_page_no_t page= ma_page->pos / info->s->block_size; DBUG_ENTER("_ma_log_prefix"); DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d", - (ulong) ma_page->pos, changed_length, move_length)); + (ulong) page, changed_length, move_length)); DBUG_ASSERT(ma_page->size == ma_page->org_size + move_length); - page= ma_page->pos / info->s->block_size; log_pos= log_data + FILEID_STORE_SIZE; page_store(log_pos, page); log_pos+= PAGE_STORE_SIZE; @@ -412,15 +411,13 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length) int diff; uint translog_parts, extra_length; MARIA_HA *info= ma_page->info; - pgcache_page_no_t page; + pgcache_page_no_t page= ma_page->pos / info->s->block_size; DBUG_ENTER("_ma_log_suffix"); DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u", - (ulong) ma_page->pos, org_length, new_length)); + (ulong) page, org_length, new_length)); DBUG_ASSERT(ma_page->size == new_length); DBUG_ASSERT(ma_page->org_size == org_length); - page= ma_page->pos / info->s->block_size; - log_pos= log_data + FILEID_STORE_SIZE; page_store(log_pos, page); log_pos+= PAGE_STORE_SIZE; @@ -488,7 +485,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length) my_bool _ma_log_add(MARIA_PAGE *ma_page, uint org_page_length __attribute__ ((unused)), uchar *key_pos, uint changed_length, int move_length, - my_bool handle_overflow __attribute__ ((unused))) + my_bool handle_overflow __attribute__ ((unused)), + enum en_key_debug debug_marker __attribute__((unused))) { LSN lsn; uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 3 + 3 + 3 + 3 + 7 + @@ -500,31 +498,30 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page, uint offset= (uint) (key_pos - buff); uint max_page_size= info->s->max_index_block_size; uint translog_parts, current_size; - pgcache_page_no_t page_pos; + pgcache_page_no_t page_pos= ma_page->pos / info->s->block_size; DBUG_ENTER("_ma_log_add"); DBUG_PRINT("enter", ("page: %lu org_page_length: %u changed_length: %u " "move_length: %d", - (ulong) ma_page->pos, org_page_length, changed_length, + (ulong) page_pos, org_page_length, changed_length, move_length)); DBUG_ASSERT(info->s->now_transactional); DBUG_ASSERT(move_length <= (int) changed_length); DBUG_ASSERT(ma_page->org_size == min(org_page_length, max_page_size)); DBUG_ASSERT(ma_page->size == org_page_length + move_length); - DBUG_ASSERT(offset < max_page_size); + DBUG_ASSERT(offset <= ma_page->org_size); /* Write REDO entry that contains the logical operations we need to do the page */ log_pos= log_data + FILEID_STORE_SIZE; - page_pos= ma_page->pos / info->s->block_size; page_store(log_pos, page_pos); current_size= ma_page->org_size; log_pos+= PAGE_STORE_SIZE; #ifdef EXTRA_DEBUG_KEY_CHANGES *log_pos++= KEY_OP_DEBUG; - *log_pos++= KEY_OP_DEBUG_LOG_ADD; + *log_pos++= debug_marker; #endif /* Store keypage_flag */ @@ -574,11 +571,33 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page, log_pos+= 3; if (move_length) { + if (move_length < 0) + { + DBUG_ASSERT(offset - move_length <= org_page_length); + if (offset - move_length > current_size) + { + /* + Truncate to end of page. We will add data to it from + the page buffer below + */ + move_length= (int) offset - (int) current_size; + } + } log_pos[0]= KEY_OP_SHIFT; int2store(log_pos+1, move_length); log_pos+= 3; current_size+= move_length; } + /* + Handle case where page was shortend but 'changed_length' goes over + 'current_size'. This can only happen when there was a page overflow + and we will below add back the overflow part + */ + if (offset + changed_length > current_size) + { + DBUG_ASSERT(offset + changed_length <= ma_page->size); + changed_length= current_size - offset; + } log_pos[0]= KEY_OP_CHANGE; } int2store(log_pos+1, changed_length); @@ -1059,14 +1078,14 @@ uint _ma_apply_redo_index(MARIA_HA *info, check_page_length= uint2korr(header); crc= uint4korr(header+2); _ma_store_page_used(share, buff, page_length); - DBUG_ASSERT(check_page_length == page_length); - if (crc != (uint32) my_checksum(0, buff + LSN_STORE_SIZE, + if (check_page_length != page_length || + crc != (uint32) my_checksum(0, buff + LSN_STORE_SIZE, page_length - LSN_STORE_SIZE)) { DBUG_DUMP("KEY_OP_CHECK bad page", buff, page_length); - if (header + 6 + page_length <= header_end) + if (header + 6 + check_page_length <= header_end) { - DBUG_DUMP("KEY_OP_CHECK org page", header + 6, page_length); + DBUG_DUMP("KEY_OP_CHECK org page", header + 6, check_page_length); } DBUG_ASSERT("crc failure in REDO_INDEX" == 0); } @@ -1085,6 +1104,11 @@ uint _ma_apply_redo_index(MARIA_HA *info, DBUG_PRINT("redo", ("Debug: %u", (uint) header[0])); header++; break; + case KEY_OP_DEBUG_2: + DBUG_PRINT("redo", ("org_page_length: %u new_page_length: %u", + uint2korr(header), uint2korr(header+2))); + header+= 4; + break; case KEY_OP_MAX_PAGELENGTH: DBUG_PRINT("redo", ("key_op_max_page_length")); page_length= max_page_size; diff --git a/storage/maria/ma_key_recover.h b/storage/maria/ma_key_recover.h index 3fdb045ee40..d6b69010d5d 100644 --- a/storage/maria/ma_key_recover.h +++ b/storage/maria/ma_key_recover.h @@ -70,7 +70,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length, uint new_length); my_bool _ma_log_add(MARIA_PAGE *page, uint buff_length, uchar *key_pos, uint changed_length, int move_length, - my_bool handle_overflow); + my_bool handle_overflow, + enum en_key_debug debug_marker); my_bool _ma_log_delete(MARIA_PAGE *page, const uchar *key_pos, uint changed_length, uint move_length, uint append_length, enum en_key_debug debug_marker); diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c index b355d7bc792..6bb308e5959 100644 --- a/storage/maria/ma_locking.c +++ b/storage/maria/ma_locking.c @@ -63,7 +63,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type) { count= --share->w_locks; if (share->lock.update_status) - (*share->lock.update_status)(info); + _ma_update_status_with_lock(info); } --share->tot_locks; if (info->lock_type == F_WRLCK && !share->w_locks) diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index be86740d822..423cd2f0dd7 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -1086,34 +1086,14 @@ static my_bool translog_max_lsn_to_header(File file, LSN lsn) /* - Information from transaction log file header -*/ - -typedef struct st_loghandler_file_info -{ - /* - LSN_IMPOSSIBLE for current file (not finished file). - Maximum LSN of the record which parts stored in the - file. - */ - LSN max_lsn; - ulonglong timestamp; /* Time stamp */ - ulong maria_version; /* Version of maria loghandler */ - ulong mysql_version; /* Version of mysql server */ - ulong server_id; /* Server ID */ - ulong page_size; /* Loghandler page size */ - ulong file_number; /* Number of the file (from the file header) */ -} LOGHANDLER_FILE_INFO; - -/* @brief Extract hander file information from loghandler file page @param desc header information descriptor to be filled with information @param page_buff buffer with the page content */ -static void translog_interpret_file_header(LOGHANDLER_FILE_INFO *desc, - uchar *page_buff) +void translog_interpret_file_header(LOGHANDLER_FILE_INFO *desc, + uchar *page_buff) { uchar *ptr; @@ -2500,10 +2480,7 @@ my_bool translog_prev_buffer_flush_wait(struct st_translog_buffer *buffer) pthread_cond_wait(&buffer->prev_sent_to_disk_cond, &buffer->mutex); if (buffer->file != file || buffer->offset != offset || buffer->ver != ver) - { - translog_buffer_unlock(buffer); DBUG_RETURN(1); /* some the thread flushed the buffer already */ - } } while(buffer->prev_buffer_offset != buffer->prev_sent_to_disk); } DBUG_RETURN(0); @@ -3403,7 +3380,7 @@ my_bool translog_walk_filenames(const char *directory, @brief Fills table of dependence length of page header from page flags */ -static void translog_fill_overhead_table() +void translog_fill_overhead_table() { uint i; for (i= 0; i < TRANSLOG_FLAGS_NUM; i++) @@ -8325,156 +8302,6 @@ void translog_set_file_size(uint32 size) /** - Write debug information to log if we EXTRA_DEBUG is enabled -*/ - -my_bool translog_log_debug_info(TRN *trn __attribute__((unused)), - enum translog_debug_info_type type - __attribute__((unused)), - uchar *info __attribute__((unused)), - size_t length __attribute__((unused))) -{ -#ifdef EXTRA_DEBUG - LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; - uchar debug_type; - LSN lsn; - - if (!trn) - { - /* - We can't log the current transaction because we don't have - an active transaction. Use a temporary transaction object instead - */ - trn= &dummy_transaction_object; - } - debug_type= (uchar) type; - log_array[TRANSLOG_INTERNAL_PARTS + 0].str= &debug_type; - log_array[TRANSLOG_INTERNAL_PARTS + 0].length= 1; - log_array[TRANSLOG_INTERNAL_PARTS + 1].str= info; - log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length; - return translog_write_record(&lsn, LOGREC_DEBUG_INFO, - trn, NULL, - (translog_size_t) (1+ length), - sizeof(log_array)/sizeof(log_array[0]), - log_array, NULL, NULL); -#else - return 0; -#endif -} - - -#ifdef MARIA_DUMP_LOG -#include <my_getopt.h> -extern void translog_example_table_init(); -static const char *load_default_groups[]= { "maria_dump_log",0 }; -static void get_options(int *argc,char * * *argv); -#ifndef DBUG_OFF -#if defined(__WIN__) -const char *default_dbug_option= "d:t:i:O,\\maria_dump_log.trace"; -#else -const char *default_dbug_option= "d:t:i:o,/tmp/maria_dump_log.trace"; -#endif -#endif -static ulonglong opt_offset; -static ulong opt_pages; -static const char *opt_file= NULL; -static File handler= -1; -static my_bool opt_unit= 0; -static struct my_option my_long_options[] = -{ -#ifdef IMPLTMENTED - {"body", 'b', - "Print chunk body dump", - (uchar **) &opt_body, (uchar **) &opt_body, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#endif -#ifndef DBUG_OFF - {"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.", - 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#endif - {"file", 'f', "Path to file which will be read", - (uchar**) &opt_file, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"help", '?', "Display this help and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - { "offset", 'o', "Start reading log from this offset", - (uchar**) &opt_offset, (uchar**) &opt_offset, - 0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 }, - { "pages", 'n', "Number of pages to read", - (uchar**) &opt_pages, (uchar**) &opt_pages, 0, - GET_ULONG, REQUIRED_ARG, (long) ~(ulong) 0, - (long) 1, (long) ~(ulong) 0, (long) 0, - (long) 1, 0}, - {"unit-test", 'U', - "Use unit test record table (for logs created by unittests", - (uchar **) &opt_unit, (uchar **) &opt_unit, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"version", 'V', "Print version and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} -}; - - -static void print_version(void) -{ - VOID(printf("%s Ver 1.0 for %s on %s\n", - my_progname_short, SYSTEM_TYPE, MACHINE_TYPE)); - NETWARE_SET_SCREEN_MODE(1); -} - - -static void usage(void) -{ - print_version(); - puts("Copyright (C) 2008 MySQL AB"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); - puts("and you are welcome to modify and redistribute it under the GPL license\n"); - - puts("Dump content of maria log pages."); - VOID(printf("\nUsage: %s -f file OPTIONS\n", my_progname_short)); - my_print_help(my_long_options); - print_defaults("my", load_default_groups); - my_print_variables(my_long_options); -} - - -static my_bool -get_one_option(int optid __attribute__((unused)), - const struct my_option *opt __attribute__((unused)), - char *argument __attribute__((unused))) -{ - switch (optid) { - case '?': - usage(); - exit(0); - case 'V': - print_version(); - exit(0); -#ifndef DBUG_OFF - case '#': - DBUG_SET_INITIAL(argument ? argument : default_dbug_option); - break; -#endif - } - return 0; -} - - -static void get_options(int *argc,char ***argv) -{ - int ho_error; - - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) - exit(ho_error); - - if (opt_file == NULL) - { - usage(); - exit(1); - } -} - - -/** @brief Dump information about file header page. */ @@ -8658,7 +8485,7 @@ static uchar *dump_chunk(uchar *buffer, uchar *ptr) @brief Dump information about page with data. */ -static void dump_datapage(uchar *buffer) +static void dump_datapage(uchar *buffer, File handler) { uchar *ptr; ulong offset; @@ -8739,79 +8566,51 @@ static void dump_datapage(uchar *buffer) @brief Dump information about page. */ -static void dump_page(uchar *buffer) +void dump_page(uchar *buffer, File handler) { - printf("Page by offset %llu (0x%llx)\n", opt_offset, opt_offset); if (strncmp((char*)maria_trans_file_magic, (char*)buffer, sizeof(maria_trans_file_magic)) == 0) { dump_header_page(buffer); } - dump_datapage(buffer); + dump_datapage(buffer, handler); } /** - @brief maria_dump_log main function. + Write debug information to log if we EXTRA_DEBUG is enabled */ -int main(int argc, char **argv) +my_bool translog_log_debug_info(TRN *trn __attribute__((unused)), + enum translog_debug_info_type type + __attribute__((unused)), + uchar *info __attribute__((unused)), + size_t length __attribute__((unused))) { - char **default_argv; - uchar buffer[TRANSLOG_PAGE_SIZE]; - MY_INIT(argv[0]); - - load_defaults("my", load_default_groups, &argc, &argv); - default_argv= argv; - get_options(&argc, &argv); - - if (opt_unit) - translog_example_table_init(); - else - translog_table_init(); - translog_fill_overhead_table(); - - maria_data_root= (char *)"."; +#ifdef EXTRA_DEBUG + LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; + uchar debug_type; + LSN lsn; - if ((handler= my_open(opt_file, O_RDONLY, MYF(MY_WME))) < 0) - { - fprintf(stderr, "Can't open file: '%s' errno: %d\n", - opt_file, my_errno); - goto err; - } - if (my_seek(handler, opt_offset, SEEK_SET, MYF(MY_WME)) != - opt_offset) - { - fprintf(stderr, "Can't set position %lld file: '%s' errno: %d\n", - opt_offset, opt_file, my_errno); - goto err; - } - for (; - opt_pages; - opt_offset+= TRANSLOG_PAGE_SIZE, opt_pages--) + if (!trn) { - if (my_pread(handler, buffer, TRANSLOG_PAGE_SIZE, opt_offset, - MYF(MY_NABP))) - { - if (my_errno == HA_ERR_FILE_TOO_SHORT) - goto end; - fprintf(stderr, "Can't read page at position %lld file: '%s' " - "errno: %d\n", opt_offset, opt_file, my_errno); - goto err; - } - dump_page(buffer); + /* + We can't log the current transaction because we don't have + an active transaction. Use a temporary transaction object instead + */ + trn= &dummy_transaction_object; } - -end: - my_close(handler, MYF(0)); - free_defaults(default_argv); - exit(0); - return 0; /* No compiler warning */ - -err: - my_close(handler, MYF(0)); - fprintf(stderr, "%s: FAILED\n", my_progname_short); - free_defaults(default_argv); - exit(1); -} + debug_type= (uchar) type; + log_array[TRANSLOG_INTERNAL_PARTS + 0].str= &debug_type; + log_array[TRANSLOG_INTERNAL_PARTS + 0].length= 1; + log_array[TRANSLOG_INTERNAL_PARTS + 1].str= info; + log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length; + return translog_write_record(&lsn, LOGREC_DEBUG_INFO, + trn, NULL, + (translog_size_t) (1+ length), + sizeof(log_array)/sizeof(log_array[0]), + log_array, NULL, NULL); +#else + return 0; #endif +} diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h index 8e04164a81a..c22d361d142 100644 --- a/storage/maria/ma_loghandler.h +++ b/storage/maria/ma_loghandler.h @@ -167,7 +167,8 @@ enum en_key_op KEY_OP_SET_PAGEFLAG, /* Set pageflag from next byte */ KEY_OP_COMPACT_PAGE, /* Compact key page */ KEY_OP_MAX_PAGELENGTH, /* Set page to max page length */ - KEY_OP_DEBUG /* Entry for storing what triggered redo_index */ + KEY_OP_DEBUG, /* Entry for storing what triggered redo_index */ + KEY_OP_DEBUG_2 /* Entry for pagelengths */ }; enum en_key_debug @@ -178,18 +179,21 @@ enum en_key_debug KEY_OP_DEBUG_FATHER_CHANGED_1, /* 3 */ KEY_OP_DEBUG_FATHER_CHANGED_2, /* 4 */ KEY_OP_DEBUG_LOG_SPLIT, /* 5 */ - KEY_OP_DEBUG_LOG_ADD, /* 6 */ - KEY_OP_DEBUG_LOG_PREFIX_1, /* 7 */ - KEY_OP_DEBUG_LOG_PREFIX_2, /* 8 */ - KEY_OP_DEBUG_LOG_PREFIX_3, /* 9 */ - KEY_OP_DEBUG_LOG_PREFIX_4, /* 10 */ - KEY_OP_DEBUG_LOG_PREFIX_5, /* 11 */ - KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 12 */ - KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 13 */ - KEY_OP_DEBUG_LOG_DEL_CHANGE_3, /* 14 */ - KEY_OP_DEBUG_LOG_DEL_CHANGE_RT, /* 15 */ - KEY_OP_DEBUG_LOG_DEL_PREFIX, /* 16 */ - KEY_OP_DEBUG_LOG_MIDDLE /* 17 */ + KEY_OP_DEBUG_LOG_ADD_1, /* 6 */ + KEY_OP_DEBUG_LOG_ADD_2, /* 7 */ + KEY_OP_DEBUG_LOG_ADD_3, /* 8 */ + KEY_OP_DEBUG_LOG_ADD_4, /* 9 */ + KEY_OP_DEBUG_LOG_PREFIX_1, /* 10 */ + KEY_OP_DEBUG_LOG_PREFIX_2, /* 11 */ + KEY_OP_DEBUG_LOG_PREFIX_3, /* 12 */ + KEY_OP_DEBUG_LOG_PREFIX_4, /* 13 */ + KEY_OP_DEBUG_LOG_PREFIX_5, /* 14 */ + KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 15 */ + KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 16 */ + KEY_OP_DEBUG_LOG_DEL_CHANGE_3, /* 17 */ + KEY_OP_DEBUG_LOG_DEL_CHANGE_RT, /* 18 */ + KEY_OP_DEBUG_LOG_DEL_PREFIX, /* 19 */ + KEY_OP_DEBUG_LOG_MIDDLE /* 20 */ }; @@ -354,6 +358,7 @@ translog_assign_id_to_share_from_recovery(struct st_maria_share *share, extern my_bool translog_walk_filenames(const char *directory, my_bool (*callback)(const char *, const char *)); +extern void dump_page(uchar *buffer, File handler); extern my_bool translog_log_debug_info(TRN *trn, enum translog_debug_info_type type, uchar *info, size_t length); @@ -372,8 +377,31 @@ extern enum enum_translog_status translog_status; ma_loghandler_for_recovery.h ? */ +/* + Information from transaction log file header +*/ + +typedef struct st_loghandler_file_info +{ + /* + LSN_IMPOSSIBLE for current file (not finished file). + Maximum LSN of the record which parts stored in the + file. + */ + LSN max_lsn; + ulonglong timestamp; /* Time stamp */ + ulong maria_version; /* Version of maria loghandler */ + ulong mysql_version; /* Version of mysql server */ + ulong server_id; /* Server ID */ + ulong page_size; /* Loghandler page size */ + ulong file_number; /* Number of the file (from the file header) */ +} LOGHANDLER_FILE_INFO; + #define SHARE_ID_MAX 65535 /* array's size */ +extern void translog_fill_overhead_table(); +extern void translog_interpret_file_header(LOGHANDLER_FILE_INFO *desc, + uchar *page_buff); extern LSN translog_first_lsn_in_log(); extern LSN translog_first_theoretical_lsn(); extern LSN translog_next_LSN(TRANSLOG_ADDRESS addr, TRANSLOG_ADDRESS horizon); diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 39c13e27e15..63e1801a39a 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -434,8 +434,14 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->base.born_transactional && ((!(open_flags & HA_OPEN_IGNORE_MOVED_STATE) && memcmp(share->base.uuid, maria_uuid, MY_UUID_SIZE)) || - share->state.create_trid > trnman_get_max_trid())) + (share->state.create_trid > trnman_get_max_trid() && + !maria_in_recovery))) { + DBUG_PRINT("warning", ("table is moved from another system. uuid_diff: %d create_trid: %lu max_trid: %lu", + memcmp(share->base.uuid, maria_uuid, + MY_UUID_SIZE) != 0, + (ulong) share->state.create_trid, + (ulong) trnman_get_max_trid())); if (open_flags & HA_OPEN_FOR_REPAIR) share->state.changed|= STATE_MOVED; else @@ -868,8 +874,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->have_versioning= 1; share->row_is_visible= _ma_row_visible_transactional_table; share->lock.get_status= _ma_block_get_status; - share->lock.update_status= _ma_block_update_status; share->lock.check_status= _ma_block_check_status; + share->lock.start_trans= _ma_block_start_trans; /* We can for the moment only allow multiple concurrent inserts only if there is no auto-increment key. To lift this restriction @@ -897,7 +903,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) else if (share->now_transactional) { DBUG_ASSERT(share->data_file_type == BLOCK_RECORD); - share->lock.get_status= _ma_block_get_status_no_versioning; + share->lock.start_trans= _ma_block_start_trans_no_versioning; } } #endif diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 441310a60ea..1bb82ba92cd 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -2037,12 +2037,12 @@ restart: KEYCACHE_DBUG_PRINT("find_block", ("block is dirty")); - pagecache_pthread_mutex_unlock(&pagecache->cache_lock); /* The call is thread safe because only the current thread might change the block->hash_link value */ DBUG_ASSERT(block->pins == 0); + pagecache_pthread_mutex_unlock(&pagecache->cache_lock); error= pagecache_fwrite(pagecache, &block->hash_link->file, block->buffer, @@ -2255,14 +2255,17 @@ static my_bool pagecache_wait_lock(PAGECACHE *pagecache, #endif PCBLOCK_INFO(block); if ((block->status & (PCBLOCK_REASSIGNED | PCBLOCK_IN_SWITCH)) || + !block->hash_link || file.file != block->hash_link->file.file || pageno != block->hash_link->pageno) { DBUG_PRINT("info", ("the block 0x%lx changed => need retry " "status: %x files %d != %d or pages %lu != %lu", (ulong)block, block->status, - file.file, block->hash_link->file.file, - (ulong) pageno, (ulong) block->hash_link->pageno)); + file.file, + block->hash_link ? block->hash_link->file.file : -1, + (ulong) pageno, + (ulong) (block->hash_link ? block->hash_link->pageno : 0))); DBUG_RETURN(1); } DBUG_RETURN(0); @@ -2611,12 +2614,12 @@ static void read_block(PAGECACHE *pagecache, */ pagecache->global_cache_read++; - /* Page is not in buffer yet, is to be read from disk */ - pagecache_pthread_mutex_unlock(&pagecache->cache_lock); /* + Page is not in buffer yet, is to be read from disk Here other threads may step in and register as secondary readers. They will register in block->wqueue[COND_FOR_REQUESTED]. */ + pagecache_pthread_mutex_unlock(&pagecache->cache_lock); error= pagecache_fread(pagecache, &block->hash_link->file, block->buffer, block->hash_link->pageno, @@ -3450,6 +3453,14 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, my_bool flush) { my_bool error= 0; + if (block->status & PCBLOCK_IN_FLUSH) + { + /* + this call is just 'hint' for the cache to free the page so we will + not interferes with flushing process but gust return success + */ + goto out; + } if (block->status & PCBLOCK_CHANGED) { if (flush) @@ -3458,12 +3469,12 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, KEYCACHE_DBUG_PRINT("find_block", ("block is dirty")); - pagecache_pthread_mutex_unlock(&pagecache->cache_lock); /* The call is thread safe because only the current thread might change the block->hash_link value */ DBUG_ASSERT(block->pins == 1); + pagecache_pthread_mutex_unlock(&pagecache->cache_lock); error= pagecache_fwrite(pagecache, &block->hash_link->file, block->buffer, @@ -3478,7 +3489,26 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, block->status|= PCBLOCK_ERROR; block->error= (int16) my_errno; my_debug_put_break_here(); - goto err; + goto out; + } + } + else + { + PAGECACHE_FILE *filedesc= &block->hash_link->file; + /* We are not going to write the page but have to call callbacks */ + DBUG_PRINT("info", ("flush_callback :0x%lx" + "write_callback: 0x%lx data: 0x%lx", + (ulong) filedesc->flush_log_callback, + (ulong) filedesc->write_callback, + (ulong) filedesc->callback_data)); + if ((*filedesc->flush_log_callback) + (block->buffer, block->hash_link->pageno, filedesc->callback_data) || + (*filedesc->write_callback) + (block->buffer, block->hash_link->pageno, filedesc->callback_data)) + { + DBUG_PRINT("error", ("flush or write callback problem")); + error= 1; + goto out; } } pagecache->blocks_changed--; @@ -3498,7 +3528,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, /* See NOTE for pagecache_unlock about registering requests. */ free_block(pagecache, block); -err: +out: dec_counter_for_resize_op(pagecache); return error; } @@ -4087,6 +4117,7 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block) ("block: %u hash_link 0x%lx", PCBLOCK_NUMBER(pagecache, block), (long) block->hash_link)); + safe_mutex_assert_owner(&pagecache->cache_lock); if (block->hash_link) { /* @@ -4114,6 +4145,8 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block) KEYCACHE_DBUG_PRINT("free_block", ("block is freed")); unreg_request(pagecache, block, 0); + DBUG_ASSERT(block->requests == 0); + DBUG_ASSERT(block->next_used != 0); block->hash_link= NULL; /* Remove the free block from the LRU ring. */ @@ -4223,7 +4256,6 @@ static int flush_cached_blocks(PAGECACHE *pagecache, DBUG_PRINT("info", ("block: %u (0x%lx) to be flushed", PCBLOCK_NUMBER(pagecache, block), (ulong)block)); PCBLOCK_INFO(block); - pagecache_pthread_mutex_unlock(&pagecache->cache_lock); DBUG_PRINT("info", ("block: %u (0x%lx) pins: %u", PCBLOCK_NUMBER(pagecache, block), (ulong)block, block->pins)); @@ -4237,6 +4269,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache, content (see StaleFilePointersInFlush in ma_checkpoint.c). @todo change argument of functions to be File. */ + pagecache_pthread_mutex_unlock(&pagecache->cache_lock); error= pagecache_fwrite(pagecache, &block->hash_link->file, block->buffer, block->hash_link->pageno, diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index c0205b5ed00..c88aedfca78 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -332,6 +332,8 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn, if (end_lsn != LSN_IMPOSSIBLE) { abort_message_printed= 1; + if (!trace_file) + fputc('\n', stderr); my_message(HA_ERR_INITIALIZATION, "Maria recovery aborted as end_lsn/end of file was reached", MYF(0)); @@ -502,9 +504,13 @@ end: } if (error && !abort_message_printed) + { + if (!trace_file) + fputc('\n', stderr); my_message(HA_ERR_INITIALIZATION, "Maria recovery failed. Please run maria_chk -r on all maria " "tables and delete all maria_log.######## files", MYF(0)); + } procent_printed= 0; /* We don't cleanly close tables if we hit some error (may corrupt them by @@ -548,6 +554,11 @@ static int display_and_apply_record(const LOG_DESC *log_desc, DBUG_ASSERT("one more hook to write" == 0); return 1; } + if (rec->type == LOGREC_DEBUG_INFO) + { + /* Query already printed by display_record_position() */ + return 0; + } if ((error= (*log_desc->record_execute_in_redo_phase)(rec))) eprint(tracef, "Got error %d when executing record %s", my_errno, log_desc->name); @@ -638,6 +649,20 @@ prototype_redo_exec_hook(INCOMPLETE_LOG) /* no such table, don't need to warn */ return 0; } + + if (maria_is_crashed(info)) + return 0; + + if (info->s->state.is_of_horizon > rec->lsn) + { + /* + This table was repaired at a time after this log entry. + We can assume that all rows was inserted sucessfully and we don't + have to warn about that the inserted data was not logged + */ + return 0; + } + /* Example of what can go wrong when replaying DDLs: CREATE TABLE t (logged); INSERT INTO t VALUES(1) (logged); @@ -658,15 +683,59 @@ prototype_redo_exec_hook(INCOMPLETE_LOG) there was a crash during a DDL (see comment in execution of REDO_RENAME_TABLE ). */ - tprint(tracef, "***WARNING: MySQL server currently logs no records" - " about insertion of data by ALTER TABLE and CREATE SELECT," - " as they are not necessary for recovery;" - " present applying of log records may well not work.***\n"); + + eprint(tracef, "***WARNING: Aria engine currently logs no records " + "about insertion of data by ALTER TABLE and CREATE SELECT, " + "as they are not necessary for recovery; " + "present applying of log records to table '%s' may well not work." + "***", info->s->index_file_name.str); + + /* Prevent using the table for anything else than undo repair */ + _ma_mark_file_crashed(info->s); recovery_warnings++; return 0; } +static my_bool create_database_if_not_exists(const char *name) +{ + char dirname[FN_REFLEN]; + size_t length; + MY_STAT stat_info; + DBUG_ENTER("create_database_if_not_exists"); + + dirname_part(dirname, name, &length); + if (!length) + { + /* Skip files without directores */ + DBUG_RETURN(0); + } + /* + Safety; Don't create files with hard path; + Should never happen with MariaDB + If hard path, then error will be detected when trying to create index file + */ + if (test_if_hard_path(dirname)) + DBUG_RETURN(0); + + if (my_stat(dirname,&stat_info,MYF(0))) + DBUG_RETURN(0); + + + tprint(tracef, "Creating not existing database '%s'\n", dirname); + if (my_mkdir(dirname, 0777, MYF(MY_WME))) + { + eprint(tracef, "***WARNING: Can't create not existing database '%s'", + dirname); + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + + + + + prototype_redo_exec_hook(REDO_CREATE_TABLE) { File dfile= -1, kfile= -1; @@ -678,11 +747,12 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) int error= 1, create_mode= O_RDWR | O_TRUNC, i; MARIA_HA *info= NULL; uint kfile_size_before_extension, keystart; + DBUG_ENTER("exec_REDO_LOGREC_REDO_CREATE_TABLE"); if (skip_DDLs) { tprint(tracef, "we skip DDLs\n"); - return 0; + DBUG_RETURN(0); } enlarge_buffer(rec); if (log_record_buffer.str == NULL || @@ -785,6 +855,8 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) name); goto end; } + if (create_database_if_not_exists(name)) + goto end; fn_format(filename, name, "", MARIA_NAME_IEXT, (MY_UNPACK_FILENAME | (flags & HA_DONT_TOUCH_DATA) ? MY_RETURN_REAL_PATH : 0) | @@ -838,7 +910,7 @@ end: error|= my_close(kfile, MYF(MY_WME)); if (info != NULL) error|= maria_close(info); - return error; + DBUG_RETURN(error); } @@ -847,10 +919,12 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE) char *old_name, *new_name; int error= 1; MARIA_HA *info= NULL; + DBUG_ENTER("exec_REDO_LOGREC_REDO_RENAME_TABLE"); + if (skip_DDLs) { tprint(tracef, "we skip DDLs\n"); - return 0; + DBUG_RETURN(0); } enlarge_buffer(rec); if (log_record_buffer.str == NULL || @@ -1025,7 +1099,7 @@ end: tprint(tracef, "\n"); if (info != NULL) error|= maria_close(info); - return error; + DBUG_RETURN(error); } @@ -1052,7 +1126,11 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE) } if ((info= get_MARIA_HA_from_REDO_record(rec)) == NULL) DBUG_RETURN(0); - + if (maria_is_crashed(info)) + { + tprint(tracef, "we skip repairing crashed table\n"); + DBUG_RETURN(0); + } /* Otherwise, the mapping is newer than the table, and our record is newer than the mapping, so we can repair. @@ -1223,6 +1301,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) MARIA_HA *info; MARIA_SHARE *share; my_off_t dfile_len, kfile_len; + DBUG_ENTER("new_table"); checkpoint_useful= TRUE; if ((name == NULL) || (name[0] == 0)) @@ -1259,6 +1338,12 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) */ if (close_one_table(share->open_file_name.str, lsn_of_file_id)) goto end; + /* + We should not try to get length of data/index files as the files + are not on disk yet. + */ + _ma_tmp_disable_logging_for_table(info, FALSE); + goto set_lsn_of_file_id; } if (!share->base.born_transactional) { @@ -1327,6 +1412,8 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) /* Recovery will fix this, no error */ ALERT_USER(); } + +set_lsn_of_file_id: /* This LSN serves in this situation; assume log is: FILE_ID(6->"t2") REDO_INSERT(6) FILE_ID(6->"t1") CHECKPOINT(6->"t1") @@ -1354,7 +1441,7 @@ end: if (error == -1) error= 0; } - return error; + DBUG_RETURN(error); } /* @@ -1367,7 +1454,8 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_HEAD) int error= 1; uchar *buff= NULL; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) + { /* Table was skipped at open time (because later dropped/renamed, not @@ -1433,7 +1521,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_TAIL) int error= 1; uchar *buff; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; enlarge_buffer(rec); if (log_record_buffer.str == NULL || @@ -1474,7 +1562,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_BLOBS) pgcache_page_no_t first_page, last_page; char llbuf1[22], llbuf2[22]; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; enlarge_buffer(rec); if (log_record_buffer.str == NULL || @@ -1508,7 +1596,7 @@ prototype_redo_exec_hook(REDO_PURGE_ROW_HEAD) { int error= 1; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; if (_ma_apply_redo_purge_row_head_or_tail(info, current_group_end_lsn, HEAD_PAGE, @@ -1524,7 +1612,7 @@ prototype_redo_exec_hook(REDO_PURGE_ROW_TAIL) { int error= 1; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; if (_ma_apply_redo_purge_row_head_or_tail(info, current_group_end_lsn, TAIL_PAGE, @@ -1541,7 +1629,7 @@ prototype_redo_exec_hook(REDO_FREE_BLOCKS) int error= 1; uchar *buff; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; enlarge_buffer(rec); @@ -1568,7 +1656,7 @@ prototype_redo_exec_hook(REDO_FREE_HEAD_OR_TAIL) { int error= 1; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; if (_ma_apply_redo_free_head_or_tail(info, current_group_end_lsn, @@ -1600,7 +1688,7 @@ prototype_redo_exec_hook(REDO_INDEX) { int error= 1; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; enlarge_buffer(rec); @@ -1626,7 +1714,7 @@ prototype_redo_exec_hook(REDO_INDEX_NEW_PAGE) { int error= 1; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; enlarge_buffer(rec); @@ -1653,7 +1741,7 @@ prototype_redo_exec_hook(REDO_INDEX_FREE_PAGE) { int error= 1; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; if (_ma_apply_redo_index_free_page(info, current_group_end_lsn, @@ -1669,7 +1757,7 @@ prototype_redo_exec_hook(REDO_BITMAP_NEW_PAGE) { int error= 1; MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec); - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) return 0; enlarge_buffer(rec); @@ -2115,7 +2203,7 @@ prototype_undo_exec_hook(UNDO_ROW_INSERT) MARIA_SHARE *share; const uchar *record_ptr; - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) { /* Unlike for REDOs, if the table was skipped it is abnormal; we have a @@ -2171,7 +2259,7 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE) LSN previous_undo_lsn= lsn_korr(rec->header); MARIA_SHARE *share; - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) { skip_undo_record(previous_undo_lsn, trn); return 0; @@ -2210,7 +2298,7 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE) LSN previous_undo_lsn= lsn_korr(rec->header); MARIA_SHARE *share; - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) { skip_undo_record(previous_undo_lsn, trn); return 0; @@ -2249,7 +2337,7 @@ prototype_undo_exec_hook(UNDO_KEY_INSERT) LSN previous_undo_lsn= lsn_korr(rec->header); MARIA_SHARE *share; - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) { skip_undo_record(previous_undo_lsn, trn); return 0; @@ -2290,7 +2378,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE) LSN previous_undo_lsn= lsn_korr(rec->header); MARIA_SHARE *share; - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) { skip_undo_record(previous_undo_lsn, trn); return 0; @@ -2331,7 +2419,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT) LSN previous_undo_lsn= lsn_korr(rec->header); MARIA_SHARE *share; - if (info == NULL) + if (info == NULL || maria_is_crashed(info)) { skip_undo_record(previous_undo_lsn, trn); return 0; @@ -2372,6 +2460,7 @@ prototype_undo_exec_hook(UNDO_BULK_INSERT) LSN previous_undo_lsn= lsn_korr(rec->header); MARIA_SHARE *share; + /* Here we don't check for crashed as we can undo the bulk insert */ if (info == NULL) { skip_undo_record(previous_undo_lsn, trn); @@ -3290,7 +3379,12 @@ static int close_all_tables(void) state while they were used. As Recovery corrected them, don't alarm the user, don't ask for a table check: */ - info->s->state.open_count= 0; + if (info->s->state.open_count != 0) + { + /* let ma_close() mark the table properly closed */ + info->s->state.open_count= 1; + info->s->global_changed= 1; + } prepare_table_for_close(info, addr); error|= maria_close(info); pthread_mutex_lock(&THR_LOCK_maria); diff --git a/storage/maria/ma_rt_key.c b/storage/maria/ma_rt_key.c index 2e204990a3b..fa173605cd3 100644 --- a/storage/maria/ma_rt_key.c +++ b/storage/maria/ma_rt_key.c @@ -59,7 +59,8 @@ int maria_rtree_add_key(const MARIA_KEY *key, MARIA_PAGE *page, page_store_size(share, page); if (share->now_transactional && _ma_log_add(page, key_pos - page->buff, - key_pos, tot_key_length, tot_key_length, 0)) + key_pos, tot_key_length, tot_key_length, 0, + KEY_OP_DEBUG_LOG_ADD_1)) DBUG_RETURN(-1); DBUG_RETURN(0); } diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c index a5b9bf18aa9..e1683dad34a 100644 --- a/storage/maria/ma_search.c +++ b/storage/maria/ma_search.c @@ -116,8 +116,9 @@ static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key, MARIA_PAGE page; MARIA_PINNED_PAGE *page_link; DBUG_ENTER("_ma_search"); - DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu", - (ulong) pos, nextflag, (ulong) info->cur_row.lastpos)); + DBUG_PRINT("enter",("page: %lu nextflag: %u lastpos: %lu", + (ulong) (pos / info->s->block_size), + nextflag, (ulong) info->cur_row.lastpos)); DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, key);); if (pos == HA_OFFSET_ERROR) diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c index c7eee7d511d..ca94d58264b 100644 --- a/storage/maria/ma_state.c +++ b/storage/maria/ma_state.c @@ -335,6 +335,25 @@ void _ma_update_status(void* param) } +/* + Same as ma_update_status() but take a lock in the table lock, to protect + against someone calling ma_get_status() from thr_lock() at the same time. +*/ + +void _ma_update_status_with_lock(MARIA_HA *info) +{ + my_bool locked= 0; + if (info->state == &info->state_save) + { + locked= 1; + pthread_mutex_lock(&info->s->lock.mutex); + } + (*info->s->lock.update_status)(info); + if (locked) + pthread_mutex_unlock(&info->s->lock.mutex); +} + + void _ma_restore_status(void *param) { MARIA_HA *info= (MARIA_HA*) param; @@ -585,7 +604,13 @@ void _ma_block_get_status(void* param, my_bool concurrent_insert) { DBUG_ASSERT(info->lock.type != TL_WRITE_CONCURRENT_INSERT); } + DBUG_VOID_RETURN; +} + +my_bool _ma_block_start_trans(void* param) +{ + MARIA_HA *info=(MARIA_HA*) param; if (info->s->lock_key_trees) { /* @@ -593,24 +618,22 @@ void _ma_block_get_status(void* param, my_bool concurrent_insert) out of memory conditions) TODO: Fix this by having one extra state pre-allocated */ - (void) _ma_setup_live_state(info); + return _ma_setup_live_state(info); } - else + + /* + Info->trn is set if this table is already handled and we are + called from maria_versioning() + */ + if (info->s->base.born_transactional && !info->trn) { /* - Info->trn is set if this table is already handled and we are - called from maria_versioning() + Assume for now that this doesn't fail (It can only fail in + out of memory conditions) */ - if (info->s->base.born_transactional && !info->trn) - { - /* - Assume for now that this doesn't fail (It can only fail in - out of memory conditions) - */ - (void) maria_create_trn_hook(info); - } + return maria_create_trn_hook(info) != 0; } - DBUG_VOID_RETURN; + return 0; } @@ -639,13 +662,10 @@ my_bool _ma_block_check_status(void *param __attribute__((unused))) /* Get status when transactional but not versioned */ -void _ma_block_get_status_no_versioning(void* param, - my_bool concurrent_insert - __attribute__((unused))) +my_bool _ma_block_start_trans_no_versioning(void* param) { MARIA_HA *info=(MARIA_HA*) param; DBUG_ENTER("_ma_block_get_status_no_version"); - DBUG_PRINT("enter", ("concurrent_insert %d", concurrent_insert)); DBUG_ASSERT(info->s->base.born_transactional); info->state->changed= 0; /* from _ma_reset_update_flag() */ @@ -655,9 +675,9 @@ void _ma_block_get_status_no_versioning(void* param, Assume for now that this doesn't fail (It can only fail in out of memory conditions) */ - (void) maria_create_trn_hook(info); + DBUG_RETURN(maria_create_trn_hook(info)); } - DBUG_VOID_RETURN; + DBUG_RETURN(0); } diff --git a/storage/maria/ma_state.h b/storage/maria/ma_state.h index f3317f0084a..03ce5c2ea8c 100644 --- a/storage/maria/ma_state.h +++ b/storage/maria/ma_state.h @@ -62,6 +62,7 @@ MARIA_STATE_HISTORY *_ma_remove_not_visible_states(MARIA_STATE_HISTORY void _ma_reset_state(MARIA_HA *info); void _ma_get_status(void* param, my_bool concurrent_insert); void _ma_update_status(void* param); +void _ma_update_status_with_lock(MARIA_HA *info); void _ma_restore_status(void *param); void _ma_copy_status(void* to, void *from); void _ma_reset_update_flag(void *param, my_bool concurrent_insert); diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index 958a07e1c70..02eeec754ee 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -613,7 +613,7 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key, MARIA_KEYDEF *keyinfo= key->keyinfo; MARIA_PAGE page; DBUG_ENTER("w_search"); - DBUG_PRINT("enter",("page: %ld", (long) page_pos)); + DBUG_PRINT("enter", ("page: %lu", (ulong) (page_pos/keyinfo->block_length))); if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+ MARIA_MAX_KEY_BUFF*2))) @@ -678,7 +678,6 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key, } else /* not HA_FULLTEXT, normal HA_NOSAME key */ { - DBUG_PRINT("warning", ("Duplicate key")); /* TODO When the index will support true versioning - with multiple @@ -696,6 +695,12 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key, info->dup_key_trid= _ma_trid_from_key(&tmp_key); info->dup_key_pos= dup_key_pos; my_errno= HA_ERR_FOUND_DUPP_KEY; + DBUG_PRINT("warning", + ("Duplicate key. dup_key_trid: %lu pos %lu visible: %d", + (ulong) info->dup_key_trid, + (ulong) info->dup_key_pos, + info->trn ? trnman_can_read_from(info->trn, + info->dup_key_trid) : 2)); goto err; } } @@ -768,6 +773,10 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, DBUG_PRINT("enter",("key_pos: 0x%lx", (ulong) key_pos)); DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, key);); + /* + Note that anc_page->size can be bigger then block_size in case of + delete key that caused increase of page length + */ org_anc_length= a_length= anc_page->size; nod_flag= anc_page->node; @@ -887,7 +896,8 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0 { if (share->now_transactional && _ma_log_add(anc_page, org_anc_length, - key_pos, s_temp.changed_length, t_length, 1)) + key_pos, s_temp.changed_length, t_length, 1, + KEY_OP_DEBUG_LOG_ADD_1)) DBUG_RETURN(-1); } DBUG_RETURN(0); /* There is room on page */ @@ -911,7 +921,9 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0 father_page, father_key_pos, &s_temp)); } - DBUG_RETURN(_ma_split_page(info, key, anc_page, org_anc_length, + DBUG_RETURN(_ma_split_page(info, key, anc_page, + min(org_anc_length, + info->s->max_index_block_size), key_pos, s_temp.changed_length, t_length, key_buff, insert_last)); } /* _ma_insert */ @@ -1239,7 +1251,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, father_key_pos+father_keylength); left_page= curr_page; right_page= &next_page; - DBUG_PRINT("info", ("use right page: %lu", (ulong) next_page.pos)); + DBUG_PRINT("info", ("use right page: %lu", + (ulong) (next_page.pos / keyinfo->block_length))); } else { @@ -1248,7 +1261,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, next_page.pos= _ma_kpos(share->base.key_reflength,father_key_pos); left_page= &next_page; right_page= curr_page; - DBUG_PRINT("info", ("use left page: %lu", (ulong) next_page.pos)); + DBUG_PRINT("info", ("use left page: %lu", + (ulong) (next_page.pos / keyinfo->block_length))); } /* father_key_pos ptr to parting key */ if (_ma_fetch_keypage(&next_page, info, keyinfo, next_page.pos, @@ -1864,14 +1878,13 @@ my_bool _ma_log_new(MARIA_PAGE *ma_page, my_bool root_page) LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; MARIA_HA *info= ma_page->info; MARIA_SHARE *share= info->s; - my_off_t page; + my_off_t page= ma_page->pos / share->block_size; DBUG_ENTER("_ma_log_new"); - DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos)); + DBUG_PRINT("enter", ("page: %lu", (ulong) page)); DBUG_ASSERT(share->now_transactional); /* Store address of new root page */ - page= ma_page->pos / share->block_size; page_store(log_data + FILEID_STORE_SIZE, page); /* Store link to next unused page */ @@ -1920,10 +1933,10 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length, uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 6 + 7], *log_pos; LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4]; uint offset= (uint) (key_pos - ma_page->buff), translog_parts; - my_off_t page; MARIA_HA *info= ma_page->info; + my_off_t page= ma_page->pos / info->s->block_size; DBUG_ENTER("_ma_log_change"); - DBUG_PRINT("enter", ("page: %lu length: %u", (ulong) ma_page->pos, length)); + DBUG_PRINT("enter", ("page: %lu length: %u", (ulong) page, length)); DBUG_ASSERT(info->s->now_transactional); DBUG_ASSERT(offset + length <= ma_page->size); @@ -1971,7 +1984,8 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length, @fn _ma_log_split() @param ma_page Page that is changed - org_length Original length of page + org_length Original length of page. Can be bigger than block_size + for block that overflowed new_length New length of page key_pos Where key is inserted on page (may be 0 if no key) key_length Number of bytes changed at key_pos @@ -2005,16 +2019,17 @@ static my_bool _ma_log_split(MARIA_PAGE *ma_page, uint offset= (uint) (key_pos - ma_page->buff); uint translog_parts, extra_length; MARIA_HA *info= ma_page->info; - my_off_t page; + my_off_t page= ma_page->pos / info->s->block_size; DBUG_ENTER("_ma_log_split"); DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u", - (ulong) ma_page->pos, org_length, new_length)); + (ulong) page, org_length, new_length)); DBUG_ASSERT(changed_length >= data_length); DBUG_ASSERT(org_length <= info->s->max_index_block_size); + DBUG_ASSERT(new_length == ma_page->size); + DBUG_ASSERT(org_length == ma_page->org_size); log_pos= log_data + FILEID_STORE_SIZE; - page= ma_page->pos / info->s->block_size; page_store(log_pos, page); log_pos+= PAGE_STORE_SIZE; @@ -2169,16 +2184,16 @@ static my_bool _ma_log_del_prefix(MARIA_PAGE *ma_page, uint diff_length= org_length + move_length - new_length; uint translog_parts, extra_length; MARIA_HA *info= ma_page->info; - my_off_t page; + my_off_t page= ma_page->pos / info->s->block_size; DBUG_ENTER("_ma_log_del_prefix"); DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u", - (ulong) ma_page->pos, org_length, new_length)); + (ulong) page, org_length, new_length)); DBUG_ASSERT((int) diff_length > 0); + DBUG_ASSERT(ma_page->org_size == org_length); DBUG_ASSERT(ma_page->size == new_length); log_pos= log_data + FILEID_STORE_SIZE; - page= ma_page->pos / info->s->block_size; page_store(log_pos, page); log_pos+= PAGE_STORE_SIZE; @@ -2277,10 +2292,10 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page, LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 6]; uint key_offset; uint translog_parts, extra_length; - my_off_t page; MARIA_HA *info= ma_page->info; + my_off_t page= ma_page->pos / info->s->block_size; DBUG_ENTER("_ma_log_key_middle"); - DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos)); + DBUG_PRINT("enter", ("page: %lu", (ulong) page)); DBUG_ASSERT(ma_page->size == new_length); @@ -2304,8 +2319,6 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page, data_deleted_last+= move_length; } - page= ma_page->pos / info->s->block_size; - /* First log changes to page */ log_pos= log_data + FILEID_STORE_SIZE; page_store(log_pos, page); @@ -2400,7 +2413,7 @@ static my_bool _ma_log_middle(MARIA_PAGE *ma_page, LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 4]; uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 5 + 7], *log_pos; MARIA_HA *info= ma_page->info; - my_off_t page; + my_off_t page= ma_page->page / info->s->block_size; uint translog_parts, extra_length; DBUG_ENTER("_ma_log_middle"); DBUG_PRINT("enter", ("page: %lu", (ulong) page)); @@ -2408,8 +2421,6 @@ static my_bool _ma_log_middle(MARIA_PAGE *ma_page, DBUG_ASSERT(ma_page->org_size + data_added_first - data_deleted_last == ma_page->size); - page= ma_page->page / info->s->block_size; - log_pos= log_data + FILEID_STORE_SIZE; page_store(log_pos, page); log_pos+= PAGE_STORE_SIZE; diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index ae840467894..d065070693f 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -271,10 +271,10 @@ static struct my_option my_long_options[] = &check_param.keys_in_use, 0, GET_ULL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0}, {"datadir", OPT_DATADIR, - "Path for control file (and logs if --log-dir not used).", + "Path for control file (and logs if --logdir not used).", &maria_data_root, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"log-dir", OPT_LOG_DIR, + {"logdir", OPT_LOG_DIR, "Path for log files.", (char**) &opt_log_dir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"max-record-length", OPT_MAX_RECORD_LENGTH, @@ -320,9 +320,6 @@ static struct my_option my_long_options[] = "Change the collation used by the index", (char**) &set_collation_name, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"set-variable", 'O', - "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"silent", 's', "Only print errors. One can use two -s to make maria_chk very silent.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -353,7 +350,7 @@ static struct my_option my_long_options[] = "properly closed'", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"unpack", 'u', - "Unpack file packed with mariapack.", + "Unpack file packed with maria_pack.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Print more information. This can be used with --description and --check. Use many -v for more verbosity!", @@ -372,12 +369,14 @@ static struct my_option my_long_options[] = &check_param.use_buffers, &check_param.use_buffers, 0, GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, 1024L*1024L, (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0}, - { "read_buffer_size", OPT_READ_BUFFER_SIZE, "", + { "read_buffer_size", OPT_READ_BUFFER_SIZE, + "Read buffer size for sequential reads during scanning", &check_param.read_buffer_length, &check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, - { "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "", + { "write_buffer_size", OPT_WRITE_BUFFER_SIZE, + "Write buffer size for sequential writes during repair of fixed size or dynamic size rows", &check_param.write_buffer_length, &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, @@ -388,7 +387,8 @@ static struct my_option my_long_options[] = &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, - { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "", + { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, + "Internal buffer for sorting keys; Don't touch :)", &check_param.sort_key_blocks, &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG, BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0}, @@ -411,7 +411,7 @@ static struct my_option my_long_options[] = (char**) &maria_stats_method_str, (char**) &maria_stats_method_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { "zerofill", 'z', - "Fill empty space in data and index files with zeroes", + "Fill empty space in data and index files with zeroes,", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, { "zerofill-keep-lsn", OPT_ZEROFILL_KEEP_LSN, "Like --zerofill but does not zero out LSN of data/index pages;" @@ -447,10 +447,12 @@ static void usage(void) printf("\ -H, --HELP Display this help and exit.\n\ -?, --help Display this help and exit.\n\ - -O, --set-variable var=option.\n\ - Change the value of a variable. Please note that\n\ - this option is deprecated; you can set variables\n\ - directly with '--variable-name=value'.\n\ + --datadir=path Path for control file (and logs if --logdir not used)\n\ + --logdir=path Path for log files\n\ + --require-control-file Abort if we can't find/read the maria_log_control\n\ + file\n\ + -s, --silent Only print errors. One can use two -s to make\n\ + maria_chk very silent.\n\ -t, --tmpdir=path Path for temporary files. Multiple paths can be\n\ specified, separated by "); #if defined( __WIN__) || defined(__NETWARE__) @@ -458,12 +460,8 @@ static void usage(void) #else printf("colon (:)"); #endif - printf(", they will be used\n\ + printf(", they will be used\n\ in a round-robin fashion.\n\ - --require-control-file Abort if we can't find/read the maria_log_control\n\ - file\n\ - -s, --silent Only print errors. One can use two -s to make\n\ - maria_chk very silent.\n\ -v, --verbose Print more information. This can be used with\n\ --description and --check. Use many -v for more verbosity.\n\ -V, --version Print version and exit.\n\ @@ -485,10 +483,11 @@ static void usage(void) -i, --information Print statistics information about table that is checked.\n\ -m, --medium-check Faster than extend-check, but only finds 99.99% of\n\ all errors. Should be good enough for most cases.\n\ - -U --update-state Mark tables as crashed if you find any errors.\n\ + -U, --update-state Mark tables as crashed if you find any errors.\n\ -T, --read-only Don't mark table as checked.\n"); - puts("Recover (repair)/ options (When using '-r' or '-o'):\n\ + puts("\ +Recover (repair)/ options (When using '--recover' or '--safe-recover'):\n\ -B, --backup Make a backup of the .MAD file as 'filename-time.BAK'.\n\ --correct-checksum Correct checksum information for table.\n\ -D, --data-file-length=# Max length of data file (when recreating data\n\ @@ -531,7 +530,7 @@ static void usage(void) puts("Other actions:\n\ -a, --analyze Analyze distribution of keys. Will make some joins in\n\ - MySQL faster. You can check the calculated distribution\n\ + MariaDB faster. You can check the calculated distribution\n\ by using '--description --verbose table_name'.\n\ --stats_method=name Specifies how index statistics collection code should\n\ treat NULLs. Possible values of name are \"nulls_unequal\"\n\ @@ -554,6 +553,13 @@ static void usage(void) --zerofill-keep-lsn Like --zerofill but does not zero out LSN of\n\ data/index pages."); + puts("Variables:\n\ +--page_buffer_size=# Size of page buffer. Used by --safe-repair\n\ +--read_buffer_size=# Read buffer size for sequential reads during scanning\n\ +--sort_buffer_size=# Size of sort buffer. Used by --recover\n\ +--sort_key_blocks=# Internal buffer for sorting keys; Don't touch :)\n\ +--write_buffer_size=# Write buffer size for sequential writes during repair"); + print_defaults("my", load_default_groups); my_print_variables(my_long_options); } @@ -1205,7 +1211,7 @@ static int maria_chk(HA_CHECK *param, char *filename) { /* Change temp file to org file */ VOID(my_close(info->dfile.file, MYF(MY_WME))); /* Close new file */ error|=maria_change_to_newfile(filename,MARIA_NAME_DEXT,DATA_TMP_EXT, - MYF(0)); + 0, MYF(0)); if (_ma_open_datafile(info,info->s, NullS, -1)) error=1; param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */ @@ -1343,11 +1349,9 @@ end2: { if (param->out_flag & O_NEW_DATA) error|=maria_change_to_newfile(filename,MARIA_NAME_DEXT,DATA_TMP_EXT, + param->backup_time, ((param->testflag & T_BACKUP_DATA) ? MYF(MY_REDEL_MAKE_BACKUP) : MYF(0))); - if (param->out_flag & O_NEW_INDEX) - error|=maria_change_to_newfile(filename,MARIA_NAME_IEXT,INDEX_TMP_EXT, - MYF(0)); } if (opt_transaction_logging && share->base.born_transactional && !error && @@ -1451,7 +1455,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) printf("UUID: %s\n", buff); pos=buff; if (share->state.changed & STATE_CRASHED) - strmov(buff,"crashed"); + strmov(buff, share->state.changed & STATE_CRASHED_ON_REPAIR ? + "crashed on repair" : "crashed"); else { if (share->state.open_count) diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 28f2fd8638d..b998ac4f3a0 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -244,8 +244,9 @@ typedef struct st_maria_file_bitmap uchar *map; pgcache_page_no_t page; /* Page number for current bitmap */ uint used_size; /* Size of bitmap head that is not 0 */ - my_bool changed; /* 1 if page needs to be flushed */ - my_bool flush_all_requested; /**< If _ma_bitmap_flush_all waiting */ + my_bool changed; /* 1 if page needs to be written */ + my_bool changed_not_flushed; /* 1 if some bitmap is not flushed */ + uint flush_all_requested; /**< If _ma_bitmap_flush_all waiting */ uint non_flushable; /**< 0 if bitmap and log are in sync */ PAGECACHE_FILE file; /* datafile where bitmap is stored */ @@ -475,7 +476,7 @@ typedef struct st_maria_block_scan { uchar *bitmap_buff, *bitmap_pos, *bitmap_end, *page_buff; uchar *dir, *dir_end; - pgcache_page_no_t bitmap_page; + pgcache_page_no_t bitmap_page, max_page; ulonglong bits; uint number_of_rows, bit_pos; MARIA_RECORD_POS row_base_page; diff --git a/storage/maria/maria_dump_log.c b/storage/maria/maria_dump_log.c new file mode 100644 index 00000000000..bc7ec566462 --- /dev/null +++ b/storage/maria/maria_dump_log.c @@ -0,0 +1,190 @@ +/* Copyright (C) 2007 MySQL AB & Sanja Belkin + + 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; version 2 of the License. + + 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 "maria_def.h" +#include <my_getopt.h> +extern void translog_example_table_init(); +static const char *load_default_groups[]= { "maria_dump_log",0 }; +static void get_options(int *argc,char * * *argv); +#ifndef DBUG_OFF +#if defined(__WIN__) +const char *default_dbug_option= "d:t:i:O,\\maria_dump_log.trace"; +#else +const char *default_dbug_option= "d:t:i:o,/tmp/maria_dump_log.trace"; +#endif +#endif +static ulonglong opt_offset; +static ulong opt_pages; +static const char *opt_file= NULL; +static File handler= -1; +static my_bool opt_unit= 0; +static struct my_option my_long_options[] = +{ +#ifdef IMPLTMENTED + {"body", 'b', + "Print chunk body dump", + (uchar **) &opt_body, (uchar **) &opt_body, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif +#ifndef DBUG_OFF + {"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"file", 'f', "Path to file which will be read", + (uchar**) &opt_file, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"help", '?', "Display this help and exit.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + { "offset", 'o', "Start reading log from this offset", + (uchar**) &opt_offset, (uchar**) &opt_offset, + 0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 }, + { "pages", 'n', "Number of pages to read", + (uchar**) &opt_pages, (uchar**) &opt_pages, 0, + GET_ULONG, REQUIRED_ARG, (long) ~(ulong) 0, + (long) 1, (long) ~(ulong) 0, (long) 0, + (long) 1, 0}, + {"unit-test", 'U', + "Use unit test record table (for logs created by unittests", + (uchar **) &opt_unit, (uchar **) &opt_unit, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Print version and exit.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + + +static void print_version(void) +{ + VOID(printf("%s Ver 1.0 for %s on %s\n", + my_progname_short, SYSTEM_TYPE, MACHINE_TYPE)); + NETWARE_SET_SCREEN_MODE(1); +} + + +static void usage(void) +{ + print_version(); + puts("Copyright (C) 2008 MySQL AB"); + puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); + puts("and you are welcome to modify and redistribute it under the GPL license\n"); + + puts("Dump content of maria log pages."); + VOID(printf("\nUsage: %s -f file OPTIONS\n", my_progname_short)); + my_print_help(my_long_options); + print_defaults("my", load_default_groups); + my_print_variables(my_long_options); +} + + +static my_bool +get_one_option(int optid __attribute__((unused)), + const struct my_option *opt __attribute__((unused)), + char *argument __attribute__((unused))) +{ + switch (optid) { + case '?': + usage(); + exit(0); + case 'V': + print_version(); + exit(0); +#ifndef DBUG_OFF + case '#': + DBUG_SET_INITIAL(argument ? argument : default_dbug_option); + break; +#endif + } + return 0; +} + + +static void get_options(int *argc,char ***argv) +{ + int ho_error; + + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + exit(ho_error); + + if (opt_file == NULL) + { + usage(); + exit(1); + } +} + + +/** + @brief maria_dump_log main function. +*/ + +int main(int argc, char **argv) +{ + char **default_argv; + uchar buffer[TRANSLOG_PAGE_SIZE]; + MY_INIT(argv[0]); + + load_defaults("my", load_default_groups, &argc, &argv); + default_argv= argv; + get_options(&argc, &argv); + + if (opt_unit) + translog_example_table_init(); + else + translog_table_init(); + translog_fill_overhead_table(); + + maria_data_root= (char *)"."; + + if ((handler= my_open(opt_file, O_RDONLY, MYF(MY_WME))) < 0) + { + fprintf(stderr, "Can't open file: '%s' errno: %d\n", + opt_file, my_errno); + goto err; + } + if (my_seek(handler, opt_offset, SEEK_SET, MYF(MY_WME)) != + opt_offset) + { + fprintf(stderr, "Can't set position %lld file: '%s' errno: %d\n", + opt_offset, opt_file, my_errno); + goto err; + } + for (; + opt_pages; + opt_offset+= TRANSLOG_PAGE_SIZE, opt_pages--) + { + if (my_pread(handler, buffer, TRANSLOG_PAGE_SIZE, opt_offset, + MYF(MY_NABP))) + { + if (my_errno == HA_ERR_FILE_TOO_SHORT) + goto end; + fprintf(stderr, "Can't read page at position %lld file: '%s' " + "errno: %d\n", opt_offset, opt_file, my_errno); + goto err; + } + printf("Page by offset %llu (0x%llx)\n", opt_offset, opt_offset); + dump_page(buffer, handler); + } + +end: + my_close(handler, MYF(0)); + free_defaults(default_argv); + exit(0); + return 0; /* No compiler warning */ + +err: + my_close(handler, MYF(0)); + fprintf(stderr, "%s: FAILED\n", my_progname_short); + free_defaults(default_argv); + exit(1); +} diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c index 167d0af3078..3e0ea3d571c 100644 --- a/storage/maria/maria_pack.c +++ b/storage/maria/maria_pack.c @@ -736,7 +736,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table) VOID(my_delete(new_name,MYF(MY_WME))); } else - error=my_redel(org_name,new_name,MYF(MY_WME | MY_COPYTIME)); + error=my_redel(org_name, new_name, 0, MYF(MY_WME | MY_COPYTIME)); } if (! error) error=save_state(isam_file,mrg,new_length,glob_crc); diff --git a/storage/maria/plug.in b/storage/maria/plug.in index 686c8361a87..bdf1ca7a5bf 100644 --- a/storage/maria/plug.in +++ b/storage/maria/plug.in @@ -1,10 +1,9 @@ MYSQL_STORAGE_ENGINE(maria,, [Maria Storage Engine], [Crash-safe tables with MyISAM heritage], [default,max,max-no-ndb]) MYSQL_PLUGIN_DIRECTORY(maria, [storage/maria]) -MYSQL_PLUGIN_STATIC(maria, [libmaria.a]) +MYSQL_PLUGIN_STATIC(maria, [libmaria_s.la], [libmaria_embedded.la]) # Maria will probably go first into max builds, not all builds, # so we don't declare it mandatory. -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(maria, [ha_maria.cc]) MYSQL_PLUGIN_ACTIONS(maria, [ # AC_CONFIG_FILES(storage/maria/unittest/Makefile) diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c index a87b2f0e55b..05330baed76 100644 --- a/storage/maria/trnman.c +++ b/storage/maria/trnman.c @@ -145,6 +145,7 @@ static uchar *trn_get_hash_key(const uchar *trn, size_t *len, int trnman_init(TrID initial_trid) { DBUG_ENTER("trnman_init"); + DBUG_PRINT("enter", ("initial_trid: %lu", (ulong) initial_trid)); short_trid_to_active_trn= (TRN **)my_malloc(SHORT_TRID_MAX*sizeof(TRN*), MYF(MY_WME|MY_ZEROFILL)); diff --git a/storage/myisam/Makefile.am b/storage/myisam/Makefile.am index ea942672856..8f3d51c4886 100644 --- a/storage/myisam/Makefile.am +++ b/storage/myisam/Makefile.am @@ -31,6 +31,10 @@ EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt plug.in pkgdata_DATA = pkglib_LIBRARIES = libmyisam.a +noinst_LTLIBRARIES = libmyisam.la libmyisam_s.la \ + @plugin_myisam_embedded_static_target@ +EXTRA_LTLIBRARIES = libmyisam_embedded.la + bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump myisamchk_DEPENDENCIES= $(LIBRARIES) myisamchk_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \ @@ -83,7 +87,8 @@ sp_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ + +libmyisam_la_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ mi_rnext.c mi_rnext_same.c \ mi_search.c mi_page.c mi_key.c mi_locking.c \ mi_rrnd.c mi_scan.c mi_cache.c \ @@ -98,8 +103,19 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ mi_keycache.c mi_preload.c \ ft_parser.c ft_stopwords.c ft_static.c \ ft_update.c ft_boolean_search.c ft_nlq_search.c \ - sort.c ha_myisam.cc ft_myisam.c \ + sort.c ft_myisam.c \ rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c +libmyisam_s_la_SOURCES = ha_myisam.cc +libmyisam_s_la_CXXFLAGS = $(AM_CXXFLAGS) +libmyisam_s_la_LIBADD = libmyisam.la +libmyisam_embedded_la_SOURCES = ha_myisam.cc +libmyisam_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@ +libmyisam_embedded_la_LIBADD = libmyisam.la + +libmyisam_a_SOURCES= +libmyisam.a: libmyisam.la + $(CP) .libs/libmyisam.a $@ + CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all rt_test.MY? sp_test.MY? # Move to automake rules ? diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 5f807be2374..1a9c80316f4 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -33,7 +33,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE; /* bits in myisam_recover_options */ const char *myisam_recover_names[] = -{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS}; +{ "DEFAULT", "BACKUP", "FORCE", "QUICK", "BACKUP_ALL", NullS}; TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"", myisam_recover_names, NULL}; @@ -799,10 +799,13 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) { if (!file) return HA_ADMIN_INTERNAL_ERROR; int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MYISAM_SHARE* share = file->s; const char *old_proc_info=thd->proc_info; + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + thd_proc_info(thd, "Checking table"); myisamchk_init(¶m); param.thd = thd; @@ -891,9 +894,12 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) { int error=0; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MYISAM_SHARE* share = file->s; + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + myisamchk_init(¶m); param.thd = thd; param.op_name= "analyze"; @@ -1021,7 +1027,9 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) err: { - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd= thd; param.op_name= "backup"; @@ -1037,10 +1045,10 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) { int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); ha_rows start_records; - if (!file) return HA_ADMIN_INTERNAL_ERROR; + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd = thd; @@ -1049,6 +1057,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM | (check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT)); param.sort_buffer_length= thd->variables.myisam_sort_buff_size; + param.backup_time= check_opt->start_time; start_records=file->state->records; while ((error=repair(thd,param,0)) && param.retry_repair) { @@ -1088,8 +1097,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) { int error; - if (!file) return HA_ADMIN_INTERNAL_ERROR; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd = thd; @@ -1283,7 +1293,10 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) if (error != HA_ADMIN_OK) { /* Send error to user */ - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + myisamchk_init(¶m); param.thd= thd; param.op_name= "assign_to_keycache"; @@ -1347,7 +1360,9 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) err: { - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd= thd; param.op_name= "preload_keys"; @@ -1457,8 +1472,12 @@ int ha_myisam::enable_indexes(uint mode) else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) { THD *thd=current_thd; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); const char *save_proc_info=thd->proc_info; + + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + thd_proc_info(thd, "Creating index"); myisamchk_init(¶m); param.op_name= "recreating_index"; @@ -1643,8 +1662,18 @@ bool ha_myisam::check_and_repair(THD *thd) if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt)) { sql_print_warning("Recovering table: '%s'",table->s->path.str); + if (myisam_recover_options & (HA_RECOVER_FULL_BACKUP | HA_RECOVER_BACKUP)) + { + char buff[MY_BACKUP_NAME_EXTRA_LENGTH+1]; + my_create_backup_name(buff, "", check_opt.start_time); + sql_print_information("Making backup of data with extension '%s'", buff); + } + if (myisam_recover_options & HA_RECOVER_FULL_BACKUP) + mi_make_backup_of_index(file, check_opt.start_time, + MYF(MY_WME | ME_JUST_WARNING)); check_opt.flags= - ((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) | + (((myisam_recover_options & + (HA_RECOVER_BACKUP | HA_RECOVER_FULL_BACKUP)) ? T_BACKUP_DATA : 0) | (marked_crashed ? 0 : T_QUICK) | (myisam_recover_options & HA_RECOVER_FORCE ? 0 : T_SAFE_REPAIR) | T_AUTO_REPAIR); diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index b7d15a6e8b7..0e53bc58c81 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -29,6 +29,7 @@ #define HA_RECOVER_BACKUP 2 /* Make a backupfile on recover */ #define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */ #define HA_RECOVER_QUICK 8 /* Don't check rows in data file */ +#define HA_RECOVER_FULL_BACKUP 16 /* Make a copy of index file too */ extern ulong myisam_sort_buffer_size; extern TYPELIB myisam_recover_typelib; diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 7096c03cf7d..68565777b43 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1337,7 +1337,7 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend) if (splits != info->s->state.split) { mi_check_print_warning(param, - "Found %10s key parts. Should be: %s", + "Found %10s parts. Should be: %s", llstr(splits,llbuff), llstr(info->s->state.split,llbuff2)); } @@ -1733,7 +1733,9 @@ err: my_close(new_file,MYF(0)); info->dfile=new_file= -1; if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, share->base.raid_chunks, + DATA_TMP_EXT, + param->backup_time, + share->base.raid_chunks, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || mi_open_datafile(info,share,name,-1)) @@ -1991,8 +1993,8 @@ int mi_sort_index(HA_CHECK *param, register MI_INFO *info, char * name) VOID(my_close(share->kfile,MYF(MY_WME))); share->kfile = -1; VOID(my_close(new_file,MYF(MY_WME))); - if (change_to_newfile(share->index_file_name,MI_NAME_IEXT,INDEX_TMP_EXT,0, - MYF(0)) || + if (change_to_newfile(share->index_file_name,MI_NAME_IEXT,INDEX_TMP_EXT, + 0, 0, MYF(0)) || mi_open_keyfile(share)) goto err2; info->lock_type= F_UNLCK; /* Force mi_readinfo to lock */ @@ -2121,6 +2123,7 @@ err: int change_to_newfile(const char * filename, const char * old_ext, const char * new_ext, + time_t backup_time, uint raid_chunks __attribute__((unused)), myf MyFlags) { @@ -2136,7 +2139,7 @@ int change_to_newfile(const char * filename, const char * old_ext, (void) fn_format(old_filename,filename,"",old_ext,2+4+32); return my_redel(old_filename, fn_format(new_filename,old_filename,"",new_ext,2+4), - MYF(MY_WME | MY_LINK_WARNING | MyFlags)); + backup_time, MYF(MY_WME | MY_LINK_WARNING | MyFlags)); } /* change_to_newfile */ @@ -2544,7 +2547,8 @@ err: my_close(new_file,MYF(0)); info->dfile=new_file= -1; if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, share->base.raid_chunks, + DATA_TMP_EXT, param->backup_time, + share->base.raid_chunks, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || mi_open_datafile(info,share,name,-1)) @@ -3081,7 +3085,8 @@ err: my_close(new_file,MYF(0)); info->dfile=new_file= -1; if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, share->base.raid_chunks, + DATA_TMP_EXT, param->backup_time, + share->base.raid_chunks, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || mi_open_datafile(info,share,name,-1)) @@ -4743,3 +4748,10 @@ set_data_file_type(MI_SORT_INFO *sort_info, MYISAM_SHARE *share) share->delete_record=tmp.delete_record; } } + +int mi_make_backup_of_index(MI_INFO *info, time_t backup_time, myf flags) +{ + char backup_name[FN_REFLEN + MY_BACKUP_NAME_EXTRA_LENGTH]; + my_create_backup_name(backup_name, info->s->index_file_name, backup_time); + return my_copy(info->s->index_file_name, backup_name, flags); +} diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c index 659abdce131..0e839cd8379 100644 --- a/storage/myisam/mi_dbug.c +++ b/storage/myisam/mi_dbug.c @@ -131,6 +131,7 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg, key=end; break; } +#endif case HA_KEYTYPE_BIT: { uint i; @@ -140,8 +141,6 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg, key= end; break; } - -#endif case HA_KEYTYPE_VARTEXT1: /* VARCHAR and TEXT */ case HA_KEYTYPE_VARTEXT2: /* VARCHAR and TEXT */ case HA_KEYTYPE_VARBINARY1: /* VARBINARY and BLOB */ diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index 3b14e5eb98e..4c5a65f900f 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -390,6 +390,11 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) share->is_log_table= TRUE; pthread_mutex_unlock(&share->intern_lock); break; + case HA_EXTRA_DETACH_CHILD: /* When used with MERGE tables */ + info->open_flag&= ~HA_OPEN_MERGE_TABLE; + info->lock.priority&= ~THR_LOCK_MERGE_PRIV; + break; + case HA_EXTRA_KEY_CACHE: case HA_EXTRA_NO_KEY_CACHE: default: diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index 40a04293731..9de043b8867 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -22,6 +22,8 @@ #include "ftdefs.h" +static void mi_update_status_with_lock(MI_INFO *info); + /* lock table by F_UNLCK, F_RDLCK or F_WRLCK */ int mi_lock_database(MI_INFO *info, int lock_type) @@ -62,7 +64,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) else { count= --share->w_locks; - mi_update_status(info); + mi_update_status_with_lock(info); } --share->tot_locks; if (info->lock_type == F_WRLCK && !share->w_locks && @@ -244,7 +246,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) a crash on windows if the table is renamed and later on referenced by the merge table. */ - if( info->owned_by_merge && (info->s)->kfile < 0 ) + if ((info->open_flag & HA_OPEN_MERGE_TABLE) && (info->s)->kfile < 0) { error = HA_ERR_NO_SUCH_TABLE; } @@ -273,9 +275,11 @@ void mi_get_status(void* param, my_bool concurrent_insert) { MI_INFO *info=(MI_INFO*) param; DBUG_ENTER("mi_get_status"); - DBUG_PRINT("info",("key_file: %ld data_file: %ld concurrent_insert: %d", - (long) info->s->state.state.key_file_length, - (long) info->s->state.state.data_file_length, + DBUG_PRINT("info",("name: %s key_file: %lu data_file: %lu rows: %lu concurrent_insert: %d", + info->s->index_file_name, + (ulong) info->s->state.state.key_file_length, + (ulong) info->s->state.state.data_file_length, + (ulong) info->s->state.state.records, concurrent_insert)); #ifndef DBUG_OFF if (info->state->key_file_length > info->s->state.state.key_file_length || @@ -306,9 +310,11 @@ void mi_update_status(void* param) if (info->state == &info->save_state) { #ifndef DBUG_OFF - DBUG_PRINT("info",("updating status: key_file: %ld data_file: %ld", - (long) info->state->key_file_length, - (long) info->state->data_file_length)); + DBUG_PRINT("info", + ("updating status: key_file: %lu data_file: %lu rows: %lu", + (ulong) info->state->key_file_length, + (ulong) info->state->data_file_length, + (ulong) info->state->records)); if (info->state->key_file_length < info->s->state.state.key_file_length || info->state->data_file_length < info->s->state.state.data_file_length) DBUG_PRINT("warning",("old info: key_file: %ld data_file: %ld", @@ -342,6 +348,24 @@ void mi_update_status(void* param) DBUG_VOID_RETURN; } +/* + Same as mi_update_status() but take a lock in the table lock, to protect + against someone calling mi_get_status() from thr_lock() at the same time. +*/ + +static void mi_update_status_with_lock(MI_INFO *info) +{ + my_bool locked= 0; + if (info->state == &info->save_state) + { + locked= 1; + pthread_mutex_lock(&info->s->lock.mutex); + } + mi_update_status(info); + if (locked) + pthread_mutex_unlock(&info->s->lock.mutex); +} + void mi_restore_status(void *param) { @@ -407,6 +431,32 @@ my_bool mi_check_status(void *param) } +/** + Fix status for thr_lock_merge() + + @param org_table + @param new_table that should point on org_lock. new_table is 0 + in case this is the first occurence of the table in the lock + structure. +*/ + +void mi_fix_status(MI_INFO *org_table, MI_INFO *new_table) +{ + DBUG_ENTER("mi_fix_status"); + if (!new_table) + { + /* First in group. Set state as in mi_get_status() */ + org_table->state= &org_table->save_state; + } + else + { + /* Set new_table to use state from org_table (first lock of this table) */ + new_table->state= org_table->state; + } + DBUG_VOID_RETURN; +} + + /**************************************************************************** ** functions to read / write the state ****************************************************************************/ diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index e4240dec90c..9fc82846e91 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -119,7 +119,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) dflt_key_cache); DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open", - if (strstr(name, "/t1")) + if (strstr(name, "/crashed")) { my_errno= HA_ERR_CRASHED; goto err; @@ -556,6 +556,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) share->lock.update_status=mi_update_status; share->lock.restore_status= mi_restore_status; share->lock.check_status=mi_check_status; + share->lock.fix_status= (void (*)(void *, void *)) mi_fix_status; } } #endif @@ -606,6 +607,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) info.s=share; info.lastpos= HA_OFFSET_ERROR; info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND); + info.open_flag= open_flags; info.opt_flag=READ_CHECK_USED; info.this_unique= (ulong) info.dfile; /* Uniq number in process */ if (share->data_file_type == COMPRESSED_RECORD) diff --git a/storage/myisam/mi_range.c b/storage/myisam/mi_range.c index aabbe1277c4..60d51637591 100644 --- a/storage/myisam/mi_range.c +++ b/storage/myisam/mi_range.c @@ -193,12 +193,11 @@ static double _mi_search_pos(register MI_INFO *info, register my_off_t pos) { int flag; - uint nod_flag,keynr,max_keynr; + uint nod_flag,keynr,UNINIT_VAR(max_keynr); my_bool after_key; uchar *keypos,*buff; double offset; DBUG_ENTER("_mi_search_pos"); - LINT_INIT(max_keynr); if (pos == HA_OFFSET_ERROR) DBUG_RETURN(0.5); diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c index 68ecd15a206..75a4835a5a7 100644 --- a/storage/myisam/mi_search.c +++ b/storage/myisam/mi_search.c @@ -296,9 +296,9 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, flag is the value returned by ha_key_cmp and as treated as final */ int flag=0, my_flag=-1; - uint nod_flag, length, len, matched, cmplen, kseg_len; - uint prefix_len,suffix_len; - int key_len_skip, seg_len_pack, key_len_left; + uint nod_flag, UNINIT_VAR(length), len, matched, cmplen, kseg_len; + uint UNINIT_VAR(prefix_len), suffix_len; + int key_len_skip, UNINIT_VAR(seg_len_pack), key_len_left; uchar *end, *kseg, *vseg; uchar *sort_order=keyinfo->seg->charset->sort_order; uchar tt_buff[HA_MAX_KEY_BUFF+2], *t_buff=tt_buff+2; @@ -308,10 +308,6 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, uint length_pack; DBUG_ENTER("_mi_prefix_search"); - LINT_INIT(length); - LINT_INIT(prefix_len); - LINT_INIT(seg_len_pack); - t_buff[0]=0; /* Avoid bugs */ end= page+mi_getint(page); nod_flag=mi_test_if_nod(page); diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 9ecbe76369f..b2344b3be7f 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1032,7 +1032,7 @@ static int myisamchk(HA_CHECK *param, char * filename) { /* Change temp file to org file */ VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */ error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT, - raid_chunks, + 0, raid_chunks, MYF(0)); if (mi_open_datafile(info,info->s, NULL, -1)) error=1; @@ -1164,12 +1164,9 @@ end2: { if (param->out_flag & O_NEW_DATA) error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT, - raid_chunks, + param->backup_time, raid_chunks, ((param->testflag & T_BACKUP_DATA) ? MYF(MY_REDEL_MAKE_BACKUP) : MYF(0))); - if (param->out_flag & O_NEW_INDEX) - error|=change_to_newfile(filename,MI_NAME_IEXT,INDEX_TMP_EXT,0, - MYF(0)); } VOID(fflush(stdout)); VOID(fflush(stderr)); if (param->error_printed) @@ -1241,7 +1238,8 @@ static void descript(HA_CHECK *param, register MI_INFO *info, char * name) } pos=buff; if (share->state.changed & STATE_CRASHED) - strmov(buff,"crashed"); + strmov(buff, share->state.changed & STATE_CRASHED_ON_REPAIR ? + "crashed on repair" : "crashed"); else { if (share->state.open_count) diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index 3262808803c..e03f88b1a1f 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -274,7 +274,9 @@ struct st_myisam_info */ ulong packed_length, blob_length; /* Length of found, packed record */ int dfile; /* The datafile */ + uint open_flag; /* Parameters for open */ uint opt_flag; /* Optim. for space/speed */ + uint once_flags; /* For MYISAMMRG */ uint update; /* If file changed since open */ int lastinx; /* Last used index */ uint lastkey_length; /* Length of key in lastkey */ @@ -300,10 +302,6 @@ struct st_myisam_info my_bool page_changed; /* If info->buff has to be reread for rnext */ my_bool buff_used; - my_bool once_flags; /* For MYISAMMRG */ -#ifdef __WIN__ - my_bool owned_by_merge; /* This MyISAM table is part of a merge union */ -#endif #ifdef THREAD THR_LOCK_DATA lock; #endif @@ -712,6 +710,7 @@ void mi_update_status(void *param); void mi_restore_status(void *param); void mi_copy_status(void *to, void *from); my_bool mi_check_status(void *param); +void mi_fix_status(MI_INFO *org_table, MI_INFO *new_table); void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); extern MI_INFO *test_if_reopen(char *filename); diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index f2b28a008fc..ba3ff3cdf0d 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -720,7 +720,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table) VOID(my_delete(new_name,MYF(MY_WME))); } else - error=my_redel(org_name,new_name,MYF(MY_WME | MY_COPYTIME)); + error=my_redel(org_name, new_name, 0, MYF(MY_WME | MY_COPYTIME)); } if (! error) error=save_state(isam_file,mrg,new_length,glob_crc); diff --git a/storage/myisam/plug.in b/storage/myisam/plug.in index e92b5e56d7f..95b29336493 100644 --- a/storage/myisam/plug.in +++ b/storage/myisam/plug.in @@ -1,7 +1,6 @@ dnl MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine], dnl [Traditional non-transactional MySQL tables]) dnl MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam]) -dnl MYSQL_PLUGIN_STATIC(myisam, [libmyisam.a]) +dnl MYSQL_PLUGIN_STATIC(myisam, [libmyisam_s.la], [libmyisam_embedded.la]) dnl MYSQL_PLUGIN_MANDATORY(myisam) dnl Default -dnl MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisam, [ha_myisam.cc]) diff --git a/storage/myisam/rt_index.c b/storage/myisam/rt_index.c index 575cc32eb56..6a825bab1fa 100644 --- a/storage/myisam/rt_index.c +++ b/storage/myisam/rt_index.c @@ -481,17 +481,13 @@ static uchar *rtree_pick_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint key_length, uchar *page_buf, uint nod_flag) { double increase; - double best_incr; + double UNINIT_VAR(best_incr); double area; - double best_area; + double UNINIT_VAR(best_area); uchar *best_key= NULL; uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); uchar *last = rt_PAGE_END(page_buf); - LINT_INIT(best_area); - LINT_INIT(best_key); - LINT_INIT(best_incr); - for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) { /* The following is safe as -1.0 is an exact number */ diff --git a/storage/myisam/rt_split.c b/storage/myisam/rt_split.c index 03d22de68fa..0b7cc43e062 100644 --- a/storage/myisam/rt_split.c +++ b/storage/myisam/rt_split.c @@ -178,18 +178,13 @@ static int split_rtree_node(SplitStruct *node, int n_entries, double **d_buffer, int n_dim) { SplitStruct *cur; - SplitStruct *a; - SplitStruct *b; + SplitStruct *UNINIT_VAR(a), *UNINIT_VAR(b); double *g1 = reserve_coords(d_buffer, n_dim); double *g2 = reserve_coords(d_buffer, n_dim); - SplitStruct *next; - int next_node; + SplitStruct *UNINIT_VAR(next); + int UNINIT_VAR(next_node); int i; SplitStruct *end = node + n_entries; - LINT_INIT(a); - LINT_INIT(b); - LINT_INIT(next); - LINT_INIT(next_node); if (all_size < min_size * 2) { diff --git a/storage/myisammrg/Makefile.am b/storage/myisammrg/Makefile.am index 1ca51bc9d03..66fd2402646 100644 --- a/storage/myisammrg/Makefile.am +++ b/storage/myisammrg/Makefile.am @@ -27,16 +27,26 @@ LDADD = DEFS = @DEFS@ pkglib_LIBRARIES = libmyisammrg.a +noinst_LTLIBRARIES = libmyisammrg.la libmyisammrg_s.la \ + @plugin_myisammrg_embedded_static_target@ +EXTRA_LTLIBRARIES = libmyisammrg_embedded.la noinst_HEADERS = myrg_def.h ha_myisammrg.h -noinst_LIBRARIES = libmyisammrg.a -libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \ +libmyisammrg_la_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \ myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \ myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \ myrg_rprev.c myrg_queue.c myrg_write.c myrg_range.c \ - ha_myisammrg.cc \ myrg_rnext_same.c myrg_records.c +libmyisammrg_s_la_SOURCES = ha_myisammrg.cc +libmyisammrg_s_la_CXXFLAGS = $(AM_CXXFLAGS) +libmyisammrg_s_la_LIBADD = libmyisammrg.la +libmyisammrg_embedded_la_SOURCES = ha_myisammrg.cc +libmyisammrg_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@ +libmyisammrg_embedded_la_LIBADD = libmyisammrg.la +libmyisammrg_a_SOURCES= +libmyisammrg.a: libmyisammrg.la + $(CP) .libs/libmyisammrg.a $@ EXTRA_DIST = CMakeLists.txt plug.in diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 30be1d34e2a..99513e2267f 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -86,8 +86,6 @@ On parent open the storage engine structures are allocated and initialized. They stay with the open table until its final close. - - */ #ifdef USE_PRAGMA_IMPLEMENTATION @@ -1070,6 +1068,8 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd, open_table != file->end_table ; open_table++) { + open_table->table->lock.priority|= THR_LOCK_MERGE_PRIV; + *(to++)= &open_table->table->lock; if (lock_type != TL_IGNORE && open_table->table->lock.type == TL_UNLOCK) open_table->table->lock.type=lock_type; diff --git a/storage/myisammrg/myrg_locking.c b/storage/myisammrg/myrg_locking.c index 4f1e3f844a1..a414cee7bb8 100644 --- a/storage/myisammrg/myrg_locking.c +++ b/storage/myisammrg/myrg_locking.c @@ -27,15 +27,8 @@ int myrg_lock_database(MYRG_INFO *info, int lock_type) error=0; for (file=info->open_tables ; file != info->end_table ; file++) { -#ifdef __WIN__ - /* - Make sure this table is marked as owned by a merge table. - The semaphore is never released as long as table remains - in memory. This should be refactored into a more generic - approach (observer pattern) - */ - (file->table)->owned_by_merge = TRUE; -#endif + DBUG_ASSERT(file->table->open_flag & HA_OPEN_MERGE_TABLE); + if ((new_error=mi_lock_database(file->table,lock_type))) { error=new_error; diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index 17c9b4ba4d1..ba452854808 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -27,8 +27,9 @@ if handle_locking is 0 then exit with error if some table is locked if handle_locking is 1 then wait if table is locked - NOTE: This function is not used in the MySQL server. It is for - MERGE use independent from MySQL. Currently there is some code + NOTE: This function is only used in the MySQL server when a + table is cloned. It is also used for usage of MERGE + independent from MySQL. Currently there is some code duplication between myrg_open() and myrg_parent_open() + myrg_attach_children(). Please duplicate changes in these functions or make common sub-functions. @@ -93,7 +94,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) } else fn_format(buff, buff, "", "", 0); - if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0)))) + if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0) | + HA_OPEN_MERGE_TABLE))) { if (handle_locking & HA_OPEN_FOR_REPAIR) { @@ -430,6 +432,8 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, m_info->open_tables[child_nr].table= myisam; m_info->open_tables[child_nr].file_offset= (my_off_t) file_offset; file_offset+= myisam->state->data_file_length; + /* Mark as MERGE table */ + myisam->open_flag|= HA_OPEN_MERGE_TABLE; /* Check table definition match. */ if (m_info->reclength != myisam->s->base.reclength) diff --git a/storage/myisammrg/plug.in b/storage/myisammrg/plug.in index 1f94e07d881..a2654373fba 100644 --- a/storage/myisammrg/plug.in +++ b/storage/myisammrg/plug.in @@ -1,6 +1,5 @@ MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine], [Merge multiple MySQL tables into one]) MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg]) -MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg.a]) +MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg_s.la], [libmyisammrg_embedded.la]) MYSQL_PLUGIN_MANDATORY(myisammrg) -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisammrg, [ha_myisammrg.cc]) diff --git a/storage/pbxt/ChangeLog b/storage/pbxt/ChangeLog index b6023d26139..f0f9864d0d5 100644 --- a/storage/pbxt/ChangeLog +++ b/storage/pbxt/ChangeLog @@ -1,7 +1,49 @@ PBXT Release Notes ================== -+------- 1.0.11 Pre-GA - 2010-05-11 +------- 1.0.11-7 Pre-GA - 2010-09-09 + +RN336: Compiled and tested with MySQL 5.1.50. + +RN335: Fixed bug #523994: Deleting all records does not update table statistics. + +RN334: Made a change to reduce the time that only temporary tables exist during the ALTER TABLE and REPAIR TABLE statements. This increases the chance of recovery if a crash occurs during these operations. + +RN333: Log name of table when PBXT recovers an index on startup. If an error occurs during index recovery, the index is set to "repair pending". + +RN332: Fixed an inifinite loop when a record in a row is corrupt. Added logging and set the table to "repair pending" in this case. + +RN331: Fixed bug #626890: Crash on truncate table operation. + +RN330: Added additional checks for corruption of the index free list. + +------- 1.0.11-6 Pre-GA - 2010-07-08 + +RN329: Fixed bug #601245: make fails. PBXT did not compile if the partition engine was disabled in the MySQL build. + +------- 1.0.11-5 Pre-GA - 2010-06-18 + +RN328: Fixed bug #595478: Compile fails (1.0.11-4). + +------- 1.0.11-4 Pre-GA - 2010-06-15 + +RN327: Fixed a bug that caused a crash during delete on the index. The crash occurred due to memory overwrite when a long key is promoted after a shorter key is deleted, and the difference causes a node size overflow. + +------- 1.0.11-3 Pre-GA - 2010-06-11 + +RN326: Fixed bug #587740: pbxt-1.0.11-pre2-ga first time create partition table error. This was not a new bug. The problem was the PBXT system table's .frm files are corrupted when the first PBXT table created is a partition table. + +RN325: Fixed the "to-sweep" column output in xtstat. + +------- 1.0.11-2 Pre-GA - 2010-05-26 + +RN324: Fixed bug #584070:pbxt-1.0.11-pre-ga does not work with mysql 5.1.47. This bug fix removes a hack which was done to avoid running into the LOCK_plugin lock. + +------- 1.0.11-1 Pre-GA - 2010-05-19 + +RN323: Detect corruption of a key length in an index page. This bug fix avoids a possible crash due to index page corruption. + +------- 1.0.11 Pre-GA - 2010-05-11 RN322: Creating a table the references a non-existing table can now only be done if you set: foreign_key_checks = 0. Also fixed a failure when creating tables with recursive foreign key declarations. diff --git a/storage/pbxt/plug.in b/storage/pbxt/plug.in index 02c5d8adcbe..c0dc06d9702 100644 --- a/storage/pbxt/plug.in +++ b/storage/pbxt/plug.in @@ -1,8 +1,7 @@ MYSQL_STORAGE_ENGINE(pbxt,no, [PBXT Storage Engine], [MVCC-based transactional engine], [max,max-no-ndb]) MYSQL_PLUGIN_DIRECTORY(pbxt, [storage/pbxt]) -MYSQL_PLUGIN_STATIC(pbxt, [src/libpbxt.a]) +MYSQL_PLUGIN_STATIC(pbxt, [src/libpbxt_s.la], [src/libpbxt_s_embedded.la]) MYSQL_PLUGIN_ACTIONS(pbxt, [ # AC_CONFIG_FILES(storage/pbxt/src/Makefile) ]) -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(pbxt, [[src/ha_pbxt.cc],[src/myxt_xt.cc],[src/discover_xt.cc]]) diff --git a/storage/pbxt/src/Makefile.am b/storage/pbxt/src/Makefile.am index fc4c4ef8f1e..4c5467d24d0 100644 --- a/storage/pbxt/src/Makefile.am +++ b/storage/pbxt/src/Makefile.am @@ -26,25 +26,31 @@ noinst_HEADERS = bsearch_xt.h cache_xt.h ccutils_xt.h database_xt.h \ pbms.h xt_config.h xt_defs.h xt_errno.h locklist_xt.h EXTRA_LTLIBRARIES = libpbxt.la -libpbxt_la_SOURCES = bsearch_xt.cc cache_xt.cc ccutils_xt.cc database_xt.cc \ +non_mysql_internal_sources = bsearch_xt.cc cache_xt.cc ccutils_xt.cc database_xt.cc \ datadic_xt.cc datalog_xt.cc filesys_xt.cc hashtab_xt.cc \ - ha_pbxt.cc heap_xt.cc index_xt.cc linklist_xt.cc \ - memory_xt.cc myxt_xt.cc pthread_xt.cc restart_xt.cc \ + heap_xt.cc index_xt.cc linklist_xt.cc \ + memory_xt.cc pthread_xt.cc restart_xt.cc \ sortedlist_xt.cc strutil_xt.cc \ tabcache_xt.cc table_xt.cc trace_xt.cc thread_xt.cc \ - systab_xt.cc ha_xtsys.cc discover_xt.cc backup_xt.cc \ + systab_xt.cc ha_xtsys.cc backup_xt.cc \ util_xt.cc xaction_xt.cc xactlog_xt.cc lock_xt.cc locklist_xt.cc - -libpbxt_la_LDFLAGS = -module +mysql_internal_sources = ha_pbxt.cc myxt_xt.cc discover_xt.cc +libpbxt_la_SOURCES = $(non_mysql_internal_sources) $(mysql_internal_sources) # These are the warning Drizzle uses: # DRIZZLE_WARNINGS = -W -Wall -Wextra -pedantic -Wundef -Wredundant-decls -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -libpbxt_la_CXXFLAGS = $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN -libpbxt_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN -std=c99 +libpbxt_la_CXXFLAGS = -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN +libpbxt_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN -std=c99 +libpbxt_la_LDFLAGS = -module + +noinst_LTLIBRARIES = libpbxt_s.la libpbxt_s_embedded.la libpbxt_s_common.la -EXTRA_LIBRARIES = libpbxt.a -noinst_LIBRARIES = libpbxt.a -libpbxt_a_SOURCES = $(libpbxt_la_SOURCES) +libpbxt_s_common_la_SOURCES = $(non_mysql_internal_sources) +libpbxt_s_la_SOURCES = $(mysql_internal_sources) +libpbxt_s_la_LIBADD = libpbxt_s_common.la +libpbxt_s_embedded_la_SOURCES = $(mysql_internal_sources) +libpbxt_s_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@ +libpbxt_s_embedded_la_LIBADD = libpbxt_s_common.la EXTRA_DIST = pbms_enabled.cc win_inttypes.h diff --git a/storage/pbxt/src/cache_xt.cc b/storage/pbxt/src/cache_xt.cc index 85eea41dd79..24e42d9e984 100644 --- a/storage/pbxt/src/cache_xt.cc +++ b/storage/pbxt/src/cache_xt.cc @@ -668,6 +668,9 @@ xtPublic void xt_ind_init(XTThreadPtr self, size_t cache_size) block->cb_data = buffer; buffer += XT_INDEX_PAGE_SIZE; #endif +#ifdef CHECK_BLOCK_TRAILERS + XT_SET_DISK_4(block->cp_check, 0xDEADBEEF); +#endif ind_cac_globals.cg_free_list = block; block++; } @@ -684,6 +687,19 @@ xtPublic void xt_ind_init(XTThreadPtr self, size_t cache_size) cont_(a); } +#ifdef CHECK_BLOCK_TRAILERS +xtPublic void check_block_trailers() +{ + XTIndBlockPtr block; + + block = ind_cac_globals.cg_blocks; + for (u_int i=0; i<ind_cac_globals.cg_block_count; i++) { + ASSERT_NS(XT_GET_DISK_4(block->cp_check) == 0xDEADBEEF); + block++; + } +} +#endif + xtPublic void xt_ind_exit(XTThreadPtr self) { #ifdef XT_USE_MYSYS @@ -1283,7 +1299,7 @@ static XTIndBlockPtr ind_cac_fetch(XTOpenTablePtr ot, XTIndexPtr ind, xtIndexNod * Conditionally count the number of deleted entries in the index: * We do this before other threads can read the block. */ - if (ind->mi_lazy_delete && read_data) + if (ind && ind->mi_lazy_delete && read_data) xt_ind_count_deleted_items(ot->ot_table, ind, block); /* Add to the hash table: */ @@ -1358,6 +1374,9 @@ xtPublic xtBool xt_ind_write(XTOpenTablePtr ot, XTIndexPtr ind, xtIndexNodeID ad #ifdef XT_TRACK_INDEX_UPDATES ot->ot_ind_changed++; #endif +#ifdef CHECK_BLOCK_TRAILERS + check_block_trailers(); +#endif return OK; } diff --git a/storage/pbxt/src/cache_xt.h b/storage/pbxt/src/cache_xt.h index ca796ab1a74..63a5164e466 100644 --- a/storage/pbxt/src/cache_xt.h +++ b/storage/pbxt/src/cache_xt.h @@ -33,6 +33,7 @@ struct XTIdxReadBuffer; #ifdef DEBUG //#define XT_USE_CACHE_DEBUG_SIZES +//#define CHECK_BLOCK_TRAILERS #endif #ifdef XT_USE_CACHE_DEBUG_SIZES @@ -116,6 +117,9 @@ typedef struct XTIndBlock { #else xtWord1 cb_data[XT_INDEX_PAGE_SIZE]; #endif +#ifdef CHECK_BLOCK_TRAILERS + xtWord1 cp_check[4]; +#endif } XTIndBlockRec, *XTIndBlockPtr; typedef struct XTIndReference { @@ -177,6 +181,10 @@ xtBool xt_ind_copy_on_write(XTIndReferencePtr iref); XTIndHandlePtr xt_ind_get_handle(struct XTOpenTable *ot, XTIndexPtr ind, XTIndReferencePtr iref); void xt_ind_release_handle(XTIndHandlePtr handle, xtBool have_lock, XTThreadPtr thread); +#ifdef CHECK_BLOCK_TRAILERS +extern void check_block_trailers(); +#endif + #ifdef DEBUG //#define DEBUG_CHECK_IND_CACHE #endif diff --git a/storage/pbxt/src/database_xt.h b/storage/pbxt/src/database_xt.h index 1b1863d2045..7744aeeac31 100644 --- a/storage/pbxt/src/database_xt.h +++ b/storage/pbxt/src/database_xt.h @@ -117,6 +117,7 @@ typedef struct XTDatabase : public XTHeap { XTSortedListPtr db_table_by_id; XTSortedListPtr db_table_paths; /* A list of table paths used by this database. */ xtBool db_multi_path; + XTSortedListPtr db_error_list; /* A list of errors already reported. */ /* The open table pool: */ XTAllTablePoolsRec db_ot_pool; diff --git a/storage/pbxt/src/datadic_xt.cc b/storage/pbxt/src/datadic_xt.cc index 1a1ffeeb096..6a58d23d980 100644 --- a/storage/pbxt/src/datadic_xt.cc +++ b/storage/pbxt/src/datadic_xt.cc @@ -396,7 +396,7 @@ void XTToken::expectNumber(XTThreadPtr self) struct charset_info_st; class XTTokenizer { - struct charset_info_st *tkn_charset; + MX_CONST_CHARSET_INFO *tkn_charset; char *tkn_cstring; char *tkn_curr_pos; XTToken *tkn_current; @@ -1324,7 +1324,7 @@ void XTParseTable::parseDropIndex(XTThreadPtr self) class XTCreateTable : public XTParseTable { public: bool ct_convert; - struct charset_info_st *ct_charset; + MX_CONST_CHARSET_INFO *ct_charset; XTPathStrPtr ct_tab_path; u_int ct_contraint_no; XTDDTable *ct_curr_table; @@ -2039,11 +2039,6 @@ void XTDDTableRef::deleteAllRows(XTThreadPtr self) if (!(ot = xt_db_open_table_using_tab(tr_fkey->co_table->dt_table, self))) xt_throw(self); - /* {FREE-ROWS-BAD} */ - /* - row_count = ((xtInt8) ot->ot_table->tab_row_eof_id) - 1; - row_count -= (xtInt8) ot->ot_table->tab_row_fnum; - */ /* Check if there are any rows in the referencing table: */ if (!xt_tab_seq_init(ot)) goto failed; diff --git a/storage/pbxt/src/datalog_xt.cc b/storage/pbxt/src/datalog_xt.cc index ff58a122e10..3238f0cbd17 100644 --- a/storage/pbxt/src/datalog_xt.cc +++ b/storage/pbxt/src/datalog_xt.cc @@ -1249,7 +1249,7 @@ xtBool XTDataLogBuffer::dlb_write_thru_log(xtLogID XT_NDEBUG_UNUSED(log_id), xtL */ dlb_data_log->dlf_log_eof += size; #ifdef DEBUG - if ((ulonglong) (log_offset + size) > (ulonglong) dlb_max_write_offset) + if (log_offset + (xtLogOffset) size > (xtLogOffset) dlb_max_write_offset) dlb_max_write_offset = log_offset + size; #endif dlb_flush_required = TRUE; @@ -1291,7 +1291,7 @@ xtBool XTDataLogBuffer::dlb_append_log(xtLogID XT_NDEBUG_UNUSED(log_id), xtLogOf if (!xt_pwrite_file(dlb_data_log->dlf_log_file, log_offset, size, data, &thread->st_statistics.st_data, thread)) return FAILED; #ifdef DEBUG - if ((ulonglong) (log_offset + size) > (ulonglong) dlb_max_write_offset) + if (log_offset + (xtLogOffset) size > (xtLogOffset) dlb_max_write_offset) dlb_max_write_offset = log_offset + size; #endif dlb_flush_required = TRUE; @@ -1734,8 +1734,8 @@ static xtBool dl_collect_garbage(XTThreadPtr self, XTDatabaseHPtr db, XTDataLogF xtLogOffset src_log_offset; xtLogID curr_log_id; xtLogOffset curr_log_offset; - xtLogID dest_log_id= 0; - xtLogOffset dest_log_offset= 0; + xtLogID dest_log_id = 0; + xtLogOffset dest_log_offset = 0; off_t garbage_count = 0; memset(&cs, 0, sizeof(XTCompactorStateRec)); diff --git a/storage/pbxt/src/discover_xt.cc b/storage/pbxt/src/discover_xt.cc index 2a42c77ac69..7f7281d8c30 100644 --- a/storage/pbxt/src/discover_xt.cc +++ b/storage/pbxt/src/discover_xt.cc @@ -1622,7 +1622,11 @@ int xt_create_table_frm(handlerton *hton, THD* thd, const char *db, const char * COLUMN_FORMAT_TYPE_FIXED, #endif NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/, - NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/)) + NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/ +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID > 50200 + , NULL /*vcol_info*/, NULL /* create options */ +#endif + )) #endif goto error; @@ -1654,8 +1658,17 @@ int xt_create_table_frm(handlerton *hton, THD* thd, const char *db, const char * if (mysql_create_table_no_lock(thd, db, name, &create_info, &table_proto, &stmt->alter_info, 1, 0)) goto error; #else +#ifdef WITH_PARTITION_STORAGE_ENGINE + partition_info *part_info; + + part_info = thd->work_part_info; + thd->work_part_info = NULL; +#endif if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &mylex.alter_info, 1, 0)) goto error; +#ifdef WITH_PARTITION_STORAGE_ENGINE + thd->work_part_info = part_info; +#endif #endif noerror: diff --git a/storage/pbxt/src/ha_pbxt.cc b/storage/pbxt/src/ha_pbxt.cc index 5bf2069f656..ef0ae582c07 100644 --- a/storage/pbxt/src/ha_pbxt.cc +++ b/storage/pbxt/src/ha_pbxt.cc @@ -1232,6 +1232,11 @@ static int pbxt_init(void *p) THD *thd = NULL; #ifndef DRIZZLED +#if MYSQL_VERSION_ID < 50147 + /* A hack which is no longer required after 5.1.46 */ + extern myxt_mutex_t LOCK_plugin; +#endif + /* {MYSQL QUIRK} * I have to release this lock for PBXT recovery to * work, because it needs to open .frm files. @@ -1248,8 +1253,7 @@ static int pbxt_init(void *p) * Only real problem, 2 threads try to load the same * plugin at the same time. */ -#if MYSQL_VERSION_ID <= 50146 - extern myxt_mutex_t LOCK_plugin; +#if MYSQL_VERSION_ID < 50147 myxt_mutex_unlock(&LOCK_plugin); #endif #endif @@ -1285,9 +1289,11 @@ static int pbxt_init(void *p) if (thd) myxt_destroy_thread(thd, FALSE); -#if MYSQL_VERSION_ID <= 50146 && !defined(DRIZZLED) +#ifndef DRIZZLED +#if MYSQL_VERSION_ID < 50147 myxt_mutex_lock(&LOCK_plugin); #endif +#endif } #endif } @@ -1948,8 +1954,13 @@ xtPublic int ha_pbxt::reopen() * selectity of the indices, as soon as the number of rows * exceeds 200 (see [**]) */ +#ifdef XT_ROW_COUNT_CORRECTED + /* {CORRECTED-ROW-COUNT} */ + pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 - pb_share->sh_table->tab_row_fnum) < 150; +#else /* {FREE-ROWS-BAD} */ pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150; +#endif } /* I am not doing this anymore because it was only required @@ -2006,7 +2017,7 @@ static int pbxt_statistics_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) xt_ha_open_database_of_table(self, (XTPathStrPtr) NULL); } - err = myxt_statistics_fill_table(self, thd, tables, cond, system_charset_info); + err = myxt_statistics_fill_table(self, thd, tables, cond, (void*) system_charset_info); } catch_(a) { err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE); @@ -2296,6 +2307,36 @@ void ha_pbxt::internal_close(THD *thd, struct XTThread *self) */ if (!thd || thd_sql_command(thd) == SQLCOM_FLUSH) // FLUSH TABLES xt_sync_flush_table(self, ot); + else { + /* This change is a result of a problem mentioned by Arjen. + * REPAIR and ALTER lead to the following sequence: + * 1. tab -- copy --> tmp1 + * 2. tab -- rename --> tmp2 + * 3. tmp1 -- rename --> tab + * 4. delete tmp2 + * + * PBXT flushes a table before rename. + * In the sequence above results in a table flush in step 3 which can + * take a very long time. + * + * The problem is, during this time frame we have only temp tables. + * A crash in this state leaves the database in a bad state. + * + * To reduce the time in this state, the flush needs to be done + * elsewhere. The code below causes the flish to occur after + * step 1: + */ + switch (thd_sql_command(thd)) { + case SQLCOM_REPAIR: + case SQLCOM_RENAME_TABLE: + case SQLCOM_OPTIMIZE: + case SQLCOM_ANALYZE: + case SQLCOM_ALTER_TABLE: + case SQLCOM_CREATE_INDEX: + xt_sync_flush_table(self, ot); + break; + } + } } freer_(); // xt_db_return_table_to_pool(ot); } @@ -2356,9 +2397,15 @@ int ha_pbxt::open(const char *table_path, int XT_UNUSED(mode), uint XT_UNUSED(te #else xt_tab_load_row_pointers(self, pb_open_tab); #endif + xt_ind_set_index_selectivity(pb_open_tab, self); +#ifdef XT_ROW_COUNT_CORRECTED + /* {CORRECTED-ROW-COUNT} */ + pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 - pb_share->sh_table->tab_row_fnum) < 150; +#else /* {FREE-ROWS-BAD} */ pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150; +#endif } init_auto_increment(0); @@ -3929,6 +3976,8 @@ int ha_pbxt::info(uint flag) if ((ot = pb_open_tab)) { if (flag & HA_STATUS_VARIABLE) { + register XTTableHPtr tab = ot->ot_table; + /* {FREE-ROWS-BAD} * Free row count is not reliable, so ignore it. * The problem is if tab_row_fnum > tab_row_eof_id - 1 then @@ -3955,11 +4004,26 @@ int ha_pbxt::info(uint flag) * the actual number of vectors. But it must assume that it has at * least EXTRA_RECORDS vectors. */ - stats.deleted = /* ot->ot_table->tab_row_fnum */ 0; - stats.records = (ha_rows) (ot->ot_table->tab_row_eof_id - 1 /* - stats.deleted */); - stats.data_file_length = xt_rec_id_to_rec_offset(ot->ot_table, ot->ot_table->tab_rec_eof_id); - stats.index_file_length = xt_ind_node_to_offset(ot->ot_table, ot->ot_table->tab_ind_eof); - stats.delete_length = ot->ot_table->tab_rec_fnum * ot->ot_rec_size; +#ifdef XT_ROW_COUNT_CORRECTED + if (tab->tab_row_eof_id <= tab->tab_row_fnum || + (!tab->tab_row_free_id && tab->tab_row_fnum)) + xt_tab_check_free_lists(NULL, ot, false, true); + stats.records = (ha_rows) tab->tab_row_eof_id - 1; + if (stats.records >= tab->tab_row_fnum) { + stats.deleted = tab->tab_row_fnum; + stats.records -= stats.deleted; + } + else { + stats.deleted = 0; + stats.records = 2; + } +#else + stats.deleted = /* tab->tab_row_fnum */ 0; + stats.records = (ha_rows) (tab->tab_row_eof_id - 1 /* - stats.deleted */); +#endif + stats.data_file_length = xt_rec_id_to_rec_offset(tab, tab->tab_rec_eof_id); + stats.index_file_length = xt_ind_node_to_offset(tab, tab->tab_ind_eof); + stats.delete_length = tab->tab_rec_fnum * ot->ot_rec_size; //check_time = info.check_time; stats.mean_rec_length = (ulong) ot->ot_rec_size; } @@ -4584,13 +4648,24 @@ xtPublic int ha_pbxt::external_lock(THD *thd, int lock_type) } if (pb_share->sh_recalc_selectivity) { +#ifdef XT_ROW_COUNT_CORRECTED + /* {CORRECTED-ROW-COUNT} */ + if ((pb_share->sh_table->tab_row_eof_id - 1 - pb_share->sh_table->tab_row_fnum) >= 200) +#else /* {FREE-ROWS-BAD} */ - if ((pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) >= 200) { + if ((pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) >= 200) +#endif + { /* [**] */ pb_share->sh_recalc_selectivity = FALSE; xt_ind_set_index_selectivity(pb_open_tab, self); +#ifdef XT_ROW_COUNT_CORRECTED + /* {CORRECTED-ROW-COUNT} */ + pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 - pb_share->sh_table->tab_row_fnum) < 150; +#else /* {FREE-ROWS-BAD} */ pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150; +#endif } } } @@ -4638,6 +4713,17 @@ xtPublic int ha_pbxt::external_lock(THD *thd, int lock_type) goto complete; } cont_(a); + + /* Occurs if you do: + * truncate table t1; + * truncate table t1; + */ + if (!pb_open_tab) { + if ((err = reopen())) { + pb_ex_in_use = 0; + goto complete; + } + } } else { pb_ex_in_use = 1; @@ -6076,6 +6162,40 @@ mysql_declare_plugin(pbxt) drizzle_declare_plugin_end; #else mysql_declare_plugin_end; +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID > 50200 +maria_declare_plugin(pbxt) +{ /* PBXT */ + MYSQL_STORAGE_ENGINE_PLUGIN, + &pbxt_storage_engine, + "PBXT", + "Paul McCullagh, PrimeBase Technologies GmbH", + "High performance, multi-versioning transactional engine", + PLUGIN_LICENSE_GPL, + pbxt_init, /* Plugin Init */ + pbxt_end, /* Plugin Deinit */ + 0x0001 /* 0.1 */, + NULL, /* status variables */ + pbxt_system_variables, /* system variables */ + "1.0.11-7 Pre-GA", /* string version */ + MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ +}, +{ /* PBXT_STATISTICS */ + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &pbxt_statitics, + "PBXT_STATISTICS", + "Paul McCullagh, PrimeBase Technologies GmbH", + "PBXT internal system statitics", + PLUGIN_LICENSE_GPL, + pbxt_init_statistics, /* plugin init */ + pbxt_exit_statistics, /* plugin deinit */ + 0x0005, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0.11-7 Pre-GA", /* string version */ + MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ +} +maria_declare_plugin_end; +#endif #endif #if defined(XT_WIN) && defined(XT_COREDUMP) diff --git a/storage/pbxt/src/index_xt.cc b/storage/pbxt/src/index_xt.cc index c8995fe253c..f6c4b4d8aa3 100644 --- a/storage/pbxt/src/index_xt.cc +++ b/storage/pbxt/src/index_xt.cc @@ -272,10 +272,17 @@ static xtBool idx_new_branch(XTOpenTablePtr ot, XTIndexPtr ind, xtIndexNodeID *a } if ((XT_NODE_ID(wrote_pos) = XT_NODE_ID(tab->tab_ind_free))) { + xtIndexNodeID next_node; + /* Use the block on the free list: */ - if (!xt_ind_read_bytes(ot, ind, wrote_pos, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) + if (!xt_ind_read_bytes(ot, NULL, wrote_pos, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) + goto failed; + XT_NODE_ID(next_node) = (xtIndexNodeID) XT_GET_DISK_8(free_block.if_next_block_8); + if (XT_NODE_ID(next_node) >= XT_NODE_ID(tab->tab_ind_eof)) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, tab->tab_name); goto failed; - XT_NODE_ID(tab->tab_ind_free) = (xtIndexNodeID) XT_GET_DISK_8(free_block.if_next_block_8); + } + XT_NODE_ID(tab->tab_ind_free) = XT_NODE_ID(next_node); xt_unlock_mutex_ns(&tab->tab_ind_lock); *address = wrote_pos; TRACK_BLOCK_ALLOC(wrote_pos); @@ -1415,30 +1422,45 @@ static xtBool idx_replace_node_key(XTOpenTablePtr ot, XTIndexPtr ind, IdxStackIt if (idx_is_item_deleted(iref.ir_branch, &item->i_pos)) iref.ir_block->cp_del_count--; } - memmove(&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item_size], - &iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size], - item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size); - memcpy(&iref.ir_branch->tb_data[item->i_pos.i_item_offset], - item_buf, item_size); - if (ind->mi_lazy_delete) { - if (idx_is_item_deleted(iref.ir_branch, &item->i_pos)) - iref.ir_block->cp_del_count++; - } - item->i_pos.i_total_size = item->i_pos.i_total_size + item_size - item->i_pos.i_item_size; - XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(item->i_pos.i_total_size)); - IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2)); - iref.ir_updated = TRUE; + + if (item->i_pos.i_total_size + item_size - item->i_pos.i_item_size <= XT_INDEX_PAGE_DATA_SIZE) { + /* The new item is larger than the old, this can result + * in overflow of the node! + */ + memmove(&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item_size], + &iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size], + item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size); + memcpy(&iref.ir_branch->tb_data[item->i_pos.i_item_offset], + item_buf, item_size); + if (ind->mi_lazy_delete) { + if (idx_is_item_deleted(iref.ir_branch, &item->i_pos)) + iref.ir_block->cp_del_count++; + } + item->i_pos.i_total_size = item->i_pos.i_total_size + item_size - item->i_pos.i_item_size; + XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(item->i_pos.i_total_size)); + IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2)); + iref.ir_updated = TRUE; #ifdef DEBUG - if (ind->mi_lazy_delete) ASSERT_NS(item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE); #endif - if (item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE) return xt_ind_release(ot, ind, XT_UNLOCK_W_UPDATE, &iref); + } /* The node has overflowed!! */ result.sr_item = item->i_pos; + memcpy(ot->ot_ind_wbuf.tb_data, iref.ir_branch->tb_data, item->i_pos.i_item_offset); // First part of the buffer + memcpy(&ot->ot_ind_wbuf.tb_data[item->i_pos.i_item_offset], item_buf, item_size); // The new item + memcpy(&ot->ot_ind_wbuf.tb_data[item->i_pos.i_item_offset + item_size], + &iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size], + item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size); + item->i_pos.i_total_size += item_size - item->i_pos.i_item_size; + item->i_pos.i_item_size = item_size; + XT_SET_DISK_2(ot->ot_ind_wbuf.tb_size_2, XT_MAKE_LEAF_SIZE(item->i_pos.i_total_size)); + IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(ot->ot_ind_wbuf.tb_size_2)); + ASSERT_NS(item->i_pos.i_total_size > XT_INDEX_PAGE_DATA_SIZE && item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE*2); + /* Adjust the stack (we want the parents of the delete node): */ for (;;) { if (idx_pop(stack) == item) @@ -1448,7 +1470,7 @@ static xtBool idx_replace_node_key(XTOpenTablePtr ot, XTIndexPtr ind, IdxStackIt /* We assume that value can be overwritten (which is the case) */ key_value.sv_flags = XT_SEARCH_WHOLE_KEY; key_value.sv_key = key_buf; - if (!idx_get_middle_branch_item(ot, ind, iref.ir_branch, &key_value, &result)) + if (!idx_get_middle_branch_item(ot, ind, &ot->ot_ind_wbuf, &key_value, &result)) goto failed_1; if (!idx_new_branch(ot, ind, &new_branch)) @@ -1456,7 +1478,6 @@ static xtBool idx_replace_node_key(XTOpenTablePtr ot, XTIndexPtr ind, IdxStackIt /* Split the node: */ new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size; - // TODO: Are 2 buffers now required? new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE]; memmove(new_branch_ptr->tb_data, &iref.ir_branch->tb_data[result.sr_item.i_item_offset + result.sr_item.i_item_size], new_size); @@ -1466,10 +1487,10 @@ static xtBool idx_replace_node_key(XTOpenTablePtr ot, XTIndexPtr ind, IdxStackIt goto failed_2; /* Change the size of the old branch: */ - XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(result.sr_item.i_item_offset)); - IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2)); + XT_SET_DISK_2(ot->ot_ind_wbuf.tb_size_2, XT_MAKE_NODE_SIZE(result.sr_item.i_item_offset)); + IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(ot->ot_ind_wbuf.tb_size_2)); + memcpy(iref.ir_branch, &ot->ot_ind_wbuf, offsetof(XTIdxBranchDRec, tb_data) + result.sr_item.i_item_offset); iref.ir_updated = TRUE; - xt_ind_release(ot, ind, XT_UNLOCK_W_UPDATE, &iref); /* Insert the new branch into the parent node, using the new middle key value: */ @@ -2071,6 +2092,11 @@ xtPublic xtBool xt_idx_insert(XTOpenTablePtr ot, XTIndexPtr ind, xtRowID row_id, if (!idx_new_branch(ot, ind, &new_branch)) goto failed_1; + if (XT_NODE_ID(current) == XT_NODE_ID(new_branch)) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + goto failed_1; + } + /* Copy and write the rest of the data to the new node: */ new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size; new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE]; @@ -2723,6 +2749,10 @@ xtPublic xtBool xt_idx_search(XTOpenTablePtr ot, XTIndexPtr ind, register XTIdxS #endif ASSERT_NS(iref.ir_xlock == 2); ASSERT_NS(iref.ir_updated == 2); + if (ind->mi_key_corrupted) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + return FAILED; + } return OK; failed: @@ -2874,6 +2904,10 @@ xtPublic xtBool xt_idx_search_prev(XTOpenTablePtr ot, XTIndexPtr ind, register X //idx_check_index(ot, ind, TRUE); //idx_check_on_key(ot); #endif + if (ind->mi_key_corrupted) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + return FAILED; + } return OK; failed: @@ -2964,6 +2998,10 @@ xtPublic xtBool xt_idx_next(register XTOpenTablePtr ot, register XTIndexPtr ind, if (!(XT_NODE_ID(current) = XT_NODE_ID(ind->mi_root))) { XT_INDEX_UNLOCK(ind, ot); + if (ind->mi_key_corrupted) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + return FAILED; + } return OK; } @@ -3071,6 +3109,10 @@ xtPublic xtBool xt_idx_next(register XTOpenTablePtr ot, register XTIndexPtr ind, ot->ot_curr_rec_id = 0; ot->ot_curr_row_id = 0; XT_INDEX_UNLOCK(ind, ot); + if (ind->mi_key_corrupted) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + return FAILED; + } return OK; } @@ -3112,6 +3154,10 @@ xtPublic xtBool xt_idx_next(register XTOpenTablePtr ot, register XTIndexPtr ind, ot->ot_curr_row_id = result.sr_row_id; ot->ot_ind_state = result.sr_item; + if (ind->mi_key_corrupted) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + return FAILED; + } return OK; failed: @@ -3178,6 +3224,10 @@ xtPublic xtBool xt_idx_prev(register XTOpenTablePtr ot, register XTIndexPtr ind, if (!(XT_NODE_ID(current) = XT_NODE_ID(ind->mi_root))) { XT_INDEX_UNLOCK(ind, ot); + if (ind->mi_key_corrupted) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + return FAILED; + } return OK; } @@ -3274,6 +3324,10 @@ xtPublic xtBool xt_idx_prev(register XTOpenTablePtr ot, register XTIndexPtr ind, ot->ot_curr_row_id = 0; XT_INDEX_UNLOCK(ind, ot); + if (ind->mi_key_corrupted) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + return FAILED; + } return OK; unlock_check_on_key: @@ -3302,6 +3356,10 @@ xtPublic xtBool xt_idx_prev(register XTOpenTablePtr ot, register XTIndexPtr ind, ot->ot_curr_rec_id = result.sr_rec_id; ot->ot_curr_row_id = result.sr_row_id; ot->ot_ind_state = result.sr_item; + if (ind->mi_key_corrupted) { + xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name); + return FAILED; + } return OK; failed: @@ -3648,7 +3706,7 @@ xtPublic void xt_check_indices(XTOpenTablePtr ot) track_block_exists(current); #endif printf("%d ", (int) XT_NODE_ID(current)); - if (!xt_ind_read_bytes(ot, *ind, current, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) { + if (!xt_ind_read_bytes(ot, NULL, current, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) { xt_log_and_clear_exception_ns(); break; } @@ -4141,11 +4199,18 @@ void XTIndexLogPool::ilp_init(struct XTThread *self, struct XTDatabase *db, size if (!ilp_open_log(&il, log_id, FALSE, self)) goto failed; if (il->il_tab_id && il->il_log_eof) { + char table_name[XT_IDENTIFIER_NAME_SIZE*3+3]; + if (!il->il_open_table(&ot)) goto failed; if (ot) { - if (!il->il_apply_log(ot)) - goto failed; + xt_tab_make_table_name(ot->ot_table, table_name, sizeof(table_name)); + xt_logf(XT_NT_INFO, "PBXT: Recovering index, table: %s, bytes to read: %llu\n", table_name, (u_llong) il->il_log_eof); + if (!il->il_apply_log(ot)) { + /* If recovery of an index fails, then it is corrupt! */ + xt_tab_disable_index(ot->ot_table, XT_INDEX_CORRUPTED); + xt_log_and_clear_exception_ns(); + } ot->ot_thread = self; il->il_close_table(ot); } @@ -4468,8 +4533,7 @@ xtBool XTIndexLog::il_apply_log(struct XTOpenTable *ot) /* Corrupt log?! */ if (il_buffer_len < req_size) { xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of)); - xt_log_and_clear_exception_ns(); - return OK; + return FAILED; } if (!xt_pread_file(il_of, offset, il_buffer_len, il_buffer_len, il_buffer, NULL, &ot->ot_thread->st_statistics.st_ilog, ot->ot_thread)) return FAILED; @@ -4548,8 +4612,7 @@ xtBool XTIndexLog::il_apply_log(struct XTOpenTable *ot) /* Corrupt log?! */ if (il_buffer_len < req_size) { xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of)); - xt_log_and_clear_exception_ns(); - return OK; + return FAILED; } if (!xt_pread_file(il_of, offset, il_buffer_len, il_buffer_len, il_buffer, NULL, &ot->ot_thread->st_statistics.st_ilog, ot->ot_thread)) return FAILED; @@ -4597,8 +4660,7 @@ xtBool XTIndexLog::il_apply_log(struct XTOpenTable *ot) break; default: xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of)); - xt_log_and_clear_exception_ns(); - return OK; + return FAILED; } } diff --git a/storage/pbxt/src/index_xt.h b/storage/pbxt/src/index_xt.h index 52f8f32dd33..a56e7b3cdb7 100644 --- a/storage/pbxt/src/index_xt.h +++ b/storage/pbxt/src/index_xt.h @@ -312,7 +312,7 @@ typedef struct XTIndex { u_int mi_flags; u_int mi_key_size; u_int mi_max_items; /* The maximum number of items that can fit in a leaf node. */ - xtBool mi_low_byte_first; + xtBool mi_key_corrupted; /* Set to TRUE if a currupted index key is detected. */ xtBool mi_fix_key; xtBool mi_lazy_delete; /* TRUE if index entries are "lazy deleted". */ u_int mi_single_type; /* Used when the index contains a single field. */ diff --git a/storage/pbxt/src/myxt_xt.cc b/storage/pbxt/src/myxt_xt.cc index 51490fc00f5..410bf2d2f3c 100644 --- a/storage/pbxt/src/myxt_xt.cc +++ b/storage/pbxt/src/myxt_xt.cc @@ -1088,7 +1088,10 @@ xtPublic u_int myxt_get_key_length(XTIndexPtr ind, xtWord1 *key_buf) } end: - return (xtWord1 *) key_data - key_buf; + u_int ilen = (xtWord1 *) key_data - key_buf; + if (ilen > XT_INDEX_MAX_KEY_SIZE) + ind->mi_key_corrupted = TRUE; + return ilen; } /* Derived from ha_key_cmp */ @@ -2183,7 +2186,8 @@ static XTIndexPtr my_create_index(XTThreadPtr self, TABLE *table_arg, u_int idx, xt_spinlock_init_with_autoname(self, &ind->mi_dirty_lock); ind->mi_index_no = idx; ind->mi_flags = (index->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL | HA_UNIQUE_CHECK)); - ind->mi_low_byte_first = TS(table_arg)->db_low_byte_first; + //ind->mi_low_byte_first = TS(table_arg)->db_low_byte_first; + ind->mi_key_corrupted = FALSE; ind->mi_fix_key = TRUE; ind->mi_select_total = 0; ind->mi_subset_of = 0; diff --git a/storage/pbxt/src/myxt_xt.h b/storage/pbxt/src/myxt_xt.h index 546b57c6e84..3898c8e30c6 100644 --- a/storage/pbxt/src/myxt_xt.h +++ b/storage/pbxt/src/myxt_xt.h @@ -69,17 +69,17 @@ void myxt_free_dictionary(XTThreadPtr self, XTDictionary *dic); void myxt_move_dictionary(XTDictionaryPtr dic, XTDictionaryPtr source_dic); XTDDTable *myxt_create_table_from_table(XTThreadPtr self, STRUCT_TABLE *my_tab); -void myxt_static_convert_identifier(XTThreadPtr self, struct charset_info_st *cs, char *from, char *to, size_t to_len); -char *myxt_convert_identifier(XTThreadPtr self, struct charset_info_st *cs, char *from); +void myxt_static_convert_identifier(XTThreadPtr self, MX_CONST_CHARSET_INFO *cs, char *from, char *to, size_t to_len); +char *myxt_convert_identifier(XTThreadPtr self, MX_CONST_CHARSET_INFO *cs, char *from); void myxt_static_convert_table_name(XTThreadPtr self, char *from, char *to, size_t to_len); void myxt_static_convert_file_name(char *from, char *to, size_t to_len); char *myxt_convert_table_name(XTThreadPtr self, char *from); int myxt_strcasecmp(char * a, char *b); -int myxt_isspace(struct charset_info_st *cs, char a); -int myxt_ispunct(struct charset_info_st *cs, char a); -int myxt_isdigit(struct charset_info_st *cs, char a); +int myxt_isspace(MX_CONST_CHARSET_INFO *cs, char a); +int myxt_ispunct(MX_CONST_CHARSET_INFO *cs, char a); +int myxt_isdigit(MX_CONST_CHARSET_INFO *cs, char a); -struct charset_info_st *myxt_getcharset(bool convert); +MX_CONST_CHARSET_INFO *myxt_getcharset(bool convert); void *myxt_create_thread(); void myxt_destroy_thread(void *thread, xtBool end_threads); diff --git a/storage/pbxt/src/restart_xt.cc b/storage/pbxt/src/restart_xt.cc index b0c8f2854ae..93720f2b113 100644 --- a/storage/pbxt/src/restart_xt.cc +++ b/storage/pbxt/src/restart_xt.cc @@ -1359,6 +1359,57 @@ static xtBool xres_sync_operations(XTThreadPtr self, XTDatabaseHPtr db, XTWriter return op_synced; } +#ifdef XT_CORRECT_TABLE_FREE_COUNT +#define CORRECT_COUNT TRUE +#else +#define CORRECT_COUNT FALSE +#endif +#ifdef XT_CHECK_RECORD_FREE_COUNT +#define CHECK_RECS TRUE +#else +#define CHECK_RECS FALSE +#endif +#if defined(XT_CHECK_RECORD_FREE_COUNT) || defined(XT_CHECK_ROW_FREE_COUNT) +#define RECOVER_FREE_COUNTS +#endif + +#ifdef RECOVER_FREE_COUNTS +/* {CORRECTED-ROW-COUNT} + * This error can be repeated by crashing the server during + * high activitity, after flush table writes the table header + * + * On recovery, the free count "from the future" is used as + * the starting point for subsequent allocation and frees. + * The count is wrong after that point. + * + * The recovery of the count only works correctly if a + * checkpoint is complete successfully after that table + * header is flushed. Basically the writing of the table + * header should be synchronsized with the writing of the + * end of the checkpoint. + * + * Another solution would be to log the count, along with + * the allocate and free commannds. + * + * The 3rd solution is the one used here. The count is corrected + * after recovery. + */ +static void xres_recover_table_free_counts(XTThreadPtr self, XTDatabaseHPtr db, XTWriterStatePtr ws) +{ + u_int edx; + XTTableEntryPtr te_ptr; + XTTableHPtr tab; + + xt_enum_tables_init(&edx); + while ((te_ptr = xt_enum_tables_next(self, db, &edx))) { + if ((tab = te_ptr->te_table)) { + if (xres_open_table(self, ws, te_ptr->te_tab_id)) + xt_tab_check_free_lists(self, ws->ws_ot, CHECK_RECS, CORRECT_COUNT); + } + } +} +#endif + /* * Operations from the log are applied in sequence order. * If the operations are out of sequence, they are buffered @@ -2175,6 +2226,13 @@ xtBool XTXactRestart::xres_restart(XTThreadPtr self, xtLogID *log_id, xtLogOffse /* This is true because if no transaction was placed in RAM then * the next transaction in RAM will have the next ID: */ db->db_xn_min_ram_id = db->db_xn_curr_id + 1; + +#ifdef RECOVER_FREE_COUNTS + if (xres_cp_log_id != *log_id || xres_cp_log_offset != *log_offset) { + /* Recovery took place, correct the row count! */ + xres_recover_table_free_counts(self, db, &ws); + } +#endif } failed: diff --git a/storage/pbxt/src/strutil_xt.cc b/storage/pbxt/src/strutil_xt.cc index 02132fbb06b..8183034a204 100644 --- a/storage/pbxt/src/strutil_xt.cc +++ b/storage/pbxt/src/strutil_xt.cc @@ -380,7 +380,7 @@ xtPublic void xt_int8_to_byte_size(xtInt8 value, char *string) /* Version number must also be set in configure.in! */ xtPublic c_char *xt_get_version(void) { - return "1.0.11 Pre-GA"; + return "1.0.11-7 Pre-GA"; } /* Copy and URL decode! */ diff --git a/storage/pbxt/src/table_xt.cc b/storage/pbxt/src/table_xt.cc index b01f4404ce3..2d93f161ac9 100644 --- a/storage/pbxt/src/table_xt.cc +++ b/storage/pbxt/src/table_xt.cc @@ -80,6 +80,65 @@ /* * ----------------------------------------------------------------------- + * Handle Error Detected in a Table + */ + +struct XTTableError { + xtTableID ter_tab_id; + xtRecordID ter_rec_id; +}; + +static int tab_comp_tab_error(XTThreadPtr XT_UNUSED(self), register const void *XT_UNUSED(thunk), register const void *a, register const void *b) +{ + XTTableError *ter_a = ((XTTableError *) a); + XTTableError *ter_b = (XTTableError *) b; + + if (ter_a->ter_tab_id < ter_b->ter_tab_id) + return -1; + if (ter_a->ter_tab_id == ter_b->ter_tab_id) { + if (ter_a->ter_rec_id < ter_b->ter_rec_id) + return -1; + if (ter_a->ter_rec_id == ter_b->ter_rec_id) + return 0; + return 1; + } + return 1; +} + +static xtBool tab_record_corrupt(XTOpenTablePtr ot, xtRowID row_id, xtRecordID rec_id, bool not_valid, int where) +{ + XTTableHPtr tab = ot->ot_table; + XTDatabaseHPtr db = tab->tab_db; + XTTableError ter; + XTTableError *ter_ptr; + + ter.ter_tab_id = tab->tab_id; + ter.ter_rec_id = rec_id; + + xt_sl_lock_ns(db->db_error_list, ot->ot_thread); + if (!(ter_ptr = (XTTableError *) xt_sl_find(NULL, db->db_error_list, &ter))) { + xtBool ok; + char table_name[XT_IDENTIFIER_NAME_SIZE*3+3]; + + ok = xt_sl_insert(NULL, db->db_error_list, &ter, &ter); + xt_sl_unlock_ns(db->db_error_list); + if (!ok) + return FAILED; + xt_tab_set_table_repair_pending(tab); + xt_tab_make_table_name(tab, table_name, sizeof(table_name)); + xt_logf(XT_NT_ERROR, "#%d Table %s: row %llu, record %llu, is %s, REPAIR TABLE required.\n", where, + table_name, + (u_llong) row_id, + (u_llong) rec_id, + not_valid ? "not valid" : "free"); + } + else + xt_sl_unlock_ns(db->db_error_list); + return OK; +} + +/* + * ----------------------------------------------------------------------- * Compare paths: */ @@ -425,6 +484,7 @@ xtPublic void xt_tab_init_db(XTThreadPtr self, XTDatabaseHPtr db) db->db_tables = xt_new_hashtable(self, tab_list_comp, tab_list_hash, tab_list_free, TRUE, TRUE); db->db_table_by_id = xt_new_sortedlist(self, sizeof(XTTableEntryRec), 20, 20, tab_comp_by_id, db, tab_free_by_id, FALSE, FALSE); db->db_table_paths = xt_new_sortedlist(self, sizeof(XTTablePathPtr), 20, 20, tab_comp_path, db, tab_free_path, FALSE, FALSE); + db->db_error_list = xt_new_sortedlist(self, sizeof(XTTableError), 20, 20, tab_comp_tab_error, db, NULL, TRUE, FALSE); if (db->db_multi_path) { XTOpenFilePtr of; @@ -649,6 +709,10 @@ xtPublic void xt_tab_exit_db(XTThreadPtr self, XTDatabaseHPtr db) xt_free_sortedlist(self, db->db_table_paths); db->db_table_paths = NULL; } + if (db->db_error_list) { + xt_free_sortedlist(self, db->db_error_list); + db->db_error_list = NULL; + } } static void tab_check_table(XTThreadPtr self, XTTableHPtr XT_UNUSED(tab)) @@ -1713,6 +1777,116 @@ xtPublic void xt_drop_table(XTThreadPtr self, XTPathStrPtr tab_name, xtBool drop exit_(); } +xtPublic void xt_tab_check_free_lists(XTThreadPtr self, XTOpenTablePtr ot, bool check_recs, bool correct_count) +{ + char table_name[XT_IDENTIFIER_NAME_SIZE*3+3]; + register XTTableHPtr tab = ot->ot_table; + xtRowID prev_row_id; + xtRowID row_id; + xtRefID next_row_id; + u_llong free_count; + + xt_tab_make_table_name(tab, table_name, sizeof(table_name)); + if (check_recs) { + xtRecordID prev_rec_id; + xtRecordID rec_id; + XTTabRecExtDRec rec_buf; + + xt_lock_mutex_ns(&tab->tab_rec_lock); + /* Checking the free list: */ + prev_rec_id = 0; + free_count = 0; + rec_id = tab->tab_rec_free_id; + while (rec_id) { + if (rec_id >= tab->tab_rec_eof_id) { + xt_logf(XT_NT_ERROR, "Table %s: invalid reference on free list: %llu, ", table_name, (u_llong) rec_id); + if (prev_rec_id) + xt_logf(XT_NT_ERROR, "reference by: %llu\n", (u_llong) prev_rec_id); + else + xt_logf(XT_NT_ERROR, "reference by list head pointer\n"); + xt_tab_set_table_repair_pending(tab); + break; + } + if (!xt_tab_get_rec_data(ot, rec_id, XT_REC_FIX_HEADER_SIZE, (xtWord1 *) &rec_buf)) { + if (self) + xt_throw(self); + else + xt_log_and_clear_warning(ot->ot_thread); + break; + } + if ((rec_buf.tr_rec_type_1 & XT_TAB_STATUS_MASK) != XT_TAB_STATUS_FREED) + xt_logf(XT_NT_INFO, "Table %s: record, %llu, on free list is not free\n", table_name, (u_llong) rec_id); + free_count++; + prev_rec_id = rec_id; + rec_id = XT_GET_DISK_4(rec_buf.tr_prev_rec_id_4); + } + if (free_count != tab->tab_rec_fnum) { + if (correct_count) { + tab->tab_rec_fnum = free_count; + tab->tab_head_rec_fnum = free_count; + tab->tab_flush_pending = TRUE; + xt_logf(XT_NT_INFO, "Table %s: free record count (%llu) has been set to the number of records on the list: %llu\n", table_name, (u_llong) tab->tab_rec_fnum, (u_llong) free_count); + } + else + xt_logf(XT_NT_INFO, "Table %s: free record count (%llu) differs from the number of records on the list: %llu\n", table_name, (u_llong) tab->tab_rec_fnum, (u_llong) free_count); + } + xt_unlock_mutex_ns(&tab->tab_rec_lock); + } + + /* Check the row free list: */ + xt_lock_mutex_ns(&tab->tab_row_lock); + + prev_row_id = 0; + free_count = 0; + row_id = tab->tab_row_free_id; + while (row_id) { + if (row_id >= tab->tab_row_eof_id) { + xt_logf(XT_NT_ERROR, "Table %s: invalid reference on free row: %llu, ", table_name, (u_llong) row_id); + if (prev_row_id) + xt_logf(XT_NT_ERROR, "reference by: %llu\n", (u_llong) prev_row_id); + else + xt_logf(XT_NT_ERROR, "reference by list head pointer\n"); + xt_tab_set_table_repair_pending(tab); + break; + } + if (!tab->tab_rows.xt_tc_read_4(ot->ot_row_file, row_id, &next_row_id, ot->ot_thread)) { + if (self) + xt_throw(self); + else + xt_log_and_clear_warning(ot->ot_thread); + break; + } + free_count++; + prev_row_id = row_id; + row_id = next_row_id; + } + if (free_count != tab->tab_row_fnum) { + if (correct_count) { + /* tab_row_fnum is the current value, and tab_head_row_fnum is the value on + * disk. tab_head_row_fnum is set by the writer as the changes are applied + * to the database. + * + * This is the value then stored in the header of the file. This value + * is in sync with other changes to the file. + * + * So the fact that I am setting both value means this will not work at + * runtime, unless all changes have been applied by the writer. + * + * The correct way to do this at run time would be to add the change to the + * transaction log, so that it is applied by the writer. + */ + tab->tab_row_fnum = free_count; + tab->tab_head_row_fnum = free_count; + tab->tab_flush_pending = TRUE; + xt_logf(XT_NT_INFO, "Table %s: free row count (%llu) has been set to the number of rows on the list: %llu\n", table_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count); + } + else + xt_logf(XT_NT_INFO, "Table %s: free row count (%llu) differs from the number of rows on the list: %llu\n", table_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count); + } + + xt_unlock_mutex_ns(&tab->tab_row_lock); +} + /* * Record buffer size: * ------------------- @@ -2010,7 +2184,7 @@ xtPublic void xt_check_table(XTThreadPtr self, XTOpenTablePtr ot) prec_id = rec_id; rec_id = XT_GET_DISK_4(rec_buf->tr_prev_rec_id_4); } - if (free_count2 < free_rec_count) + if (free_count2 != free_rec_count) xt_logf(XT_INFO, "Table %s: not all free blocks (%llu) on free list: %llu\n", tab->tab_name, (u_llong) free_rec_count, (u_llong) free_count2); freer_(); // xt_unlock_mutex_ns(&tab->tab_rec_lock); @@ -2042,6 +2216,29 @@ xtPublic void xt_check_table(XTThreadPtr self, XTOpenTablePtr ot) rec_id++; } + prec_id = 0; + free_count2 = 0; + row_id = tab->tab_row_free_id; + while (row_id) { + if (row_id >= tab->tab_row_eof_id) { + xt_logf(XT_INFO, "Table %s: invalid reference on free row: %llu, ", tab->tab_name, (u_llong) row_id); + if (prec_id) + xt_logf(XT_INFO, "reference by: %llu\n", (u_llong) prec_id); + else + xt_logf(XT_INFO, "reference by list head pointer\n"); + break; + } + if (!tab->tab_rows.xt_tc_read_4(ot->ot_row_file, row_id, &ref_id, self)) { + xt_log_and_clear_exception(self); + break; + } + free_count2++; + prec_id = row_id; + row_id = ref_id; + } + if (free_count2 != tab->tab_row_fnum) + xt_logf(XT_INFO, "Table %s: free row count (%llu) differs from the number of row on the list: %llu\n", tab->tab_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count2); + freer_(); // xt_unlock_mutex(&tab->tab_row_lock); #ifdef CHECK_INDEX_ON_CHECK_TABLE @@ -3117,10 +3314,18 @@ static int tab_visible(register XTOpenTablePtr ot, XTTabRecHeadDPtr rec_head, xt #endif break; case XT_XN_REREAD: + /* {RETRY-READ} + * TODO: This is not as "correct" as it could be. + * Such records should be considered to be aborted, + * and removed from the list. + */ if (invalid_rec != var_rec_id) { invalid_rec = var_rec_id; goto retry_3; } + if (!tab_record_corrupt(ot, row_id, var_rec_id, true, 1)) + goto failed; + /* Assume end of list. */ #ifdef XT_CRASH_DEBUG /* Should not happen! */ @@ -3308,6 +3513,8 @@ xtPublic int xt_tab_visible(XTOpenTablePtr ot) /* Avoid infinite loop: */ if (read_again) { /* Should not happen! */ + if (!tab_record_corrupt(ot, row_id, ot->ot_curr_rec_id, true, 2)) + return XT_ERR; #ifdef XT_CRASH_DEBUG /* Generate a core dump! */ xt_crash_me(); @@ -3364,6 +3571,8 @@ xtPublic int xt_tab_read_record(register XTOpenTablePtr ot, xtWord1 *buffer) /* Avoid infinite loop: */ if (read_again) { /* Should not happen! */ + if (!tab_record_corrupt(ot, XT_GET_DISK_4(((XTTabRecHeadDPtr) ot->ot_row_rbuffer)->tr_row_id_4), ot->ot_curr_rec_id, true, 3)) + return XT_ERR; #ifdef XT_CRASH_DEBUG /* Generate a core dump! */ xt_crash_me(); @@ -3580,6 +3789,7 @@ xtPublic xtBool xt_tab_free_row(XTOpenTablePtr ot, XTTableHPtr tab, xtRowID row_ } tab->tab_row_free_id = row_id; tab->tab_row_fnum++; + ASSERT_NS(tab->tab_row_fnum < tab->tab_row_eof_id); xt_unlock_mutex_ns(&tab->tab_row_lock); if (!xt_xlog_modify_table(tab->tab_id, XT_LOG_ENT_ROW_FREED, op_seq, 0, row_id, sizeof(XTTabRowRefDRec), (xtWord1 *) &free_row, ot->ot_thread)) @@ -3776,7 +3986,7 @@ xtPublic int xt_tab_remove_record(XTOpenTablePtr ot, xtRecordID rec_id, xtWord1 xt_lock_mutex_ns(&tab->tab_db->db_co_ext_lock); if (!xt_tab_get_rec_data(ot, rec_id, XT_REC_EXT_HEADER_SIZE, ot->ot_row_rbuffer)) { xt_unlock_mutex_ns(&tab->tab_db->db_co_ext_lock); - return FAILED; + return XT_ERR; } xt_unlock_mutex_ns(&tab->tab_db->db_co_ext_lock); @@ -3824,7 +4034,7 @@ xtPublic int xt_tab_remove_record(XTOpenTablePtr ot, xtRecordID rec_id, xtWord1 XT_SET_DISK_4(free_rec->rf_next_rec_id_4, prev_rec_id); if (!xt_tab_put_rec_data(ot, rec_id, sizeof(XTTabRecFreeDRec), ot->ot_row_rbuffer, &op_seq)) { xt_unlock_mutex_ns(&tab->tab_rec_lock); - return FAILED; + return XT_ERR; } tab->tab_rec_free_id = rec_id; ASSERT_NS(tab->tab_rec_free_id < tab->tab_rec_eof_id); @@ -3832,7 +4042,9 @@ xtPublic int xt_tab_remove_record(XTOpenTablePtr ot, xtRecordID rec_id, xtWord1 xt_unlock_mutex_ns(&tab->tab_rec_lock); free_rec->rf_rec_type_1 = old_rec_type; - return xt_xlog_modify_table(tab->tab_id, XT_LOG_ENT_REC_REMOVED_BI, op_seq, (xtRecordID) new_rec_type, rec_id, rec_size, ot->ot_row_rbuffer, ot->ot_thread); + if (!xt_xlog_modify_table(tab->tab_id, XT_LOG_ENT_REC_REMOVED_BI, op_seq, (xtRecordID) new_rec_type, rec_id, rec_size, ot->ot_row_rbuffer, ot->ot_thread)) + return XT_ERR; + return OK; } static xtRowID tab_new_row(XTOpenTablePtr ot, XTTableHPtr tab) @@ -3851,6 +4063,7 @@ static xtRowID tab_new_row(XTOpenTablePtr ot, XTTableHPtr tab) return 0; } tab->tab_row_free_id = next_row_id; + ASSERT_NS(tab->tab_row_fnum > 0); tab->tab_row_fnum--; } else { @@ -4170,9 +4383,12 @@ static xtBool tab_wait_for_rollback(XTOpenTablePtr ot, xtRowID row_id, xtRecordI return FAILED; if (XT_REC_IS_CLEAN(var_head.tr_rec_type_1)) goto locked; - if (XT_REC_IS_FREE(var_head.tr_rec_type_1)) + if (XT_REC_IS_FREE(var_head.tr_rec_type_1)) { /* Should not happen: */ + if (!tab_record_corrupt(ot, row_id, var_rec_id, false, 4)) + return FAILED; goto record_invalid; + } xn_id = XT_GET_DISK_4(var_head.tr_xact_id_4); switch (xt_xn_status(ot, xn_id, var_rec_id)) { case XT_XN_VISIBLE: @@ -4195,6 +4411,8 @@ static xtBool tab_wait_for_rollback(XTOpenTablePtr ot, xtRowID row_id, xtRecordI XT_TAB_ROW_WRITE_LOCK(&tab->tab_row_rwlock[row_id % XT_ROW_RWLOCKS], ot->ot_thread); goto retry; case XT_XN_REREAD: + if (!tab_record_corrupt(ot, row_id, var_rec_id, true, 5)) + return FAILED; goto record_invalid; } var_rec_id = XT_GET_DISK_4(var_head.tr_prev_rec_id_4); @@ -4206,9 +4424,10 @@ static xtBool tab_wait_for_rollback(XTOpenTablePtr ot, xtRowID row_id, xtRecordI return FAILED; record_invalid: + /* {RETRY-READ} */ /* Prevent an infinite loop due to a bad record: */ if (invalid_rec != var_rec_id) { - var_rec_id = invalid_rec; + invalid_rec = var_rec_id; goto retry; } /* The record is invalid, it will be "overwritten"... */ @@ -4280,9 +4499,12 @@ xtPublic int xt_tab_maybe_committed(XTOpenTablePtr ot, xtRecordID rec_id, xtXact #ifdef TRACE_VARIATIONS_IN_DUP_CHECK t_type="Re-read"; #endif + /* {RETRY-READ} */ /* Avoid infinite loop: */ if (invalid_rec == rec_id) { /* Should not happen! */ + if (!tab_record_corrupt(ot, XT_GET_DISK_4(rec_head.tr_row_id_4), rec_id, true, 6)) + goto failed; #ifdef XT_CRASH_DEBUG /* Generate a core dump! */ xt_crash_me(); @@ -4327,7 +4549,7 @@ xtPublic int xt_tab_maybe_committed(XTOpenTablePtr ot, xtRecordID rec_id, xtXact if (XT_REC_IS_FREE(rec_head.tr_rec_type_1)) { /* Should not happen: */ if (invalid_rec != var_rec_id) { - var_rec_id = invalid_rec; + invalid_rec = var_rec_id; goto retry; } /* Assume end of list. */ @@ -4364,11 +4586,14 @@ xtPublic int xt_tab_maybe_committed(XTOpenTablePtr ot, xtRecordID rec_id, xtXact } break; case XT_XN_REREAD: + /* {RETRY-READ} */ if (invalid_rec != var_rec_id) { - var_rec_id = invalid_rec; + invalid_rec = var_rec_id; goto retry; } /* Assume end of list. */ + if (!tab_record_corrupt(ot, row_id, invalid_rec, true, 7)) + goto failed; #ifdef XT_CRASH_DEBUG /* Should not happen! */ xt_crash_me(); @@ -5068,6 +5293,8 @@ xtPublic xtBool xt_tab_seq_next(XTOpenTablePtr ot, xtWord1 *buffer, xtBool *eof) ot->ot_on_page = FALSE; goto next_page; } + if (!tab_record_corrupt(ot, XT_GET_DISK_4(((XTTabRecHeadDPtr) buff_ptr)->tr_row_id_4), invalid_rec, true, 8)) + return XT_ERR; #ifdef XT_CRASH_DEBUG /* Should not happen! */ xt_crash_me(); @@ -5240,7 +5467,7 @@ static xtBool tab_exec_repair_pending(XTDatabaseHPtr db, int what, char *table_n return FALSE; } -static void tab_make_table_name(XTTableHPtr tab, char *table_name, size_t size) +xtPublic void xt_tab_make_table_name(XTTableHPtr tab, char *table_name, size_t size) { char *nptr; @@ -5316,7 +5543,7 @@ xtPublic xtBool xt_tab_is_table_repair_pending(XTTableHPtr tab) { char table_name[XT_IDENTIFIER_NAME_SIZE*3+3]; - tab_make_table_name(tab, table_name, sizeof(table_name)); + xt_tab_make_table_name(tab, table_name, sizeof(table_name)); return tab_exec_repair_pending(tab->tab_db, REP_FIND, table_name); } @@ -5326,7 +5553,7 @@ xtPublic void xt_tab_table_repaired(XTTableHPtr tab) char table_name[XT_IDENTIFIER_NAME_SIZE*3+3]; tab->tab_repair_pending = FALSE; - tab_make_table_name(tab, table_name, sizeof(table_name)); + xt_tab_make_table_name(tab, table_name, sizeof(table_name)); tab_exec_repair_pending(tab->tab_db, REP_DEL, table_name); } } @@ -5337,7 +5564,7 @@ xtPublic void xt_tab_set_table_repair_pending(XTTableHPtr tab) char table_name[XT_IDENTIFIER_NAME_SIZE*3+3]; tab->tab_repair_pending = TRUE; - tab_make_table_name(tab, table_name, sizeof(table_name)); + xt_tab_make_table_name(tab, table_name, sizeof(table_name)); tab_exec_repair_pending(tab->tab_db, REP_ADD, table_name); } } diff --git a/storage/pbxt/src/table_xt.h b/storage/pbxt/src/table_xt.h index 83f2168dd6e..f6c32587419 100644 --- a/storage/pbxt/src/table_xt.h +++ b/storage/pbxt/src/table_xt.h @@ -507,6 +507,7 @@ int xt_tab_compare_names(const char *n1, const char *n2); int xt_tab_compare_paths(char *n1, char *n2); void xt_tab_init_db(struct XTThread *self, struct XTDatabase *db); void xt_tab_exit_db(struct XTThread *self, struct XTDatabase *db); +void xt_tab_check_free_lists(struct XTThread *self, XTOpenTablePtr ot, bool check_recs, bool correct_count); void xt_check_tables(struct XTThread *self); char *xt_tab_file_to_name(size_t size, char *tab_name, char *file_name); @@ -572,6 +573,7 @@ xtBool xt_tab_get_rec_data(register XTOpenTablePtr ot, xtRecordID rec_id, siz void xt_tab_disable_index(XTTableHPtr tab, u_int ind_error); void xt_tab_set_index_error(XTTableHPtr tab); +void xt_tab_make_table_name(XTTableHPtr tab, char *table_name, size_t size); xtBool xt_tab_is_table_repair_pending(XTTableHPtr tab); void xt_tab_table_repaired(XTTableHPtr tab); void xt_tab_set_table_repair_pending(XTTableHPtr tab); diff --git a/storage/pbxt/src/thread_xt.cc b/storage/pbxt/src/thread_xt.cc index ac42896d22f..52c2c6c29c5 100644 --- a/storage/pbxt/src/thread_xt.cc +++ b/storage/pbxt/src/thread_xt.cc @@ -224,11 +224,16 @@ static void thr_log_va(XTThreadPtr self, c_char *func, c_char *file, u_int line, #else /* Use the buffer, unless it is too small */ va_list ap2; + int bufsize; va_copy(ap2, ap); - if (vsnprintf(buffer, DEFAULT_LOG_BUFFER_SIZE, fmt, ap) >= DEFAULT_LOG_BUFFER_SIZE) { - if (vasprintf(&log_string, fmt, ap2) == -1) + bufsize = vsnprintf(buffer, DEFAULT_LOG_BUFFER_SIZE, fmt, ap); + if (bufsize >= DEFAULT_LOG_BUFFER_SIZE) { + log_string = (char *) malloc(bufsize + 1); + if (vsnprintf(log_string, bufsize + 1, fmt, ap2) > bufsize) { + free(log_string); log_string = NULL; + } } else log_string = buffer; diff --git a/storage/pbxt/src/xaction_xt.cc b/storage/pbxt/src/xaction_xt.cc index 7281eafd8db..48abc5d2b66 100644 --- a/storage/pbxt/src/xaction_xt.cc +++ b/storage/pbxt/src/xaction_xt.cc @@ -1558,6 +1558,8 @@ xtPublic int xt_xn_status(XTOpenTablePtr ot, xtXactID xn_id, xtRecordID XT_UNUSE * Because we are only here because the record was valid but not * clean (you can confirm this by looking at the code that * calls this function). + * + * See {RETRY-READ} */ return XT_XN_REREAD; } @@ -1743,7 +1745,7 @@ xtPublic xtWord8 xt_xn_bytes_to_sweep(XTDatabaseHPtr db, XTThreadPtr thread) } else { xn_log_id = x_log_id; - x_log_offset = x_log_offset; + xn_log_offset = x_log_offset; } } xn_id++; diff --git a/storage/pbxt/src/xt_defs.h b/storage/pbxt/src/xt_defs.h index 4a03f941cf8..3c77415265c 100644 --- a/storage/pbxt/src/xt_defs.h +++ b/storage/pbxt/src/xt_defs.h @@ -397,6 +397,24 @@ typedef struct XTPathStr { */ #define XT_XLOG_FLUSH_FREQ 1000 +/* + * Define here if you want to check (and correct) the table free list + * counts. The free list counts are not durable, because they are not + * written to the log. + * + * The row free count is most critical because it can be used to + * estimate the the of rows in the record. + */ +#define XT_CHECK_ROW_FREE_COUNT +#ifdef DEBUG +#define XT_CHECK_RECORD_FREE_COUNT +#endif +#define XT_CORRECT_TABLE_FREE_COUNT + +#if defined(XT_CHECK_ROW_FREE_COUNT) && defined(XT_CORRECT_TABLE_FREE_COUNT) +#define XT_ROW_COUNT_CORRECTED +#endif + /* ---------------------------------------------------------------------- * GLOBAL CONSTANTS */ @@ -873,7 +891,11 @@ extern "C" void session_mark_transaction_to_rollback(Session *session, bool all) #define MX_ULONGLONG_T ulonglong #define MX_LONGLONG_T longlong #define MX_CHARSET_INFO CHARSET_INFO -#define MX_CONST_CHARSET_INFO struct charset_info_st +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID > 50200 +#define MX_CONST_CHARSET_INFO const struct charset_info_st +#else +#define MX_CONST_CHARSET_INFO struct charset_info_st +#endif #define MX_CONST #define MX_BITMAP MY_BITMAP #define MX_BIT_SIZE() n_bits diff --git a/storage/xtradb/ChangeLog b/storage/xtradb/ChangeLog index 5ebcf1e87a2..43f87a1baf5 100644 --- a/storage/xtradb/ChangeLog +++ b/storage/xtradb/ChangeLog @@ -1,3 +1,58 @@ +2010-08-24 The InnoDB Team + + * handler/ha_innodb.c, dict/dict0dict.c: + Fix Bug #55832 selects crash too easily when innodb_force_recovery>3 + +2010-08-03 The InnoDB Team + + * include/dict0dict.h, include/dict0dict.ic, row/row0mysql.c: + Fix bug #54678, InnoDB, TRUNCATE, ALTER, I_S SELECT, crash or deadlock + +2010-08-03 The InnoDB Team + + * dict/dict0load.c, handler/ha_innodb.cc, include/db0err.h, + include/dict0load.h, include/dict0mem.h, include/que0que.h, + row/row0merge.c, row/row0mysql.c: + Fix Bug#54582 stack overflow when opening many tables linked + with foreign keys at once + +2010-08-03 The InnoDB Team + + * include/ut0mem.h, ut/ut0mem.c: + Fix Bug #55627 segv in ut_free pars_lexer_close innobase_shutdown + innodb-use-sys-malloc=0 + +2010-08-01 The InnoDB Team + + * handler/ha_innodb.cc + Fix Bug #55382 Assignment with SELECT expressions takes unexpected + S locks in READ COMMITTED +>>>>>>> MERGE-SOURCE + +2010-07-27 The InnoDB Team + + * include/mem0pool.h, mem/mem0mem.c, mem/mem0pool.c, srv/srv0start.c: + Fix Bug#55581 shutdown with innodb-use-sys-malloc=0: assert + mutex->magic_n == MUTEX_MAGIC_N. + +2010-06-30 The InnoDB Team + + * btr/btr0sea.c, ha/ha0ha.c, handler/ha_innodb.cc, include/btr0sea.h: + Fix Bug#54311 Crash on CHECK PARTITION after concurrent LOAD DATA + and adaptive_hash_index=OFF + +2010-06-29 The InnoDB Team + * row/row0row.c, row/row0undo.c, row/row0upd.c: + Fix Bug#54408 txn rollback after recovery: row0umod.c:673 + dict_table_get_format(index->table) + +2010-06-29 The InnoDB Team + + * btr/btr0cur.c, include/btr0cur.h, + include/row0mysql.h, row/row0merge.c, row/row0sel.c: + Fix Bug#54358 READ UNCOMMITTED access failure of off-page DYNAMIC + or COMPRESSED columns + 2010-06-24 The InnoDB Team * handler/ha_innodb.cc: diff --git a/storage/xtradb/Makefile.am b/storage/xtradb/Makefile.am index b0b4721a9c5..abc24b0e1a4 100644 --- a/storage/xtradb/Makefile.am +++ b/storage/xtradb/Makefile.am @@ -229,9 +229,8 @@ noinst_HEADERS= \ handler/innodb_patch_info.h \ mem/mem0dbg.c -EXTRA_LIBRARIES= libxtradb.a -noinst_LIBRARIES= @plugin_xtradb_static_target@ -libxtradb_a_SOURCES= \ +noinst_LTLIBRARIES= @plugin_xtradb_static_target@ +libxtradb_la_SOURCES= \ btr/btr0btr.c \ btr/btr0cur.c \ btr/btr0pcur.c \ @@ -326,16 +325,16 @@ libxtradb_a_SOURCES= \ ut/ut0vec.c \ ut/ut0wqueue.c -libxtradb_a_CXXFLAGS= $(AM_CFLAGS) -libxtradb_a_CFLAGS= $(AM_CFLAGS) +libxtradb_la_CXXFLAGS= $(AM_CXXFLAGS) +libxtradb_la_CFLAGS= $(AM_CFLAGS) -EXTRA_LTLIBRARIES= ha_xtradb.la +EXTRA_LTLIBRARIES= libxtradb.la ha_xtradb.la pkgplugin_LTLIBRARIES= @plugin_xtradb_shared_target@ ha_xtradb_la_LDFLAGS= -module -rpath $(pkgplugindir) -ha_xtradb_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) -ha_xtradb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) -ha_xtradb_la_SOURCES= $(libxtradb_a_SOURCES) +ha_xtradb_la_CXXFLAGS= -shared $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) +ha_xtradb_la_CFLAGS= -shared $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) +ha_xtradb_la_SOURCES= $(libxtradb_la_SOURCES) EXTRA_DIST= CMakeLists.txt plug.in \ pars/make_bison.sh pars/make_flex.sh \ diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c index 9b87d969a64..3fc2b48162a 100644 --- a/storage/xtradb/btr/btr0cur.c +++ b/storage/xtradb/btr/btr0cur.c @@ -3866,9 +3866,10 @@ btr_cur_set_ownership_of_extern_field( Marks not updated extern fields as not-owned by this record. The ownership is transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. */ +to free the field. +@return TRUE if BLOB ownership was transferred */ UNIV_INTERN -void +ibool btr_cur_mark_extern_inherited_fields( /*=================================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed @@ -3882,13 +3883,14 @@ btr_cur_mark_extern_inherited_fields( ulint n; ulint j; ulint i; + ibool change_ownership = FALSE; ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); if (!rec_offs_any_extern(offsets)) { - return; + return(FALSE); } n = rec_offs_n_fields(offsets); @@ -3911,10 +3913,14 @@ btr_cur_mark_extern_inherited_fields( btr_cur_set_ownership_of_extern_field( page_zip, rec, index, offsets, i, FALSE, mtr); + + change_ownership = TRUE; updated: ; } } + + return(change_ownership); } /*******************************************************************//** @@ -5202,7 +5208,7 @@ btr_copy_externally_stored_field( /*******************************************************************//** Copies an externally stored field of a record to mem heap. -@return the field copied to heap */ +@return the field copied to heap, or NULL if the field is incomplete */ UNIV_INTERN byte* btr_rec_copy_externally_stored_field( @@ -5232,6 +5238,18 @@ btr_rec_copy_externally_stored_field( data = rec_get_nth_field(rec, offsets, no, &local_len); + ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE); + + if (UNIV_UNLIKELY + (!memcmp(data + local_len - BTR_EXTERN_FIELD_REF_SIZE, + field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE))) { + /* The externally stored field was not written yet. + This record should only be seen by + recv_recovery_rollback_active() or any + TRX_ISO_READ_UNCOMMITTED transactions. */ + return(NULL); + } + return(btr_copy_externally_stored_field(len, data, zip_size, local_len, heap)); } diff --git a/storage/xtradb/btr/btr0sea.c b/storage/xtradb/btr/btr0sea.c index 36dadd47e69..6628333d32a 100644 --- a/storage/xtradb/btr/btr0sea.c +++ b/storage/xtradb/btr/btr0sea.c @@ -46,6 +46,7 @@ Created 2/17/1996 Heikki Tuuri /** Flag: has the search system been enabled? Protected by btr_search_latch and btr_search_enabled_mutex. */ UNIV_INTERN char btr_search_enabled = TRUE; +UNIV_INTERN ibool btr_search_fully_disabled = FALSE; /** Mutex protecting btr_search_enabled */ static mutex_t btr_search_enabled_mutex; @@ -201,12 +202,19 @@ btr_search_disable(void) mutex_enter(&btr_search_enabled_mutex); rw_lock_x_lock(&btr_search_latch); + /* Disable access to hash index, also tell ha_insert_for_fold() + stop adding new nodes to hash index, but still allow updating + existing nodes */ btr_search_enabled = FALSE; /* Clear all block->is_hashed flags and remove all entries from btr_search_sys->hash_index. */ buf_pool_drop_hash_index(); + /* hash index has been cleaned up, disallow any operation to + the hash index */ + btr_search_fully_disabled = TRUE; + /* btr_search_enabled_mutex should guarantee this. */ ut_ad(!btr_search_enabled); @@ -225,6 +233,7 @@ btr_search_enable(void) rw_lock_x_lock(&btr_search_latch); btr_search_enabled = TRUE; + btr_search_fully_disabled = FALSE; rw_lock_x_unlock(&btr_search_latch); mutex_exit(&btr_search_enabled_mutex); @@ -1488,7 +1497,7 @@ btr_search_build_page_hash_index( rw_lock_x_lock(&btr_search_latch); - if (UNIV_UNLIKELY(!btr_search_enabled)) { + if (UNIV_UNLIKELY(btr_search_fully_disabled)) { goto exit_func; } @@ -1850,6 +1859,7 @@ function_exit: } } +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /********************************************************************//** Validates the search system. @return TRUE if ok */ @@ -2019,3 +2029,4 @@ btr_search_validate(void) return(ok); } +#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index 94a67c1759c..1c08bd6d0bf 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -792,7 +792,7 @@ buf_block_reuse( ptrdiff_t frame_offset) { /* block_init */ - block->frame = ((byte*)(block->frame) + frame_offset); + block->frame += frame_offset; UNIV_MEM_DESC(block->frame, UNIV_PAGE_SIZE, block); @@ -809,7 +809,7 @@ buf_block_reuse( #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ if (block->page.zip.data) - block->page.zip.data = ((byte*)(block->page.zip.data) + frame_offset); + block->page.zip.data += frame_offset; block->is_hashed = FALSE; @@ -845,6 +845,8 @@ buf_chunk_init( although it already should be. */ mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE); + srv_buffer_pool_shm_is_reused = FALSE; + if (srv_buffer_pool_shm_key) { /* zip_hash size */ zip_hash_n = (mem_size / UNIV_PAGE_SIZE) * 2; @@ -870,39 +872,46 @@ buf_chunk_init( ut_a(buf_pool->n_chunks == 1); fprintf(stderr, - "InnoDB: Notice: innodb_buffer_pool_shm_key option is specified.\n" - "InnoDB: This option may not be safe to keep consistency of datafiles.\n" - "InnoDB: Because InnoDB cannot lock datafiles when shutdown until reusing shared memory segment.\n" - "InnoDB: You should ensure no change of InnoDB files while using innodb_buffer_pool_shm_key.\n"); + "InnoDB: Warning: The innodb_buffer_pool_shm_key option has been specified.\n" + "InnoDB: Do not change the following between restarts of the server while this option is being used:\n" + "InnoDB: * the mysqld executable between restarts of the server.\n" + "InnoDB: * the value of innodb_buffer_pool_size.\n" + "InnoDB: * the value of innodb_page_size.\n" + "InnoDB: * datafiles created by InnoDB during this session.\n" + "InnoDB: Otherwise, data corruption in datafiles may result.\n"); /* FIXME: This is vague id still */ - binary_id = (ulint) ((char*)mtr_commit - (char *)btr_root_get) - + (ulint) ((char *)os_get_os_version - (char *)buf_calc_page_new_checksum) - + (ulint) ((char *)page_dir_find_owner_slot - (char *)dfield_data_is_binary_equal) - + (ulint) ((char *)que_graph_publish - (char *)dict_casedn_str) - + (ulint) ((char *)read_view_oldest_copy_or_open_new - (char *)fil_space_get_version) - + (ulint) ((char *)rec_get_n_extern_new - (char *)fsp_get_size_low) - + (ulint) ((char *)row_get_trx_id_offset - (char *)ha_create_func) - + (ulint) ((char *)srv_set_io_thread_op_info - (char *)thd_is_replication_slave_thread) - + (ulint) ((char *)mutex_create_func - (char *)ibuf_inside) - + (ulint) ((char *)trx_set_detailed_error - (char *)lock_check_trx_id_sanity) - + (ulint) ((char *)ut_time - (char *)mem_heap_strdup); + binary_id = (ulint) ((byte*)mtr_commit - (byte*)btr_root_get) + + (ulint) ((byte*)os_get_os_version - (byte*)buf_calc_page_new_checksum) + + (ulint) ((byte*)page_dir_find_owner_slot - (byte*)dfield_data_is_binary_equal) + + (ulint) ((byte*)que_graph_publish - (byte*)dict_casedn_str) + + (ulint) ((byte*)read_view_oldest_copy_or_open_new - (byte*)fil_space_get_version) + + (ulint) ((byte*)rec_get_n_extern_new - (byte*)fsp_get_size_low) + + (ulint) ((byte*)row_get_trx_id_offset - (byte*)ha_create_func) + + (ulint) ((byte*)srv_set_io_thread_op_info - (byte*)thd_is_replication_slave_thread) + + (ulint) ((byte*)mutex_create_func - (byte*)ibuf_inside) + + (ulint) ((byte*)trx_set_detailed_error - (byte*)lock_check_trx_id_sanity) + + (ulint) ((byte*)ut_time - (byte*)mem_heap_strdup); chunk->mem = os_shm_alloc(&chunk->mem_size, srv_buffer_pool_shm_key, &is_new); if (UNIV_UNLIKELY(chunk->mem == NULL)) { return(NULL); } - +init_again: #ifdef UNIV_SET_MEM_TO_ZERO if (is_new) { memset(chunk->mem, '\0', chunk->mem_size); } #endif + /* for ut_fold_binary_32(), these values should be 32-bit aligned */ + ut_a(sizeof(buf_shm_info_t) % 4 == 0); + ut_a((ulint)chunk->mem % 4 == 0); + ut_a(chunk->mem_size % 4 == 0); shm_info = chunk->mem; - zip_hash_tmp = (hash_table_t*)((char *)chunk->mem + chunk->mem_size - zip_hash_mem_size); + zip_hash_tmp = (hash_table_t*)((byte*)chunk->mem + chunk->mem_size - zip_hash_mem_size); if (is_new) { strncpy(shm_info->head_str, BUF_SHM_INFO_HEAD, 8); @@ -932,16 +941,6 @@ buf_chunk_init( "InnoDB: Error: The shared memory was not initialized yet.\n"); return(NULL); } - if (!shm_info->clean) { - fprintf(stderr, - "InnoDB: Error: The shared memory was not shut down cleanly.\n"); - return(NULL); - } - if (!shm_info->reusable) { - fprintf(stderr, - "InnoDB: Error: The shared memory has unrecoverable contents.\n"); - return(NULL); - } if (shm_info->buf_pool_size != srv_buf_pool_size) { fprintf(stderr, "InnoDB: Error: srv_buf_pool_size is different (shm=%lu current=%lu).\n", @@ -954,14 +953,34 @@ buf_chunk_init( shm_info->page_size, srv_page_size); return(NULL); } + if (!shm_info->reusable) { + fprintf(stderr, + "InnoDB: Warning: The shared memory has unrecoverable contents.\n" + "InnoDB: The shared memory segment is initialized.\n"); + is_new = TRUE; + goto init_again; + } + if (!shm_info->clean) { + fprintf(stderr, + "InnoDB: Warning: The shared memory was not shut down cleanly.\n" + "InnoDB: The shared memory segment is initialized.\n"); + is_new = TRUE; + goto init_again; + } ut_a(shm_info->zip_hash_offset == chunk->mem_size - zip_hash_mem_size); ut_a(shm_info->zip_hash_n == zip_hash_n); /* check checksum */ - checksum = ut_fold_binary((byte*)chunk->mem + sizeof(buf_shm_info_t), - chunk->mem_size - sizeof(buf_shm_info_t)); - if (shm_info->checksum != checksum) { + if (srv_buffer_pool_shm_checksum) { + checksum = ut_fold_binary_32((byte*)chunk->mem + sizeof(buf_shm_info_t), + chunk->mem_size - sizeof(buf_shm_info_t)); + } else { + checksum = BUF_NO_CHECKSUM_MAGIC; + } + + if (shm_info->checksum != BUF_NO_CHECKSUM_MAGIC + && shm_info->checksum != checksum) { fprintf(stderr, "InnoDB: Error: checksum of the shared memory is not match. " "(stored=%lu calculated=%lu)\n", @@ -979,6 +998,8 @@ buf_chunk_init( } else { /* adjust offset is done later */ hash_create_reuse(zip_hash_tmp); + + srv_buffer_pool_shm_is_reused = TRUE; } } else { chunk->mem = os_mem_alloc_large(&chunk->mem_size); @@ -992,7 +1013,7 @@ buf_chunk_init( /* Allocate the block descriptors from the start of the memory block. */ if (srv_buffer_pool_shm_key) { - chunk->blocks = (buf_block_t*)((char*)chunk->mem + sizeof(buf_shm_info_t)); + chunk->blocks = (buf_block_t*)((byte*)chunk->mem + sizeof(buf_shm_info_t)); } else { chunk->blocks = chunk->mem; } @@ -1039,10 +1060,10 @@ buf_chunk_init( } chunk->size = shm_info->chunk_backup.size; - phys_offset = (char*)frame - ((char*)chunk->mem + shm_info->frame_offset); - logi_offset = (char *)frame - (char *)chunk->blocks[0].frame; + phys_offset = frame - ((byte*)chunk->mem + shm_info->frame_offset); + logi_offset = frame - chunk->blocks[0].frame; previous_frame_address = chunk->blocks[0].frame; - blocks_offset = (char *)chunk->blocks - (char *)shm_info->chunk_backup.blocks; + blocks_offset = (byte*)chunk->blocks - (byte*)shm_info->chunk_backup.blocks; if (phys_offset || logi_offset || blocks_offset) { fprintf(stderr, @@ -1053,10 +1074,10 @@ buf_chunk_init( "InnoDB: Pysical offset : %ld (%#lx)\n" "InnoDB: Logical offset (frames) : %ld (%#lx)\n" "InnoDB: Logical offset (blocks) : %ld (%#lx)\n", - (char *)chunk->mem + shm_info->frame_offset, + (byte*)chunk->mem + shm_info->frame_offset, chunk->blocks[0].frame, frame, - (ulong) phys_offset, (ulong) phys_offset, (ulong) logi_offset, (ulong) logi_offset, - (ulong) blocks_offset, (ulong) blocks_offset); + (long) phys_offset, (ulong) phys_offset, (long) logi_offset, (ulong) logi_offset, + (long) blocks_offset, (ulong) blocks_offset); } else { fprintf(stderr, "InnoDB: Buffer pool in the shared memory segment can be used as it is.\n"); @@ -1066,24 +1087,24 @@ buf_chunk_init( fprintf(stderr, "InnoDB: Aligning physical offset..."); - memmove(frame, ((char*)chunk->mem + shm_info->frame_offset), + memmove(frame, (byte*)chunk->mem + shm_info->frame_offset, chunk->size * UNIV_PAGE_SIZE); fprintf(stderr, " Done.\n"); } + /* buf_block_t */ + block = chunk->blocks; + for (i = chunk->size; i--; ) { + buf_block_reuse(block, logi_offset); + block++; + } + if (logi_offset || blocks_offset) { fprintf(stderr, "InnoDB: Aligning logical offset..."); - /* buf_block_t */ - block = chunk->blocks; - - for (i = chunk->size; i--; ) { - buf_block_reuse(block, logi_offset); - block++; - } /* buf_pool_t buf_pool_backup */ UT_LIST_OFFSET(flush_list, buf_page_t, shm_info->buf_pool_backup.flush_list, @@ -1094,7 +1115,7 @@ buf_chunk_init( previous_frame_address, logi_offset, blocks_offset); if (shm_info->buf_pool_backup.LRU_old) shm_info->buf_pool_backup.LRU_old = - (buf_page_t*)((char*)(shm_info->buf_pool_backup.LRU_old) + (buf_page_t*)((byte*)(shm_info->buf_pool_backup.LRU_old) + (((byte*)shm_info->buf_pool_backup.LRU_old > previous_frame_address) ? logi_offset : blocks_offset)); @@ -1141,7 +1162,7 @@ buf_chunk_init( } if (shm_info) { - shm_info->frame_offset = (char*)chunk->blocks[0].frame - (char*)chunk->mem; + shm_info->frame_offset = chunk->blocks[0].frame - (byte*)chunk->mem; } return(chunk); @@ -1396,10 +1417,10 @@ buf_pool_init(void) if (srv_buffer_pool_shm_key) { buf_shm_info_t* shm_info; - ut_a((char*)chunk->blocks == (char*)chunk->mem + sizeof(buf_shm_info_t)); + ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t)); shm_info = chunk->mem; - buf_pool->zip_hash = (hash_table_t*)((char*)chunk->mem + shm_info->zip_hash_offset); + buf_pool->zip_hash = (hash_table_t*)((byte*)chunk->mem + shm_info->zip_hash_offset); if(shm_info->is_new) { shm_info->is_new = FALSE; /* initialization was finished */ @@ -1504,7 +1525,7 @@ buf_pool_free(void) chunk = buf_pool->chunks; shm_info = chunk->mem; - ut_a((char*)chunk->blocks == (char*)chunk->mem + sizeof(buf_shm_info_t)); + ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t)); /* validation the shared memory segment doesn't have unrecoverable contents. */ /* Currently, validation became not needed */ @@ -1514,8 +1535,12 @@ buf_pool_free(void) memcpy(&(shm_info->chunk_backup), chunk, sizeof(buf_chunk_t)); if (srv_fast_shutdown < 2) { - shm_info->checksum = ut_fold_binary((byte*)chunk->mem + sizeof(buf_shm_info_t), - chunk->mem_size - sizeof(buf_shm_info_t)); + if (srv_buffer_pool_shm_checksum) { + shm_info->checksum = ut_fold_binary_32((byte*)chunk->mem + sizeof(buf_shm_info_t), + chunk->mem_size - sizeof(buf_shm_info_t)); + } else { + shm_info->checksum = BUF_NO_CHECKSUM_MAGIC; + } shm_info->clean = TRUE; } diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c index 14ec1720873..94828940fd4 100644 --- a/storage/xtradb/buf/buf0lru.c +++ b/storage/xtradb/buf/buf0lru.c @@ -2228,6 +2228,26 @@ end: return(ret); } + +typedef struct { + ib_uint32_t space_id; + ib_uint32_t page_no; +} dump_record_t; + +static int dump_record_cmp(const void *a, const void *b) +{ + const dump_record_t *rec1 = (dump_record_t *) a; + const dump_record_t *rec2 = (dump_record_t *) b; + + if (rec1->space_id < rec2->space_id) + return -1; + if (rec1->space_id > rec2->space_id) + return 1; + if (rec1->page_no < rec2->page_no) + return -1; + return rec1->page_no > rec2->page_no; +} + /********************************************************************//** Read the pages based on the specific file.*/ UNIV_INTERN @@ -2245,25 +2265,34 @@ buf_LRU_file_restore(void) ulint req = 0; ibool terminated = FALSE; ibool ret = FALSE; - - buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE); - buffer = ut_align(buffer_base, UNIV_PAGE_SIZE); - if (!buffer) { - fprintf(stderr, - " InnoDB: cannot allocate buffer.\n"); - goto end; - } + dump_record_t* records= 0; + ulint size; + ulint size_high; + ulint length; dump_file = os_file_create_simple_no_error_handling( LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); - if (!success) { + if (!success || !os_file_get_size(dump_file, &size, &size_high)) { os_file_get_last_error(TRUE); fprintf(stderr, " InnoDB: cannot open %s\n", LRU_DUMP_FILE); goto end; } + if (size == 0 || size_high > 0 || size % 8) { + fprintf(stderr, " InnoDB: broken LRU dump file\n"); + goto end; + } + buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE); + buffer = ut_align(buffer_base, UNIV_PAGE_SIZE); + records = ut_malloc(size); + if (!buffer || !records) { + fprintf(stderr, + " InnoDB: cannot allocate buffer.\n"); + goto end; + } buffers = 0; + length = 0; while (!terminated) { success = os_file_read(dump_file, buffer, (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL, @@ -2272,15 +2301,14 @@ buf_LRU_file_restore(void) if (!success) { fprintf(stderr, " InnoDB: cannot read page %lu of %s," - " or meet unexpected terminal.", + " or meet unexpected terminal.\n", buffers, LRU_DUMP_FILE); goto end; } for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) { - ulint space_id, zip_size, page_no; - ulint err; - ib_int64_t tablespace_version; + ulint space_id; + ulint page_no; space_id = mach_read_from_4(buffer + offset * 4); page_no = mach_read_from_4(buffer + (offset + 1) * 4); @@ -2290,31 +2318,61 @@ buf_LRU_file_restore(void) break; } - if (offset % 16 == 15) { - os_aio_simulated_wake_handler_threads(); - buf_flush_free_margin(FALSE); + records[length].space_id = space_id; + records[length].page_no = page_no; + length++; + if (length * 8 >= size) { + fprintf(stderr, + " InnoDB: could not find the " + "end-of-file marker after reading " + "the expected %lu bytes from the " + "LRU dump file.\n" + " InnoDB: this could be caused by a " + "broken or incomplete file.\n" + " InnoDB: trying to process what has " + "been read so far.\n", + size); + terminated= TRUE; + break; } + } + buffers++; + } - zip_size = fil_space_get_zip_size(space_id); - if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) { - continue; - } + qsort(records, length, sizeof(dump_record_t), dump_record_cmp); - if (fil_area_is_exist(space_id, zip_size, page_no, 0, - zip_size ? zip_size : UNIV_PAGE_SIZE)) { + for (offset = 0; offset < length; offset++) { + ulint space_id; + ulint page_no; + ulint zip_size; + ulint err; + ib_int64_t tablespace_version; - tablespace_version = fil_space_get_version(space_id); + space_id = records[offset].space_id; + page_no = records[offset].page_no; - req++; - reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE - | OS_AIO_SIMULATED_WAKE_LATER, - space_id, zip_size, TRUE, - tablespace_version, page_no, NULL); - buf_LRU_stat_inc_io(); - } + if (offset % 16 == 15) { + os_aio_simulated_wake_handler_threads(); + buf_flush_free_margin(FALSE); } - buffers++; + zip_size = fil_space_get_zip_size(space_id); + if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) { + continue; + } + + if (fil_area_is_exist(space_id, zip_size, page_no, 0, + zip_size ? zip_size : UNIV_PAGE_SIZE)) { + + tablespace_version = fil_space_get_version(space_id); + + req++; + reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE + | OS_AIO_SIMULATED_WAKE_LATER, + space_id, zip_size, TRUE, + tablespace_version, page_no, NULL); + buf_LRU_stat_inc_io(); + } } os_aio_simulated_wake_handler_threads(); @@ -2330,6 +2388,8 @@ end: os_file_close(dump_file); if (buffer_base) ut_free(buffer_base); + if (records) + ut_free(records); return(ret); } diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c index 258bf77d1fc..a6d0e11740a 100644 --- a/storage/xtradb/dict/dict0crea.c +++ b/storage/xtradb/dict/dict0crea.c @@ -1245,13 +1245,13 @@ dict_create_index_step( goto function_exit; } - if (srv_use_sys_stats_table) { + if (srv_use_sys_stats_table + && !((node->table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY)) { node->state = INDEX_BUILD_STATS_COLS; } else { node->state = INDEX_CREATE_INDEX_TREE; } } - if (node->state == INDEX_BUILD_STATS_COLS) { if (node->stats_no <= dict_index_get_n_unique(node->index)) { diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c index 51ee7f9246f..1d0517f5cc7 100644 --- a/storage/xtradb/dict/dict0dict.c +++ b/storage/xtradb/dict/dict0dict.c @@ -569,8 +569,7 @@ dict_table_get_on_id( { dict_table_t* table; - if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 - || trx->dict_operation_lock_mode == RW_X_LATCH) { + if (trx->dict_operation_lock_mode == RW_X_LATCH) { /* Note: An X latch implies that the transaction already owns the dictionary mutex. */ @@ -4514,7 +4513,6 @@ dict_update_statistics_low( ibool sync) /*!< in: TRUE if must update SYS_STATS */ { dict_index_t* index; - ulint size; ulint sum_of_index_sizes = 0; if (table->ibd_file_missing) { @@ -4529,15 +4527,7 @@ dict_update_statistics_low( return; } - /* If we have set a high innodb_force_recovery level, do not calculate - statistics, as a badly corrupted index can cause a crash in it. */ - - if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - - return; - } - - if (srv_use_sys_stats_table && !sync) { + if (srv_use_sys_stats_table && !((table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY) && !sync) { /* reload statistics from SYS_STATS table */ if (dict_reload_statistics(table, &sum_of_index_sizes)) { /* success */ @@ -4565,33 +4555,54 @@ dict_update_statistics_low( return; } - while (index) { + do { if (table->is_corrupt) { ut_a(srv_pass_corrupt_table); return; } - size = btr_get_size(index, BTR_TOTAL_SIZE); + if (UNIV_LIKELY + (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE + || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO + && dict_index_is_clust(index)))) { + ulint size; + size = btr_get_size(index, BTR_TOTAL_SIZE); - index->stat_index_size = size; + index->stat_index_size = size; - sum_of_index_sizes += size; + sum_of_index_sizes += size; - size = btr_get_size(index, BTR_N_LEAF_PAGES); + size = btr_get_size(index, BTR_N_LEAF_PAGES); - if (size == 0) { - /* The root node of the tree is a leaf */ - size = 1; - } + if (size == 0) { + /* The root node of the tree is a leaf */ + size = 1; + } - index->stat_n_leaf_pages = size; + index->stat_n_leaf_pages = size; + + btr_estimate_number_of_different_key_vals(index); + } else { + /* If we have set a high innodb_force_recovery + level, do not calculate statistics, as a badly + corrupted index can cause a crash in it. + Initialize some bogus index cardinality + statistics, so that the data can be queried in + various means, also via secondary indexes. */ + ulint i; + + sum_of_index_sizes++; + index->stat_index_size = index->stat_n_leaf_pages = 1; - btr_estimate_number_of_different_key_vals(index); + for (i = dict_index_get_n_unique(index); i; ) { + index->stat_n_diff_key_vals[i--] = 1; + } + } index = dict_table_get_next_index(index); - } + } while (index); - if (srv_use_sys_stats_table) { + if (srv_use_sys_stats_table && !((table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY)) { /* store statistics to SYS_STATS table */ dict_store_statistics(table); } diff --git a/storage/xtradb/dict/dict0load.c b/storage/xtradb/dict/dict0load.c index 0d8292cc2bf..43c0810fe67 100644 --- a/storage/xtradb/dict/dict0load.c +++ b/storage/xtradb/dict/dict0load.c @@ -1010,16 +1010,27 @@ err_exit: err = dict_load_indexes(table, heap); + /* Initialize table foreign_child value. Its value could be + changed when dict_load_foreigns() is called below */ + table->fk_max_recusive_level = 0; + /* If the force recovery flag is set, we open the table irrespective of the error condition, since the user may want to dump data from the clustered index. However we load the foreign key information only if all indexes were loaded. */ if (err == DB_SUCCESS) { - err = dict_load_foreigns(table->name, TRUE); + err = dict_load_foreigns(table->name, TRUE, TRUE); + + if (err != DB_SUCCESS) { + dict_table_remove_from_cache(table); + table = NULL; + } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } + + table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { @@ -1073,6 +1084,8 @@ dict_load_table_on_id( ut_ad(mutex_own(&(dict_sys->mutex))); + table = NULL; + /* NOTE that the operation of this function is protected by the dictionary mutex, and therefore no deadlocks can occur with other dictionary operations. */ @@ -1099,15 +1112,17 @@ dict_load_table_on_id( BTR_SEARCH_LEAF, &pcur, &mtr); rec = btr_pcur_get_rec(&pcur); - if (!btr_pcur_is_on_user_rec(&pcur) - || rec_get_deleted_flag(rec, 0)) { + if (!btr_pcur_is_on_user_rec(&pcur)) { /* Not found */ + goto func_exit; + } - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap); - - return(NULL); + /* Find the first record that is not delete marked */ + while (rec_get_deleted_flag(rec, 0)) { + if (!btr_pcur_move_to_next_user_rec(&pcur, &mtr)) { + goto func_exit; + } + rec = btr_pcur_get_rec(&pcur); } /*---------------------------------------------------*/ @@ -1120,19 +1135,14 @@ dict_load_table_on_id( /* Check if the table id in record is the one searched for */ if (ut_dulint_cmp(table_id, mach_read_from_8(field)) != 0) { - - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap); - - return(NULL); + goto func_exit; } /* Now we get the table name from the record */ field = rec_get_nth_field_old(rec, 1, &len); /* Load the table definition to memory */ table = dict_load_table(mem_heap_strdupl(heap, (char*) field, len)); - +func_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); @@ -1242,8 +1252,12 @@ dict_load_foreign( /*==============*/ const char* id, /*!< in: foreign constraint id as a null-terminated string */ - ibool check_charsets) + ibool check_charsets, /*!< in: TRUE=check charset compatibility */ + ibool check_recursive) + /*!< in: Whether to record the foreign table + parent count to avoid unlimited recursive + load of chained foreign tables */ { dict_foreign_t* foreign; dict_table_t* sys_foreign; @@ -1257,6 +1271,8 @@ dict_load_foreign( ulint len; ulint n_fields_and_type; mtr_t mtr; + dict_table_t* for_table; + dict_table_t* ref_table; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1341,11 +1357,54 @@ dict_load_foreign( dict_load_foreign_cols(id, foreign); - /* If the foreign table is not yet in the dictionary cache, we - have to load it so that we are able to make type comparisons - in the next function call. */ - - dict_table_get_low(foreign->foreign_table_name); + ref_table = dict_table_check_if_in_cache_low( + foreign->referenced_table_name); + + /* We could possibly wind up in a deep recursive calls if + we call dict_table_get_low() again here if there + is a chain of tables concatenated together with + foreign constraints. In such case, each table is + both a parent and child of the other tables, and + act as a "link" in such table chains. + To avoid such scenario, we would need to check the + number of ancesters the current table has. If that + exceeds DICT_FK_MAX_CHAIN_LEN, we will stop loading + the child table. + Foreign constraints are loaded in a Breath First fashion, + that is, the index on FOR_NAME is scanned first, and then + index on REF_NAME. So foreign constrains in which + current table is a child (foreign table) are loaded first, + and then those constraints where current table is a + parent (referenced) table. + Thus we could check the parent (ref_table) table's + reference count (fk_max_recusive_level) to know how deep the + recursive call is. If the parent table (ref_table) is already + loaded, and its fk_max_recusive_level is larger than + DICT_FK_MAX_CHAIN_LEN, we will stop the recursive loading + by skipping loading the child table. It will not affect foreign + constraint check for DMLs since child table will be loaded + at that time for the constraint check. */ + if (!ref_table + || ref_table->fk_max_recusive_level < DICT_FK_MAX_RECURSIVE_LOAD) { + + /* If the foreign table is not yet in the dictionary cache, we + have to load it so that we are able to make type comparisons + in the next function call. */ + + for_table = dict_table_get_low(foreign->foreign_table_name); + + if (for_table && ref_table && check_recursive) { + /* This is to record the longest chain of ancesters + this table has, if the parent has more ancesters + than this table has, record it after add 1 (for this + parent */ + if (ref_table->fk_max_recusive_level + >= for_table->fk_max_recusive_level) { + for_table->fk_max_recusive_level = + ref_table->fk_max_recusive_level + 1; + } + } + } /* Note that there may already be a foreign constraint object in the dictionary cache for this constraint: then the following @@ -1370,6 +1429,8 @@ ulint dict_load_foreigns( /*===============*/ const char* table_name, /*!< in: table name */ + ibool check_recursive,/*!< in: Whether to check recursive + load of tables chained by FK */ ibool check_charsets) /*!< in: TRUE=check charset compatibility */ { @@ -1471,7 +1532,7 @@ loop: /* Load the foreign constraint definition to the dictionary cache */ - err = dict_load_foreign(id, check_charsets); + err = dict_load_foreign(id, check_charsets, check_recursive); if (err != DB_SUCCESS) { btr_pcur_close(&pcur); @@ -1499,6 +1560,11 @@ load_next_index: mtr_start(&mtr); + /* Switch to scan index on REF_NAME, fk_max_recusive_level + already been updated when scanning FOR_NAME index, no need to + update again */ + check_recursive = FALSE; + goto start_load; } diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c index e9dc8185be6..cae91d4037c 100644 --- a/storage/xtradb/fil/fil0fil.c +++ b/storage/xtradb/fil/fil0fil.c @@ -3043,6 +3043,10 @@ fil_open_single_table_tablespace( if (srv_expand_import && (space_id != id || space_flags != (flags & ~(~0 << DICT_TF_BITS)))) { + ibool file_is_corrupt = FALSE; + byte* buf3; + byte* descr_page; + ibool descr_is_corrupt = FALSE; dulint old_id[31]; dulint new_id[31]; ulint root_page[31]; @@ -3052,16 +3056,37 @@ fil_open_single_table_tablespace( ulint i; int len; ib_uint64_t current_lsn; - ulint size_low, size_high, size; - ib_int64_t size_bytes; + ulint size_low, size_high, size, free_limit; + ib_int64_t size_bytes, free_limit_bytes; dict_table_t* table; dict_index_t* index; fil_system_t* system; fil_node_t* node = NULL; fil_space_t* space; + buf3 = ut_malloc(2 * UNIV_PAGE_SIZE); + descr_page = ut_align(buf3, UNIV_PAGE_SIZE); + current_lsn = log_get_lsn(); + /* check the header page's consistency */ + if (buf_page_is_corrupted(page, + dict_table_flags_to_zip_size(space_flags))) { + fprintf(stderr, "InnoDB: page 0 of %s seems corrupt.\n", filepath); + file_is_corrupt = TRUE; + descr_is_corrupt = TRUE; + } + + /* store as first descr page */ + memcpy(descr_page, page, UNIV_PAGE_SIZE); + + /* get free limit (page number) of the table space */ +/* these should be same to the definition in fsp0fsp.c */ +#define FSP_HEADER_OFFSET FIL_PAGE_DATA +#define FSP_FREE_LIMIT 12 + free_limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT + page); + free_limit_bytes = (ib_int64_t)free_limit * (ib_int64_t)UNIV_PAGE_SIZE; + /* overwrite fsp header */ fsp_header_init_fields(page, id, flags); mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id); @@ -3086,6 +3111,12 @@ fil_open_single_table_tablespace( size_bytes = (((ib_int64_t)size_high) << 32) + (ib_int64_t)size_low; + if (size_bytes < free_limit_bytes) { + free_limit_bytes = size_bytes; + fprintf(stderr, "InnoDB: free limit of %s is larger than its real size.\n", filepath); + file_is_corrupt = TRUE; + } + /* get cruster index information */ table = dict_table_get_low(name); index = dict_table_get_first_index(table); @@ -3107,16 +3138,19 @@ fil_open_single_table_tablespace( info_file_path, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); if (!success) { fprintf(stderr, "InnoDB: cannot open %s\n", info_file_path); + file_is_corrupt = TRUE; goto skip_info; } success = os_file_read(info_file, page, 0, 0, UNIV_PAGE_SIZE); if (!success) { fprintf(stderr, "InnoDB: cannot read %s\n", info_file_path); + file_is_corrupt = TRUE; goto skip_info; } if (mach_read_from_4(page) != 0x78706f72UL || mach_read_from_4(page + 4) != 0x74696e66UL) { fprintf(stderr, "InnoDB: %s seems not to be a correct .exp file\n", info_file_path); + file_is_corrupt = TRUE; goto skip_info; } @@ -3153,20 +3187,29 @@ skip_info: fprintf(stderr, "InnoDB: Progress in %%:"); - for (offset = 0; offset < size_bytes; offset += UNIV_PAGE_SIZE) { + for (offset = 0; offset < free_limit_bytes; offset += UNIV_PAGE_SIZE) { ulint checksum_field; ulint old_checksum_field; + ibool page_is_corrupt; success = os_file_read(file, page, (ulint)(offset & 0xFFFFFFFFUL), (ulint)(offset >> 32), UNIV_PAGE_SIZE); - /* skip inconsistent pages, it may be free page. */ + page_is_corrupt = FALSE; + + /* check consistency */ if (memcmp(page + FIL_PAGE_LSN + 4, page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) { - goto skip_write; + page_is_corrupt = TRUE; + } + + if (mach_read_from_4(page + FIL_PAGE_OFFSET) + != offset / UNIV_PAGE_SIZE) { + + page_is_corrupt = TRUE; } checksum_field = mach_read_from_4(page @@ -3182,7 +3225,7 @@ skip_info: && old_checksum_field != buf_calc_page_old_checksum(page)) { - goto skip_write; + page_is_corrupt = TRUE; } if (!srv_fast_checksum @@ -3191,7 +3234,7 @@ skip_info: && checksum_field != buf_calc_page_new_checksum(page)) { - goto skip_write; + page_is_corrupt = TRUE; } if (srv_fast_checksum @@ -3202,6 +3245,77 @@ skip_info: && checksum_field != buf_calc_page_new_checksum(page)) { + page_is_corrupt = TRUE; + } + + /* if it is free page, inconsistency is acceptable */ + if (!offset) { + /* header page*/ + /* it should be overwritten already */ + ut_a(!page_is_corrupt); + + } else if (!((offset / UNIV_PAGE_SIZE) % UNIV_PAGE_SIZE)) { + /* descr page (not header) */ + if (page_is_corrupt) { + file_is_corrupt = TRUE; + descr_is_corrupt = TRUE; + } else { + ut_a(fil_page_get_type(page) == FIL_PAGE_TYPE_XDES); + descr_is_corrupt = FALSE; + } + + /* store as descr page */ + memcpy(descr_page, page, UNIV_PAGE_SIZE); + + } else if (descr_is_corrupt) { + /* unknown state of the page */ + if (page_is_corrupt) { + file_is_corrupt = TRUE; + } + + } else { + /* check free page or not */ + /* These definitions should be same to fsp0fsp.c */ +#define FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE) + +#define XDES_BITMAP (FLST_NODE_SIZE + 12) +#define XDES_BITS_PER_PAGE 2 +#define XDES_FREE_BIT 0 +#define XDES_SIZE \ + (XDES_BITMAP + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE)) +#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) + + /*descr = descr_page + XDES_ARR_OFFSET + XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset)*/ + /*xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)*/ + byte* descr; + ulint index; + ulint byte_index; + ulint bit_index; + + descr = descr_page + XDES_ARR_OFFSET + + XDES_SIZE * (ut_2pow_remainder((offset / UNIV_PAGE_SIZE), UNIV_PAGE_SIZE) / FSP_EXTENT_SIZE); + + index = XDES_FREE_BIT + XDES_BITS_PER_PAGE * ((offset / UNIV_PAGE_SIZE) % FSP_EXTENT_SIZE); + byte_index = index / 8; + bit_index = index % 8; + + if (ut_bit_get_nth(mach_read_from_1(descr + XDES_BITMAP + byte_index), bit_index)) { + /* free page */ + if (page_is_corrupt) { + goto skip_write; + } + } else { + /* not free */ + if (page_is_corrupt) { + file_is_corrupt = TRUE; + } + } + } + + if (page_is_corrupt) { + fprintf(stderr, " [errp:%lld]", offset / UNIV_PAGE_SIZE); + + /* cannot treat corrupt page */ goto skip_write; } @@ -3294,11 +3408,11 @@ skip_info: } skip_write: - if (size_bytes - && ((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / size_bytes) - != ((offset * 100) / size_bytes)) { + if (free_limit_bytes + && ((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / free_limit_bytes) + != ((offset * 100) / free_limit_bytes)) { fprintf(stderr, " %lu", - (ulong)((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / size_bytes)); + (ulong)((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / free_limit_bytes)); } } @@ -3379,6 +3493,26 @@ skip_write: node->size = size; } mutex_exit(&(system->mutex)); + + ut_free(buf3); + + if (file_is_corrupt) { + ut_print_timestamp(stderr); + fputs(" InnoDB: Error: file ", + stderr); + ut_print_filename(stderr, filepath); + fprintf(stderr, " seems to be corrupt.\n" + "InnoDB: anyway, all not corrupt pages were tried to be converted to salvage.\n" + "InnoDB: ##### CAUTION #####\n" + "InnoDB: ## The .ibd must cause to crash InnoDB, though re-import would seem to be succeeded.\n" + "InnoDB: ## If you don't have knowledge about salvaging data from .ibd, you should not use the file.\n" + "InnoDB: ###################\n"); + success = FALSE; + + ut_free(buf2); + + goto func_exit; + } } ut_free(buf2); diff --git a/storage/xtradb/ha/ha0ha.c b/storage/xtradb/ha/ha0ha.c index 9d9d341ad39..7f11917de0a 100644 --- a/storage/xtradb/ha/ha0ha.c +++ b/storage/xtradb/ha/ha0ha.c @@ -31,9 +31,7 @@ Created 8/22/1994 Heikki Tuuri #ifdef UNIV_DEBUG # include "buf0buf.h" #endif /* UNIV_DEBUG */ -#ifdef UNIV_SYNC_DEBUG -# include "btr0sea.h" -#endif /* UNIV_SYNC_DEBUG */ +#include "btr0sea.h" #include "page0page.h" /*************************************************************//** @@ -127,7 +125,8 @@ ha_clear( /*************************************************************//** Inserts an entry into a hash table. If an entry with the same fold number is found, its node is updated to point to the new data, and no new node -is inserted. +is inserted. If btr_search_enabled is set to FALSE, we will only allow +updating existing nodes, but no new node is allowed to be added. @return TRUE if succeed, FALSE if no more memory could be allocated */ UNIV_INTERN ibool @@ -174,6 +173,7 @@ ha_insert_for_fold_func( prev_block->n_pointers--; block->n_pointers++; } + ut_ad(!btr_search_fully_disabled); # endif /* !UNIV_HOTBACKUP */ prev_node->block = block; @@ -186,6 +186,13 @@ ha_insert_for_fold_func( prev_node = prev_node->next; } + /* We are in the process of disabling hash index, do not add + new chain node */ + if (!btr_search_enabled) { + ut_ad(!btr_search_fully_disabled); + return(TRUE); + } + /* We have to allocate a new chain node */ node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t)); @@ -347,6 +354,7 @@ ha_remove_all_nodes_to_page( #endif } +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /*************************************************************//** Validates a given range of the cells in hash table. @return TRUE if ok */ @@ -393,6 +401,7 @@ ha_validate( return(ok); } +#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ /*************************************************************//** Prints info of a hash table. */ diff --git a/storage/xtradb/ha/hash0hash.c b/storage/xtradb/ha/hash0hash.c index 70516deb005..0f4fc55d895 100644 --- a/storage/xtradb/ha/hash0hash.c +++ b/storage/xtradb/ha/hash0hash.c @@ -161,7 +161,7 @@ hash_create_init( offset = (sizeof(hash_table_t) + 7) / 8; offset *= 8; - table->array = (hash_cell_t*)(((char*)table) + offset); + table->array = (hash_cell_t*)(((byte*)table) + offset); table->n_cells = prime; # if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG table->adaptive = FALSE; @@ -187,7 +187,7 @@ hash_create_reuse( offset = (sizeof(hash_table_t) + 7) / 8; offset *= 8; - table->array = (hash_cell_t*)(((char*)table) + offset); + table->array = (hash_cell_t*)(((byte*)table) + offset); ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 602fbd59517..9e634a07ad4 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -194,6 +194,7 @@ static my_bool innobase_rollback_on_timeout = FALSE; static my_bool innobase_create_status_file = FALSE; static my_bool innobase_stats_on_metadata = TRUE; static my_bool innobase_use_sys_stats_table = FALSE; +static my_bool innobase_buffer_pool_shm_checksum = TRUE; static char* internal_innobase_data_file_path = NULL; @@ -812,6 +813,19 @@ convert_error_code_to_mysql( case DB_INTERRUPTED: my_error(ER_QUERY_INTERRUPTED, MYF(0)); /* fall through */ + + case DB_FOREIGN_EXCEED_MAX_CASCADE: + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_ROW_IS_REFERENCED, + "InnoDB: Cannot delete/update " + "rows with cascading foreign key " + "constraints that exceed max " + "depth of %d. Please " + "drop extra constraints and try " + "again", DICT_FK_MAX_RECURSIVE_LOAD); + + /* fall through */ + case DB_ERROR: default: return(-1); /* unspecified error */ @@ -2413,6 +2427,7 @@ innobase_change_buffering_inited_ok: srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite; srv_use_checksums = (ibool) innobase_use_checksums; srv_fast_checksum = (ibool) innobase_fast_checksum; + srv_buffer_pool_shm_checksum = (ibool) innobase_buffer_pool_shm_checksum; #ifdef HAVE_LARGE_PAGES if ((os_use_large_pages = (ibool) my_use_large_pages)) @@ -2549,6 +2564,7 @@ skip_overwrite: /* Get the current high water mark format. */ innobase_file_format_check = (char*) trx_sys_file_format_max_get(); + btr_search_fully_disabled = (!btr_search_enabled); DBUG_RETURN(FALSE); error: DBUG_RETURN(TRUE); @@ -3648,12 +3664,19 @@ ha_innobase::innobase_initialize_autoinc() err = row_search_max_autoinc(index, col_name, &read_auto_inc); switch (err) { - case DB_SUCCESS: + case DB_SUCCESS: { + ulonglong col_max_value; + + col_max_value = innobase_get_int_col_max_value(field); + /* At the this stage we do not know the increment - or the offset, so use a default increment of 1. */ - auto_inc = read_auto_inc + 1; - break; + nor the offset, so use a default increment of 1. */ + auto_inc = innobase_next_autoinc( + read_auto_inc, 1, 1, col_max_value); + + break; + } case DB_RECORD_NOT_FOUND: ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: MySQL and InnoDB data " @@ -3966,8 +3989,6 @@ retry: dict_table_get_format(prebuilt->table)); } - info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); - /* Only if the table has an AUTOINC column. */ if (prebuilt->table != NULL && table->found_next_number_field != NULL) { dict_table_autoinc_lock(prebuilt->table); @@ -3984,6 +4005,8 @@ retry: dict_table_autoinc_unlock(prebuilt->table); } + info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); + DBUG_RETURN(0); } @@ -7911,28 +7934,15 @@ ha_innobase::info( dict_index_t* index; ha_rows rec_per_key; ib_int64_t n_rows; - ulong j; - ulong i; char path[FN_REFLEN]; os_file_stat_t stat_info; - DBUG_ENTER("info"); /* If we are forcing recovery at a high level, we will suppress statistics calculation on tables, because that may crash the server if an index is badly corrupted. */ - if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - - /* We return success (0) instead of HA_ERR_CRASHED, - because we want MySQL to process this query and not - stop, like it would do if it received the error code - HA_ERR_CRASHED. */ - - DBUG_RETURN(0); - } - /* We do not know if MySQL can call this function before calling external_lock(). To be safe, update the thd of the current table handle. */ @@ -7955,7 +7965,7 @@ ha_innobase::info( /* In sql_show we call with this flag: update then statistics so that they are up-to-date */ - if (srv_use_sys_stats_table + if (srv_use_sys_stats_table && !((ib_table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY) && thd_sql_command(user_thd) == SQLCOM_ANALYZE) { /* If the indexes on the table don't have enough rows in SYS_STATS system table, */ /* they need to be created. */ @@ -8050,11 +8060,18 @@ ha_innobase::info( acquiring latches inside InnoDB, we do not call it if we are asked by MySQL to avoid locking. Another reason to avoid the call is that it uses quite a lot of CPU. - See Bug#38185. - We do not update delete_length if no locking is requested - so the "old" value can remain. delete_length is initialized - to 0 in the ha_statistics' constructor. */ - if (!(flag & HA_STATUS_NO_LOCK) && srv_stats_update_need_lock) { + See Bug#38185. */ + if (flag & HA_STATUS_NO_LOCK) { + /* We do not update delete_length if no + locking is requested so the "old" value can + remain. delete_length is initialized to 0 in + the ha_statistics' constructor. */ + } else if (UNIV_UNLIKELY + (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) { + /* Avoid accessing the tablespace if + innodb_crash_recovery is set to a high value. */ + stats.delete_length = 0; + } else if (srv_stats_update_need_lock) { /* lock the data dictionary to avoid races with ibd_file_missing and tablespace_discarded */ @@ -8100,6 +8117,7 @@ ha_innobase::info( } if (flag & HA_STATUS_CONST) { + ulong i; /* Verify the number of index in InnoDB and MySQL matches up. If prebuilt->clust_index_was_generated holds, InnoDB defines GEN_CLUST_INDEX internally */ @@ -8116,6 +8134,7 @@ ha_innobase::info( } for (i = 0; i < table->s->keys; i++) { + ulong j; /* We could get index quickly through internal index mapping with the index translation table. The identity of index (match up index name with @@ -8181,6 +8200,11 @@ ha_innobase::info( } } + if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { + + goto func_exit; + } + if (flag & HA_STATUS_ERRKEY) { const dict_index_t* err_index; @@ -8201,6 +8225,7 @@ ha_innobase::info( stats.auto_increment_value = innobase_peek_autoinc(); } +func_exit: prebuilt->trx->op_info = (char*)""; DBUG_RETURN(0); @@ -9691,7 +9716,8 @@ ha_innobase::store_lock( && (sql_command == SQLCOM_INSERT_SELECT || sql_command == SQLCOM_REPLACE_SELECT || sql_command == SQLCOM_UPDATE - || sql_command == SQLCOM_CREATE_TABLE)) { + || sql_command == SQLCOM_CREATE_TABLE + || sql_command == SQLCOM_SET_OPTION)) { /* If we either have innobase_locks_unsafe_for_binlog option set or this session is using READ COMMITTED @@ -9699,9 +9725,9 @@ ha_innobase::store_lock( is not set to serializable and MySQL is doing INSERT INTO...SELECT or REPLACE INTO...SELECT or UPDATE ... = (SELECT ...) or CREATE ... - SELECT... without FOR UPDATE or IN SHARE - MODE in select, then we use consistent read - for select. */ + SELECT... or SET ... = (SELECT ...) without + FOR UPDATE or IN SHARE MODE in select, + then we use consistent read for select. */ prebuilt->select_lock_type = LOCK_NONE; prebuilt->stored_select_lock_type = LOCK_NONE; @@ -11359,9 +11385,14 @@ static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size, static MYSQL_SYSVAR_UINT(buffer_pool_shm_key, srv_buffer_pool_shm_key, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "[experimental] The key value of shared memory segment for the buffer pool. 0 means disable the feature (default).", + "[experimental] The key value of shared memory segment for the buffer pool. 0 (default) disables the feature.", NULL, NULL, 0, 0, INT_MAX32, 0); +static MYSQL_SYSVAR_BOOL(buffer_pool_shm_checksum, innobase_buffer_pool_shm_checksum, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "Enable buffer_pool_shm checksum validation (enabled by default).", + NULL, NULL, TRUE); + static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency, PLUGIN_VAR_RQCMDARG, "Helps in performance tuning in heavily concurrent environments.", @@ -11608,6 +11639,12 @@ static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit, "Limit the allocated memory for dictionary cache. (0: unlimited)", NULL, NULL, 0, 0, LONG_MAX, 0); +static MYSQL_SYSVAR_UINT(auto_lru_dump, srv_auto_lru_dump, + PLUGIN_VAR_RQCMDARG, + "Time in seconds between automatic buffer pool dumps. " + "0 (the default) disables automatic dumps.", + NULL, NULL, 0, 0, UINT_MAX32, 0); + static MYSQL_SYSVAR_ULINT(pass_corrupt_table, srv_pass_corrupt_table, PLUGIN_VAR_RQCMDARG, "Pass corruptions of user tables as 'corrupt table' instead of not crashing itself, " @@ -11622,6 +11659,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(autoextend_increment), MYSQL_SYSVAR(buffer_pool_size), MYSQL_SYSVAR(buffer_pool_shm_key), + MYSQL_SYSVAR(buffer_pool_shm_checksum), MYSQL_SYSVAR(checksums), MYSQL_SYSVAR(fast_checksum), MYSQL_SYSVAR(commit_concurrency), @@ -11699,6 +11737,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(change_buffering), MYSQL_SYSVAR(read_ahead_threshold), MYSQL_SYSVAR(io_capacity), + MYSQL_SYSVAR(auto_lru_dump), MYSQL_SYSVAR(use_purge_thread), MYSQL_SYSVAR(pass_corrupt_table), NULL diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h index 716f15c4267..e151fdcb563 100644 --- a/storage/xtradb/include/btr0cur.h +++ b/storage/xtradb/include/btr0cur.h @@ -468,9 +468,10 @@ btr_estimate_number_of_different_key_vals( Marks not updated extern fields as not-owned by this record. The ownership is transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. */ +to free the field. +@return TRUE if BLOB ownership was transferred */ UNIV_INTERN -void +ibool btr_cur_mark_extern_inherited_fields( /*=================================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed @@ -570,7 +571,7 @@ btr_copy_externally_stored_field_prefix( ulint local_len);/*!< in: length of data, in bytes */ /*******************************************************************//** Copies an externally stored field of a record to mem heap. -@return the field copied to heap */ +@return the field copied to heap, or NULL if the field is incomplete */ UNIV_INTERN byte* btr_rec_copy_externally_stored_field( diff --git a/storage/xtradb/include/btr0sea.h b/storage/xtradb/include/btr0sea.h index 7f4842d0897..f6d194319ae 100644 --- a/storage/xtradb/include/btr0sea.h +++ b/storage/xtradb/include/btr0sea.h @@ -187,6 +187,7 @@ btr_search_update_hash_on_delete( btr_cur_t* cursor);/*!< in: cursor which was positioned on the record to delete using btr_cur_search_..., the record is not yet deleted */ +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /********************************************************************//** Validates the search system. @return TRUE if ok */ @@ -194,10 +195,19 @@ UNIV_INTERN ibool btr_search_validate(void); /*======================*/ +#else +# define btr_search_validate() TRUE +#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ /** Flag: has the search system been enabled? Protected by btr_search_latch and btr_search_enabled_mutex. */ -extern char btr_search_enabled; +extern char btr_search_enabled; + +/** Flag: whether the search system has completed its disabling process, +It is set to TRUE right after buf_pool_drop_hash_index() in +btr_search_disable(), indicating hash index entries are cleaned up. +Protected by btr_search_latch and btr_search_enabled_mutex. */ +extern ibool btr_search_fully_disabled; /** The search info struct in an index */ struct btr_search_struct{ diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h index a7854e3038d..e06927f42f0 100644 --- a/storage/xtradb/include/buf0buf.h +++ b/storage/xtradb/include/buf0buf.h @@ -1305,7 +1305,7 @@ Compute the hash fold value for blocks in buf_pool->zip_hash. */ /* the fold should be relative when srv_buffer_pool_shm_key is enabled */ #define BUF_POOL_ZIP_FOLD_PTR(ptr) (!srv_buffer_pool_shm_key\ ?((ulint) (ptr) / UNIV_PAGE_SIZE)\ - :((ulint) ((char*)ptr - (char*)(buf_pool->chunks->blocks->frame)) / UNIV_PAGE_SIZE)) + :((ulint) ((byte*)ptr - (byte*)(buf_pool->chunks->blocks->frame)) / UNIV_PAGE_SIZE)) #define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame) #define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b)) /* @} */ diff --git a/storage/xtradb/include/db0err.h b/storage/xtradb/include/db0err.h index c841c2b4afe..c7fa6d2a444 100644 --- a/storage/xtradb/include/db0err.h +++ b/storage/xtradb/include/db0err.h @@ -94,6 +94,9 @@ enum db_err { DB_PRIMARY_KEY_IS_NULL, /* a column in the PRIMARY KEY was found to be NULL */ + DB_FOREIGN_EXCEED_MAX_CASCADE, /* Foreign key constraint related + cascading delete/update exceeds + maximum allowed depth */ /* The following are partial failure codes */ DB_FAIL = 1000, diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index 3c5e620d3c1..d18b3ecb1b0 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -680,6 +680,22 @@ ulint dict_table_zip_size( /*================*/ const dict_table_t* table); /*!< in: table */ +/*********************************************************************//** +Obtain exclusive locks on all index trees of the table. This is to prevent +accessing index trees while InnoDB is updating internal metadata for +operations such as truncate tables. */ +UNIV_INLINE +void +dict_table_x_lock_indexes( +/*======================*/ + dict_table_t* table); /*!< in: table */ +/*********************************************************************//** +Release the exclusive locks on all index tree. */ +UNIV_INLINE +void +dict_table_x_unlock_indexes( +/*========================*/ + dict_table_t* table); /*!< in: table */ /********************************************************************//** Checks if a column is in the ordering columns of the clustered index of a table. Column prefixes are treated like whole columns. diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic index aada3096261..bd7534dc7e2 100644 --- a/storage/xtradb/include/dict0dict.ic +++ b/storage/xtradb/include/dict0dict.ic @@ -452,6 +452,48 @@ dict_table_zip_size( return(dict_table_flags_to_zip_size(table->flags)); } +/*********************************************************************//** +Obtain exclusive locks on all index trees of the table. This is to prevent +accessing index trees while InnoDB is updating internal metadata for +operations such as truncate tables. */ +UNIV_INLINE +void +dict_table_x_lock_indexes( +/*======================*/ + dict_table_t* table) /*!< in: table */ +{ + dict_index_t* index; + + ut_a(table); + ut_ad(mutex_own(&(dict_sys->mutex))); + + /* Loop through each index of the table and lock them */ + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_lock(dict_index_get_lock(index)); + } +} + +/*********************************************************************//** +Release the exclusive locks on all index tree. */ +UNIV_INLINE +void +dict_table_x_unlock_indexes( +/*========================*/ + dict_table_t* table) /*!< in: table */ +{ + dict_index_t* index; + + ut_a(table); + ut_ad(mutex_own(&(dict_sys->mutex))); + + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + rw_lock_x_unlock(dict_index_get_lock(index)); + } +} /********************************************************************//** Gets the number of fields in the internal representation of an index, including fields added by the dictionary system. diff --git a/storage/xtradb/include/dict0load.h b/storage/xtradb/include/dict0load.h index 60b8c1fb632..f41882019d5 100644 --- a/storage/xtradb/include/dict0load.h +++ b/storage/xtradb/include/dict0load.h @@ -97,6 +97,8 @@ ulint dict_load_foreigns( /*===============*/ const char* table_name, /*!< in: table name */ + ibool check_recursive,/*!< in: Whether to check recursive + load of tables chained by FK */ ibool check_charsets);/*!< in: TRUE=check charsets compatibility */ /********************************************************************//** diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h index 37c5a4a24fc..6736c2a3a36 100644 --- a/storage/xtradb/include/dict0mem.h +++ b/storage/xtradb/include/dict0mem.h @@ -112,6 +112,21 @@ ROW_FORMAT=REDUNDANT. */ in table->flags. */ /* @} */ +/** Tables could be chained together with Foreign key constraint. When +first load the parent table, we would load all of its descedents. +This could result in rescursive calls and out of stack error eventually. +DICT_FK_MAX_RECURSIVE_LOAD defines the maximum number of recursive loads, +when exceeded, the child table will not be loaded. It will be loaded when +the foreign constraint check needs to be run. */ +#define DICT_FK_MAX_RECURSIVE_LOAD 250 + +/** Similarly, when tables are chained together with foreign key constraints +with on cascading delete/update clause, delete from parent table could +result in recursive cascading calls. This defines the maximum number of +such cascading deletes/updates allowed. When exceeded, the delete from +parent table will fail, and user has to drop excessive foreign constraint +before proceeds. */ +#define FK_MAX_CASCADE_DEL 300 /**********************************************************************//** Creates a table memory object. @@ -434,6 +449,12 @@ struct dict_table_struct{ NOT allowed until this count gets to zero; MySQL does NOT itself check the number of open handles at drop */ + unsigned fk_max_recusive_level:8; + /*!< maximum recursive level we support when + loading tables chained together with FK + constraints. If exceeds this level, we will + stop loading child table into memory along with + its parent table */ ulint n_foreign_key_checks_running; /*!< count of how many foreign key check operations are currently being performed diff --git a/storage/xtradb/include/ha0ha.h b/storage/xtradb/include/ha0ha.h index 1ffbd3440aa..3299000bf3c 100644 --- a/storage/xtradb/include/ha0ha.h +++ b/storage/xtradb/include/ha0ha.h @@ -186,6 +186,7 @@ ha_remove_all_nodes_to_page( hash_table_t* table, /*!< in: hash table */ ulint fold, /*!< in: fold value */ const page_t* page); /*!< in: buffer page */ +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /*************************************************************//** Validates a given range of the cells in hash table. @return TRUE if ok */ @@ -196,6 +197,7 @@ ha_validate( hash_table_t* table, /*!< in: hash table */ ulint start_index, /*!< in: start index */ ulint end_index); /*!< in: end index */ +#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ /*************************************************************//** Prints info of a hash table. */ UNIV_INTERN diff --git a/storage/xtradb/include/hash0hash.h b/storage/xtradb/include/hash0hash.h index 9dc20cc057f..492c767acc4 100644 --- a/storage/xtradb/include/hash0hash.h +++ b/storage/xtradb/include/hash0hash.h @@ -363,13 +363,13 @@ do {\ NODE_TYPE* node2222;\ \ if ((TABLE)->array[i2222].node) \ - (TABLE)->array[i2222].node = (void*)((char*)(TABLE)->array[i2222].node \ + (TABLE)->array[i2222].node = (void*)((byte*)(TABLE)->array[i2222].node \ + (((TABLE)->array[i2222].node > (void*)FADDR)?FOFFSET:BOFFSET));\ node2222 = HASH_GET_FIRST((TABLE), i2222);\ \ while (node2222) {\ if (node2222->PTR_NAME) \ - node2222->PTR_NAME = (void*)((char*)node2222->PTR_NAME \ + node2222->PTR_NAME = (void*)((byte*)(node2222->PTR_NAME) \ + ((((void*)node2222->PTR_NAME) > (void*)FADDR)?FOFFSET:BOFFSET));\ \ node2222 = node2222->PTR_NAME;\ diff --git a/storage/xtradb/include/mem0pool.h b/storage/xtradb/include/mem0pool.h index 5e93bf88a47..fa8be296ec9 100644 --- a/storage/xtradb/include/mem0pool.h +++ b/storage/xtradb/include/mem0pool.h @@ -100,18 +100,6 @@ mem_pool_get_reserved( /*==================*/ mem_pool_t* pool); /*!< in: memory pool */ /********************************************************************//** -Reserves the mem pool mutex. */ -UNIV_INTERN -void -mem_pool_mutex_enter(void); -/*======================*/ -/********************************************************************//** -Releases the mem pool mutex. */ -UNIV_INTERN -void -mem_pool_mutex_exit(void); -/*=====================*/ -/********************************************************************//** Validates a memory pool. @return TRUE if ok */ UNIV_INTERN diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index 0c22162b900..c230a03b6db 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -189,7 +189,7 @@ os_event_wait_low( /**********************************************************//** Waits for an event object until it is in the signaled state or -a timeout is exceeded. In Unix the timeout is always infinite. +a timeout is exceeded. @return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ UNIV_INTERN ulint diff --git a/storage/xtradb/include/que0que.h b/storage/xtradb/include/que0que.h index 09a671f49b1..ed48f980294 100644 --- a/storage/xtradb/include/que0que.h +++ b/storage/xtradb/include/que0que.h @@ -381,6 +381,9 @@ struct que_thr_struct{ thus far */ ulint lock_state; /*!< lock state of thread (table or row) */ + ulint fk_cascade_depth; /*!< maximum cascading call depth + supported for foreign key constraint + related delete/updates */ }; #define QUE_THR_MAGIC_N 8476583 diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h index a604f6e3724..f8fab59ef80 100644 --- a/storage/xtradb/include/row0mysql.h +++ b/storage/xtradb/include/row0mysql.h @@ -630,7 +630,11 @@ struct row_prebuilt_struct { the secondary index, then this is set to TRUE */ unsigned templ_contains_blob:1;/*!< TRUE if the template contains - BLOB column(s) */ + a column with DATA_BLOB == + get_innobase_type_from_mysql_type(); + not to be confused with InnoDB + externally stored columns + (VARCHAR can be off-page too) */ mysql_row_templ_t* mysql_template;/*!< template used to transform rows fast between MySQL and Innobase formats; memory for this template diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index 0904a5da1eb..f4c9704741c 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -57,6 +57,9 @@ extern const char srv_mysql50_table_name_prefix[9]; thread starts running */ extern os_event_t srv_lock_timeout_thread_event; +/* This event is set at shutdown to wakeup threads from sleep */ +extern os_event_t srv_shutdown_event; + /* If the last data file is auto-extended, we add this many pages to it at a time */ #define SRV_AUTO_EXTEND_INCREMENT \ @@ -157,6 +160,8 @@ extern ulint srv_mem_pool_size; extern ulint srv_lock_table_size; extern uint srv_buffer_pool_shm_key; +extern ibool srv_buffer_pool_shm_is_reused; +extern ibool srv_buffer_pool_shm_checksum; extern ibool srv_thread_concurrency_timer_based; @@ -340,6 +345,9 @@ extern ulint srv_buf_pool_flushed; reading of a disk page */ extern ulint srv_buf_pool_reads; +/** Time in seconds between automatic buffer pool dumps */ +extern uint srv_auto_lru_dump; + /** Status variables to be passed to MySQL */ typedef struct export_var_struct export_struc; @@ -608,6 +616,16 @@ srv_error_monitor_thread( /*=====================*/ void* arg); /*!< in: a dummy parameter required by os_thread_create */ +/*********************************************************************//** +A thread which restores the buffer pool from a dump file on startup and does +periodic buffer pool dumps. +@return a dummy parameter */ +UNIV_INTERN +os_thread_ret_t +srv_LRU_dump_restore_thread( +/*====================*/ + void* arg); /*!< in: a dummy parameter required by + os_thread_create */ /******************************************************************//** Outputs to a file the output of the InnoDB Monitor. @return FALSE if not all information printed diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 71476443964..8691e3cf337 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -46,8 +46,8 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 10 -#define PERCONA_INNODB_VERSION 12.0 +#define INNODB_VERSION_BUGFIX 12 +#define PERCONA_INNODB_VERSION 12.1 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; diff --git a/storage/xtradb/include/ut0lst.h b/storage/xtradb/include/ut0lst.h index 4305f6571b5..245dfc226c3 100644 --- a/storage/xtradb/include/ut0lst.h +++ b/storage/xtradb/include/ut0lst.h @@ -269,10 +269,10 @@ do { \ TYPE* ut_list_node_313; \ \ if ((BASE).start) \ - (BASE).start = (void*)((char*)((BASE).start) \ + (BASE).start = (void*)((byte*)((BASE).start) \ + (((void*)((BASE).start) > (void*)FADDR)?FOFFSET:BOFFSET));\ if ((BASE).end) \ - (BASE).end = (void*)((char*)((BASE).end) \ + (BASE).end = (void*)((byte*)((BASE).end) \ + (((void*)((BASE).end) > (void*)FADDR)?FOFFSET:BOFFSET));\ \ ut_list_node_313 = (BASE).start; \ @@ -280,10 +280,10 @@ do { \ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \ ut_a(ut_list_node_313); \ if ((ut_list_node_313->NAME).prev) \ - (ut_list_node_313->NAME).prev = (void*)((char*)((ut_list_node_313->NAME).prev) \ + (ut_list_node_313->NAME).prev = (void*)((byte*)((ut_list_node_313->NAME).prev)\ + (((void*)((ut_list_node_313->NAME).prev) > (void*)FADDR)?FOFFSET:BOFFSET));\ if ((ut_list_node_313->NAME).next) \ - (ut_list_node_313->NAME).next = (void *)((char*)((ut_list_node_313->NAME).next) \ + (ut_list_node_313->NAME).next = (void*)((byte*)((ut_list_node_313->NAME).next)\ + (((void*)((ut_list_node_313->NAME).next)> (void*)FADDR)?FOFFSET:BOFFSET));\ ut_list_node_313 = (ut_list_node_313->NAME).next; \ } \ diff --git a/storage/xtradb/include/ut0mem.h b/storage/xtradb/include/ut0mem.h index cf41cba4643..f14606be966 100644 --- a/storage/xtradb/include/ut0mem.h +++ b/storage/xtradb/include/ut0mem.h @@ -113,7 +113,8 @@ ut_test_malloc( ulint n); /*!< in: try to allocate this many bytes */ #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** -Frees a memory block allocated with ut_malloc. */ +Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is +a nop. */ UNIV_INTERN void ut_free( diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c index 7ec4a53e0ea..1ded67d9147 100644 --- a/storage/xtradb/lock/lock0lock.c +++ b/storage/xtradb/lock/lock0lock.c @@ -4606,7 +4606,7 @@ print_rec: nth_lock++; if (nth_lock >= srv_show_locks_held) { - fputs("TOO LOCKS PRINTED FOR THIS TRX:" + fputs("TOO MANY LOCKS PRINTED FOR THIS TRX:" " SUPPRESSING FURTHER PRINTS\n", file); diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c index fade31037b5..3f14d84ac72 100644 --- a/storage/xtradb/log/log0log.c +++ b/storage/xtradb/log/log0log.c @@ -3102,6 +3102,7 @@ logs_empty_and_mark_files_at_shutdown(void) algorithm only works if the server is idle at shutdown */ srv_shutdown_state = SRV_SHUTDOWN_CLEANUP; + os_event_set(srv_shutdown_event); loop: os_thread_sleep(100000); diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c index bbb634addb0..200b3b088a7 100644 --- a/storage/xtradb/log/log0recv.c +++ b/storage/xtradb/log/log0recv.c @@ -2901,6 +2901,7 @@ recv_init_crash_recovery(void) /*==========================*/ { ut_a(!recv_needed_recovery); + ut_a(!srv_buffer_pool_shm_is_reused); recv_needed_recovery = TRUE; diff --git a/storage/xtradb/mem/mem0mem.c b/storage/xtradb/mem/mem0mem.c index c0ce8a3e1ac..1dd4db30841 100644 --- a/storage/xtradb/mem/mem0mem.c +++ b/storage/xtradb/mem/mem0mem.c @@ -367,7 +367,7 @@ mem_heap_create_block( block->line = line; #ifdef MEM_PERIODIC_CHECK - mem_pool_mutex_enter(); + mutex_enter(&(mem_comm_pool->mutex)); if (!mem_block_list_inited) { mem_block_list_inited = TRUE; @@ -376,7 +376,7 @@ mem_heap_create_block( UT_LIST_ADD_LAST(mem_block_list, mem_block_list, block); - mem_pool_mutex_exit(); + mutex_exit(&(mem_comm_pool->mutex)); #endif mem_block_set_len(block, len); mem_block_set_type(block, type); @@ -479,11 +479,11 @@ mem_heap_block_free( UT_LIST_REMOVE(list, heap->base, block); #ifdef MEM_PERIODIC_CHECK - mem_pool_mutex_enter(); + mutex_enter(&(mem_comm_pool->mutex)); UT_LIST_REMOVE(mem_block_list, mem_block_list, block); - mem_pool_mutex_exit(); + mutex_exit(&(mem_comm_pool->mutex)); #endif ut_ad(heap->total_size >= block->len); @@ -556,7 +556,7 @@ mem_validate_all_blocks(void) { mem_block_t* block; - mem_pool_mutex_enter(); + mutex_enter(&(mem_comm_pool->mutex)); block = UT_LIST_GET_FIRST(mem_block_list); @@ -568,6 +568,6 @@ mem_validate_all_blocks(void) block = UT_LIST_GET_NEXT(mem_block_list, block); } - mem_pool_mutex_exit(); + mutex_exit(&(mem_comm_pool->mutex)); } #endif diff --git a/storage/xtradb/mem/mem0pool.c b/storage/xtradb/mem/mem0pool.c index c4f8af607e0..3291453eeb5 100644 --- a/storage/xtradb/mem/mem0pool.c +++ b/storage/xtradb/mem/mem0pool.c @@ -34,6 +34,7 @@ Created 5/12/1997 Heikki Tuuri #include "ut0lst.h" #include "ut0byte.h" #include "mem0mem.h" +#include "srv0start.h" /* We would like to use also the buffer frames to allocate memory. This would be desirable, because then the memory consumption of the database @@ -121,23 +122,33 @@ mysql@lists.mysql.com */ UNIV_INTERN ulint mem_n_threads_inside = 0; /********************************************************************//** -Reserves the mem pool mutex. */ -UNIV_INTERN +Reserves the mem pool mutex if we are not in server shutdown. Use +this function only in memory free functions, since only memory +free functions are used during server shutdown. */ +UNIV_INLINE void -mem_pool_mutex_enter(void) -/*======================*/ +mem_pool_mutex_enter( +/*=================*/ + mem_pool_t* pool) /*!< in: memory pool */ { - mutex_enter(&(mem_comm_pool->mutex)); + if (srv_shutdown_state < SRV_SHUTDOWN_EXIT_THREADS) { + mutex_enter(&(pool->mutex)); + } } /********************************************************************//** -Releases the mem pool mutex. */ -UNIV_INTERN +Releases the mem pool mutex if we are not in server shutdown. As +its corresponding mem_pool_mutex_enter() function, use it only +in memory free functions */ +UNIV_INLINE void -mem_pool_mutex_exit(void) -/*=====================*/ +mem_pool_mutex_exit( +/*================*/ + mem_pool_t* pool) /*!< in: memory pool */ { - mutex_exit(&(mem_comm_pool->mutex)); + if (srv_shutdown_state < SRV_SHUTDOWN_EXIT_THREADS) { + mutex_exit(&(pool->mutex)); + } } /********************************************************************//** @@ -567,7 +578,7 @@ mem_area_free( n = ut_2_log(size); - mutex_enter(&(pool->mutex)); + mem_pool_mutex_enter(pool); mem_n_threads_inside++; ut_a(mem_n_threads_inside == 1); @@ -595,7 +606,7 @@ mem_area_free( pool->reserved += ut_2_exp(n); mem_n_threads_inside--; - mutex_exit(&(pool->mutex)); + mem_pool_mutex_exit(pool); mem_area_free(new_ptr, pool); @@ -611,7 +622,7 @@ mem_area_free( } mem_n_threads_inside--; - mutex_exit(&(pool->mutex)); + mem_pool_mutex_exit(pool); ut_ad(mem_pool_validate(pool)); } @@ -630,7 +641,7 @@ mem_pool_validate( ulint free; ulint i; - mutex_enter(&(pool->mutex)); + mem_pool_mutex_enter(pool); free = 0; @@ -658,7 +669,7 @@ mem_pool_validate( ut_a(free + pool->reserved == pool->size); - mutex_exit(&(pool->mutex)); + mem_pool_mutex_exit(pool); return(TRUE); } diff --git a/storage/xtradb/os/os0proc.c b/storage/xtradb/os/os0proc.c index c101db3d179..4567d96b6f4 100644 --- a/storage/xtradb/os/os0proc.c +++ b/storage/xtradb/os/os0proc.c @@ -246,12 +246,10 @@ os_shm_alloc( #if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H ulint size; int shmid; -#endif *is_new = FALSE; -#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H fprintf(stderr, - "InnoDB: The shared memory key %#x (%d) is specified.\n", + "InnoDB: The shared memory segment containing the buffer pool is: key %#x (%d).\n", key, key); # if defined HAVE_LARGE_PAGES && defined UNIV_LINUX if (!os_use_large_pages || !os_large_page_size) { @@ -268,12 +266,12 @@ os_shm_alloc( if (shmid < 0) { if (errno == EEXIST) { fprintf(stderr, - "InnoDB: HugeTLB: The shared memory segment seems to exist already.\n"); + "InnoDB: HugeTLB: The shared memory segment exists.\n"); shmid = shmget((key_t)key, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W); if (shmid < 0) { fprintf(stderr, - "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes.(reuse) errno %d\n", + "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. (reuse) errno %d\n", size, errno); goto skip; } else { @@ -282,14 +280,14 @@ os_shm_alloc( } } else { fprintf(stderr, - "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes.(new) errno %d\n", + "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. (new) errno %d\n", size, errno); goto skip; } } else { *is_new = TRUE; fprintf(stderr, - "InnoDB: HugeTLB: The new shared memory segment is created.\n"); + "InnoDB: HugeTLB: A new shared memory segment has been created .\n"); } ptr = shmat(shmid, NULL, 0); @@ -325,12 +323,12 @@ skip: if (shmid < 0) { if (errno == EEXIST) { fprintf(stderr, - "InnoDB: The shared memory segment seems to exist already.\n"); + "InnoDB: A shared memory segment containing the buffer pool seems to already exist.\n"); shmid = shmget((key_t)key, (size_t)size, SHM_R | SHM_W); if (shmid < 0) { fprintf(stderr, - "InnoDB: Warning: Failed to allocate %lu bytes.(reuse) errno %d\n", + "InnoDB: Warning: Failed to allocate %lu bytes. (reuse) errno %d\n", size, errno); ptr = NULL; goto end; @@ -340,7 +338,7 @@ skip: } } else { fprintf(stderr, - "InnoDB: Warning: Failed to allocate %lu bytes.(new) errno %d\n", + "InnoDB: Warning: Failed to allocate %lu bytes. (new) errno %d\n", size, errno); ptr = NULL; goto end; @@ -348,7 +346,7 @@ skip: } else { *is_new = TRUE; fprintf(stderr, - "InnoDB: The new shared memory segment is created.\n"); + "InnoDB: A new shared memory segment has been created.\n"); } ptr = shmat(shmid, NULL, 0); diff --git a/storage/xtradb/os/os0sync.c b/storage/xtradb/os/os0sync.c index 60467242e14..f9ab58c2ee4 100644 --- a/storage/xtradb/os/os0sync.c +++ b/storage/xtradb/os/os0sync.c @@ -31,6 +31,9 @@ Created 9/6/1995 Heikki Tuuri #ifdef __WIN__ #include <windows.h> +#else +#include <sys/time.h> +#include <time.h> #endif #include "ut0mem.h" @@ -407,14 +410,14 @@ os_event_wait_low( /**********************************************************//** Waits for an event object until it is in the signaled state or -a timeout is exceeded. In Unix the timeout is always infinite. +a timeout is exceeded. @return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ UNIV_INTERN ulint os_event_wait_time( /*===============*/ os_event_t event, /*!< in: event to wait */ - ulint time) /*!< in: timeout in microseconds, or + ulint wtime) /*!< in: timeout in microseconds, or OS_SYNC_INFINITE_TIME */ { #ifdef __WIN__ @@ -422,8 +425,8 @@ os_event_wait_time( ut_a(event); - if (time != OS_SYNC_INFINITE_TIME) { - err = WaitForSingleObject(event->handle, (DWORD) time / 1000); + if (wtime != OS_SYNC_INFINITE_TIME) { + err = WaitForSingleObject(event->handle, (DWORD) wtime / 1000); } else { err = WaitForSingleObject(event->handle, INFINITE); } @@ -439,13 +442,47 @@ os_event_wait_time( return(1000000); /* dummy value to eliminate compiler warn. */ } #else - UT_NOT_USED(time); + int err; + int ret = 0; + ulint tmp; + ib_int64_t old_count; + struct timeval tv_start; + struct timespec timeout; + + if (wtime == OS_SYNC_INFINITE_TIME) { + os_event_wait(event); + return 0; + } + + /* Compute the absolute point in time at which to time out. */ + gettimeofday(&tv_start, NULL); + tmp = tv_start.tv_usec + wtime; + timeout.tv_sec = tv_start.tv_sec + (tmp / 1000000); + timeout.tv_nsec = (tmp % 1000000) * 1000; + + os_fast_mutex_lock(&(event->os_mutex)); + old_count = event->signal_count; + + for (;;) { + if (event->is_set == TRUE || event->signal_count != old_count) + break; + + err = pthread_cond_timedwait(&(event->cond_var), + &(event->os_mutex), &timeout); + if (err == ETIMEDOUT) { + ret = OS_SYNC_TIME_EXCEEDED; + break; + } + } - /* In Posix this is just an ordinary, infinite wait */ + os_fast_mutex_unlock(&(event->os_mutex)); - os_event_wait(event); + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + + os_thread_exit(NULL); + } - return(0); + return ret; #endif } diff --git a/storage/xtradb/plug.in b/storage/xtradb/plug.in index 37c895fb520..67f25755762 100644 --- a/storage/xtradb/plug.in +++ b/storage/xtradb/plug.in @@ -17,7 +17,7 @@ MYSQL_STORAGE_ENGINE(xtradb, xtradb, [XtraDB Storage Engine], [XtraDB - a drop-in replacement for InnoDB], [max,max-no-ndb]) MYSQL_PLUGIN_DIRECTORY(xtradb, [storage/xtradb]) -MYSQL_PLUGIN_STATIC(xtradb, [libxtradb.a]) +MYSQL_PLUGIN_STATIC(xtradb, [libxtradb.la]) MYSQL_PLUGIN_DYNAMIC(xtradb, [ha_xtradb.la]) MYSQL_PLUGIN_ACTIONS(xtradb, [ with_plugin_innobase=$with_plugin_xtradb # for legacy code in configure.in diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c index 47c03c77850..65102851bdf 100644 --- a/storage/xtradb/row/row0merge.c +++ b/storage/xtradb/row/row0merge.c @@ -1787,6 +1787,11 @@ row_merge_copy_blobs( (below). */ data = btr_rec_copy_externally_stored_field( mrec, offsets, zip_size, i, &len, heap); + /* Because we have locked the table, any records + written by incomplete transactions must have been + rolled back already. There must not be any incomplete + BLOB columns. */ + ut_a(data); dfield_set_data(field, data, len); } @@ -2399,7 +2404,7 @@ row_merge_rename_tables( goto err_exit; } - err = dict_load_foreigns(old_name, TRUE); + err = dict_load_foreigns(old_name, FALSE, TRUE); if (err != DB_SUCCESS) { err_exit: diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c index 62221fa456d..56754404b65 100644 --- a/storage/xtradb/row/row0mysql.c +++ b/storage/xtradb/row/row0mysql.c @@ -577,6 +577,13 @@ handle_new_error: "InnoDB: " REFMAN "forcing-recovery.html" " for help.\n", stderr); break; + case DB_FOREIGN_EXCEED_MAX_CASCADE: + fprintf(stderr, "InnoDB: Cannot delete/update rows with" + " cascading foreign key constraints that exceed max" + " depth of %lu\n" + "Please drop excessive foreign constraints" + " and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD); + break; default: fprintf(stderr, "InnoDB: unknown error code %lu\n", (ulong) err); @@ -1392,11 +1399,15 @@ row_update_for_mysql( run_again: thr->run_node = node; thr->prev_node = node; + thr->fk_cascade_depth = 0; row_upd_step(thr); err = trx->error_state; + /* Reset fk_cascade_depth back to 0 */ + thr->fk_cascade_depth = 0; + if (err != DB_SUCCESS) { que_thr_stop_for_mysql(thr); @@ -1587,6 +1598,12 @@ row_update_cascade_for_mysql( trx_t* trx; trx = thr_get_trx(thr); + + thr->fk_cascade_depth++; + + if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) { + return (DB_FOREIGN_EXCEED_MAX_CASCADE); + } run_again: thr->run_node = node; thr->prev_node = node; @@ -2106,7 +2123,7 @@ row_table_add_foreign_constraints( name, reject_fks); if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ - err = dict_load_foreigns(name, TRUE); + err = dict_load_foreigns(name, FALSE, TRUE); } if (err != DB_SUCCESS) { @@ -2799,6 +2816,15 @@ row_truncate_table_for_mysql( trx->table_id = table->id; + /* Lock all index trees for this table, as we will + truncate the table/index and possibly change their metadata. + All DML/DDL are blocked by table level lock, with + a few exceptions such as queries into information schema + about the table, MySQL could try to access index stats + for this kind of query, we need to use index locks to + sync up */ + dict_table_x_lock_indexes(table); + if (table->space && !table->dir_path_of_temp_table) { /* Discard and create the single-table tablespace. */ ulint space = table->space; @@ -2815,6 +2841,7 @@ row_truncate_table_for_mysql( || fil_create_new_single_table_tablespace( space, table->name, FALSE, flags, FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) { + dict_table_x_unlock_indexes(table); ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: TRUNCATE TABLE %s failed to" @@ -2918,6 +2945,10 @@ next_rec: mem_heap_free(heap); + /* Done with index truncation, release index tree locks, + subsequent work relates to table level metadata change */ + dict_table_x_unlock_indexes(table); + dict_hdr_get_new_id(&new_id, NULL, NULL); info = pars_info_create(); @@ -3967,7 +3998,7 @@ end: an ALTER, not in a RENAME. */ err = dict_load_foreigns( - new_name, !old_is_tmp || trx->check_foreigns); + new_name, FALSE, !old_is_tmp || trx->check_foreigns); if (err != DB_SUCCESS) { ut_print_timestamp(stderr); diff --git a/storage/xtradb/row/row0row.c b/storage/xtradb/row/row0row.c index cb7dfa2b7c9..8e806a14a98 100644 --- a/storage/xtradb/row/row0row.c +++ b/storage/xtradb/row/row0row.c @@ -294,7 +294,13 @@ row_build( ut_ad(dtuple_check_typed(row)); - if (j) { + if (!ext) { + /* REDUNDANT and COMPACT formats store a local + 768-byte prefix of each externally stored + column. No cache is needed. */ + ut_ad(dict_table_get_format(index->table) + < DICT_TF_FORMAT_ZIP); + } else if (j) { *ext = row_ext_create(j, ext_cols, row, dict_table_zip_size(index->table), heap); diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index 0db4fb6f3db..a1511e35435 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -416,7 +416,7 @@ row_sel_fetch_columns( field_no))) { /* Copy an externally stored field to the - temporary heap */ + temporary heap, if possible. */ heap = mem_heap_create(1); @@ -425,6 +425,17 @@ row_sel_fetch_columns( dict_table_zip_size(index->table), field_no, &len, heap); + /* data == NULL means that the + externally stored field was not + written yet. This record + should only be seen by + recv_recovery_rollback_active() or any + TRX_ISO_READ_UNCOMMITTED + transactions. The InnoDB SQL parser + (the sole caller of this function) + does not implement READ UNCOMMITTED, + and it is not involved during rollback. */ + ut_a(data); ut_a(len != UNIV_SQL_NULL); needs_copy = TRUE; @@ -926,6 +937,7 @@ row_sel_get_clust_rec( when plan->clust_pcur was positioned. The latch will not be released until mtr_commit(mtr). */ + ut_ad(!rec_get_deleted_flag(clust_rec, rec_offs_comp(offsets))); row_sel_fetch_columns(index, clust_rec, offsets, UT_LIST_GET_FIRST(plan->columns)); *out_rec = clust_rec; @@ -1628,6 +1640,13 @@ skip_lock: } if (old_vers == NULL) { + /* The record does not exist + in our read view. Skip it, but + first attempt to determine + whether the index segment we + are searching through has been + exhausted. */ + offsets = rec_get_offsets( rec, index, offsets, ULINT_UNDEFINED, &heap); @@ -2647,9 +2666,8 @@ Convert a row in the Innobase format to a row in the MySQL format. Note that the template in prebuilt may advise us to copy only a few columns to mysql_rec, other columns are left blank. All columns may not be needed in the query. -@return TRUE if success, FALSE if could not allocate memory for a BLOB -(though we may also assert in that case) */ -static +@return TRUE on success, FALSE if not all columns could be retrieved */ +static __attribute__((warn_unused_result)) ibool row_sel_store_mysql_rec( /*====================*/ @@ -2719,6 +2737,21 @@ row_sel_store_mysql_rec( dict_table_zip_size(prebuilt->table), templ->rec_field_no, &len, heap); + if (UNIV_UNLIKELY(!data)) { + /* The externally stored field + was not written yet. This + record should only be seen by + recv_recovery_rollback_active() + or any TRX_ISO_READ_UNCOMMITTED + transactions. */ + + if (extern_field_heap) { + mem_heap_free(extern_field_heap); + } + + return(FALSE); + } + ut_a(len != UNIV_SQL_NULL); } else { /* Field is stored in the row. */ @@ -3136,9 +3169,10 @@ row_sel_pop_cached_row_for_mysql( } /********************************************************************//** -Pushes a row for MySQL to the fetch cache. */ -UNIV_INLINE -void +Pushes a row for MySQL to the fetch cache. +@return TRUE on success, FALSE if the record contains incomplete BLOBs */ +UNIV_INLINE __attribute__((warn_unused_result)) +ibool row_sel_push_cache_row_for_mysql( /*=============================*/ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */ @@ -3180,10 +3214,11 @@ row_sel_push_cache_row_for_mysql( prebuilt->fetch_cache[ prebuilt->n_fetch_cached], prebuilt, rec, offsets))) { - ut_error; + return(FALSE); } prebuilt->n_fetch_cached++; + return(TRUE); } /*********************************************************************//** @@ -3576,14 +3611,25 @@ row_search_for_mysql( row_sel_try_search_shortcut_for_mysql(). The latch will not be released until mtr_commit(&mtr). */ + ut_ad(!rec_get_deleted_flag(rec, comp)); if (!row_sel_store_mysql_rec(buf, prebuilt, rec, offsets)) { - err = DB_TOO_BIG_RECORD; - - /* We let the main loop to do the - error handling */ - goto shortcut_fails_too_big_rec; + /* Only fresh inserts may contain + incomplete externally stored + columns. Pretend that such + records do not exist. Such + records may only be accessed + at the READ UNCOMMITTED + isolation level or when + rolling back a recovered + transaction. Rollback happens + at a lower level, not here. */ + ut_a(trx->isolation_level + == TRX_ISO_READ_UNCOMMITTED); + + /* Proceed as in case SEL_RETRY. */ + break; } mtr_commit(&mtr); @@ -3623,7 +3669,7 @@ release_search_latch_if_needed: default: ut_ad(0); } -shortcut_fails_too_big_rec: + mtr_commit(&mtr); mtr_start(&mtr); } @@ -4217,7 +4263,7 @@ no_gap_lock: rec = old_vers; } - } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) { + } else { /* We are looking into a non-clustered index, and to get the right version of the record we have to look also into the clustered index: this @@ -4225,8 +4271,12 @@ no_gap_lock: information via the clustered index record. */ ut_ad(index != clust_index); + ut_ad(!dict_index_is_clust(index)); - goto requires_clust_rec; + if (!lock_sec_rec_cons_read_sees( + rec, trx->read_view)) { + goto requires_clust_rec; + } } } @@ -4349,8 +4399,13 @@ requires_clust_rec: ULINT_UNDEFINED, &heap); result_rec = rec; } + + /* result_rec can legitimately be delete-marked + now that it has been established that it points to a + clustered index record that exists in the read view. */ } else { result_rec = rec; + ut_ad(!rec_get_deleted_flag(rec, comp)); } /* We found a qualifying record 'result_rec'. At this point, @@ -4382,9 +4437,18 @@ requires_clust_rec: not cache rows because there the cursor is a scrollable cursor. */ - row_sel_push_cache_row_for_mysql(prebuilt, result_rec, - offsets); - if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) { + if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec, + offsets)) { + /* Only fresh inserts may contain incomplete + externally stored columns. Pretend that such + records do not exist. Such records may only be + accessed at the READ UNCOMMITTED isolation + level or when rolling back a recovered + transaction. Rollback happens at a lower + level, not here. */ + ut_a(trx->isolation_level == TRX_ISO_READ_UNCOMMITTED); + } else if (prebuilt->n_fetch_cached + == MYSQL_FETCH_CACHE_SIZE) { goto got_row; } @@ -4400,9 +4464,17 @@ requires_clust_rec: } else { if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec, offsets)) { - err = DB_TOO_BIG_RECORD; - - goto lock_wait_or_error; + /* Only fresh inserts may contain + incomplete externally stored + columns. Pretend that such records do + not exist. Such records may only be + accessed at the READ UNCOMMITTED + isolation level or when rolling back a + recovered transaction. Rollback + happens at a lower level, not here. */ + ut_a(trx->isolation_level + == TRX_ISO_READ_UNCOMMITTED); + goto next_rec; } } diff --git a/storage/xtradb/row/row0undo.c b/storage/xtradb/row/row0undo.c index 9ef842b5114..fd28a4f6520 100644 --- a/storage/xtradb/row/row0undo.c +++ b/storage/xtradb/row/row0undo.c @@ -199,8 +199,24 @@ row_undo_search_clust_to_pcur( ret = FALSE; } else { + row_ext_t** ext; + + if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) { + /* In DYNAMIC or COMPRESSED format, there is + no prefix of externally stored columns in the + clustered index record. Build a cache of + column prefixes. */ + ext = &node->ext; + } else { + /* REDUNDANT and COMPACT formats store a local + 768-byte prefix of each externally stored + column. No cache is needed. */ + ext = NULL; + node->ext = NULL; + } + node->row = row_build(ROW_COPY_DATA, clust_index, rec, - offsets, NULL, &node->ext, node->heap); + offsets, NULL, ext, node->heap); if (node->update) { node->undo_row = dtuple_copy(node->row, node->heap); row_upd_replace(node->undo_row, &node->undo_ext, diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c index d0aaecd3dae..04c3139fcc7 100644 --- a/storage/xtradb/row/row0upd.c +++ b/storage/xtradb/row/row0upd.c @@ -1398,6 +1398,7 @@ row_upd_store_row( dict_index_t* clust_index; rec_t* rec; mem_heap_t* heap = NULL; + row_ext_t** ext; ulint offsets_[REC_OFFS_NORMAL_SIZE]; const ulint* offsets; rec_offs_init(offsets_); @@ -1414,8 +1415,22 @@ row_upd_store_row( offsets = rec_get_offsets(rec, clust_index, offsets_, ULINT_UNDEFINED, &heap); + + if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) { + /* In DYNAMIC or COMPRESSED format, there is no prefix + of externally stored columns in the clustered index + record. Build a cache of column prefixes. */ + ext = &node->ext; + } else { + /* REDUNDANT and COMPACT formats store a local + 768-byte prefix of each externally stored column. + No cache is needed. */ + ext = NULL; + node->ext = NULL; + } + node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets, - NULL, &node->ext, node->heap); + NULL, ext, node->heap); if (node->is_delete) { node->upd_row = NULL; node->upd_ext = NULL; @@ -1583,6 +1598,7 @@ row_upd_clust_rec_by_insert( dict_table_t* table; dtuple_t* entry; ulint err; + ibool change_ownership = FALSE; ut_ad(node); ut_ad(dict_index_is_clust(index)); @@ -1615,9 +1631,9 @@ row_upd_clust_rec_by_insert( index = dict_table_get_first_index(table); offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); - btr_cur_mark_extern_inherited_fields( - btr_cur_get_page_zip(btr_cur), - rec, index, offsets, node->update, mtr); + change_ownership = btr_cur_mark_extern_inherited_fields( + btr_cur_get_page_zip(btr_cur), rec, index, offsets, + node->update, mtr); if (check_ref) { /* NOTE that the following call loses the position of pcur ! */ @@ -1646,10 +1662,11 @@ row_upd_clust_rec_by_insert( row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id); - if (node->upd_ext) { + if (change_ownership) { /* If we return from a lock wait, for example, we may have extern fields marked as not-owned in entry (marked in the - if-branch above). We must unmark them. */ + if-branch above). We must unmark them, take the ownership + back. */ btr_cur_unmark_dtuple_extern_fields(entry); diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c index b9905116603..35745072445 100644 --- a/storage/xtradb/srv/srv0srv.c +++ b/storage/xtradb/srv/srv0srv.c @@ -213,6 +213,8 @@ UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX; /* key value for shm */ UNIV_INTERN uint srv_buffer_pool_shm_key = 0; +UNIV_INTERN ibool srv_buffer_pool_shm_is_reused = FALSE; +UNIV_INTERN ibool srv_buffer_pool_shm_checksum = TRUE; /* This parameter is deprecated. Use srv_n_io_[read|write]_threads instead. */ @@ -307,6 +309,9 @@ UNIV_INTERN ulint srv_buf_pool_flushed = 0; reading of a disk page */ UNIV_INTERN ulint srv_buf_pool_reads = 0; +/** Time in seconds between automatic buffer pool dumps */ +UNIV_INTERN uint srv_auto_lru_dump = 0; + /* structure to pass status variables to MySQL */ UNIV_INTERN export_struc export_vars; @@ -699,6 +704,8 @@ UNIV_INTERN srv_slot_t* srv_mysql_table = NULL; UNIV_INTERN os_event_t srv_lock_timeout_thread_event; +UNIV_INTERN os_event_t srv_shutdown_event; + UNIV_INTERN srv_sys_t* srv_sys = NULL; /* padding to prevent other memory update hotspots from residing on @@ -1004,6 +1011,7 @@ srv_init(void) } srv_lock_timeout_thread_event = os_event_create(NULL); + srv_shutdown_event = os_event_create(NULL); for (i = 0; i < SRV_MASTER + 1; i++) { srv_n_threads_active[i] = 0; @@ -2231,7 +2239,7 @@ loop: /* Wake up every 5 seconds to see if we need to print monitor information. */ - os_thread_sleep(5000000); + os_event_wait_time(srv_shutdown_event, 5000000); current_time = time(NULL); @@ -2373,7 +2381,7 @@ loop: /* When someone is waiting for a lock, we wake up every second and check if a timeout has passed for a lock wait */ - os_thread_sleep(1000000); + os_event_wait_time(srv_shutdown_event, 1000000); srv_lock_timeout_active = TRUE; @@ -2538,7 +2546,7 @@ loop: fflush(stderr); - os_thread_sleep(1000000); + os_event_wait_time(srv_shutdown_event, 1000000); if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) { @@ -2555,6 +2563,56 @@ loop: OS_THREAD_DUMMY_RETURN; } +/*********************************************************************//** +A thread which restores the buffer pool from a dump file on startup and does +periodic buffer pool dumps. +@return a dummy parameter */ +UNIV_INTERN +os_thread_ret_t +srv_LRU_dump_restore_thread( +/*====================*/ + void* arg __attribute__((unused))) + /*!< in: a dummy parameter required by + os_thread_create */ +{ + uint auto_lru_dump; + time_t last_dump_time; + time_t time_elapsed; + +#ifdef UNIV_DEBUG_THREAD_CREATION + fprintf(stderr, "LRU dump/restore thread starts, id %lu\n", + os_thread_pf(os_thread_get_curr_id())); +#endif + + if (srv_auto_lru_dump) + buf_LRU_file_restore(); + + last_dump_time = time(NULL); + +loop: + os_event_wait_time(srv_shutdown_event, 5000000); + + if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) { + goto exit_func; + } + + time_elapsed = time(NULL) - last_dump_time; + auto_lru_dump = srv_auto_lru_dump; + if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) { + last_dump_time = time(NULL); + buf_LRU_file_dump(); + } + + goto loop; +exit_func: + /* We count the number of threads in os_thread_exit(). A created + thread should always use that to exit and not use return() to exit. */ + + os_thread_exit(NULL); + + OS_THREAD_DUMMY_RETURN; +} + /*******************************************************************//** Tells the InnoDB server that there has been activity in the database and wakes up the master thread if it is suspended (not sleeping). Used @@ -2696,7 +2754,7 @@ loop: if (!skip_sleep) { - os_thread_sleep(1000000); + os_event_wait_time(srv_shutdown_event, 1000000); srv_main_sleeps++; /* @@ -3282,9 +3340,10 @@ loop: mutex_exit(&kernel_mutex); sleep_ms = 10; + os_event_reset(srv_shutdown_event); } - os_thread_sleep( sleep_ms * 1000 ); + os_event_wait_time(srv_shutdown_event, sleep_ms * 1000); history_len = trx_sys->rseg_history_len; if (history_len > 1000) diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c index 62ffa366f18..b36faf2d2d7 100644 --- a/storage/xtradb/srv/srv0start.c +++ b/storage/xtradb/srv/srv0start.c @@ -126,9 +126,9 @@ static mutex_t ios_mutex; static ulint ios; /** io_handler_thread parameters for thread identification */ -static ulint n[SRV_MAX_N_IO_THREADS + 6 + 64]; +static ulint n[SRV_MAX_N_IO_THREADS + 7 + 64]; /** io_handler_thread identifiers */ -static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6 + 64]; +static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 7 + 64]; /** We use this mutex to test the return value of pthread_mutex_trylock on successful locking. HP-UX does NOT return 0, though Linux et al do. */ @@ -1719,8 +1719,8 @@ innobase_start_or_create_for_mysql(void) Note that this is not as heavy weight as it seems. At this point there will be only ONE page in the buf_LRU and there must be no page in the buf_flush list. */ - /* TODO: treat more correctly */ - if (!srv_buffer_pool_shm_key) + /* buffer_pool_shm should not be reused when recovery was needed. */ + if (!srv_buffer_pool_shm_is_reused) buf_pool_invalidate(); /* We always try to do a recovery, even if the database had @@ -1835,6 +1835,10 @@ innobase_start_or_create_for_mysql(void) os_thread_create(&srv_monitor_thread, NULL, thread_ids + 4 + SRV_MAX_N_IO_THREADS); + /* Create the thread which automaticaly dumps/restore buffer pool */ + os_thread_create(&srv_LRU_dump_restore_thread, NULL, + thread_ids + 5 + SRV_MAX_N_IO_THREADS); + srv_is_being_started = FALSE; if (trx_doublewrite == NULL) { @@ -1859,13 +1863,13 @@ innobase_start_or_create_for_mysql(void) ulint i; os_thread_create(&srv_purge_thread, NULL, thread_ids - + (5 + SRV_MAX_N_IO_THREADS)); + + (6 + SRV_MAX_N_IO_THREADS)); for (i = 0; i < srv_use_purge_thread - 1; i++) { - n[6 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */ + n[7 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */ os_thread_create(&srv_purge_worker_thread, - n + (6 + i + SRV_MAX_N_IO_THREADS), - thread_ids + (6 + i + SRV_MAX_N_IO_THREADS)); + n + (7 + i + SRV_MAX_N_IO_THREADS), + thread_ids + (7 + i + SRV_MAX_N_IO_THREADS)); } } #ifdef UNIV_DEBUG @@ -2214,6 +2218,10 @@ innobase_shutdown_for_mysql(void) log_mem_free(); buf_pool_free(); mem_close(); + + /* ut_free_all_mem() frees all allocated memory not freed yet + in shutdown, and it will also free the ut_list_mutex, so it + should be the last one for all operation */ ut_free_all_mem(); if (os_thread_count != 0 diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c index ad4471ada0b..11581a3f2ae 100644 --- a/storage/xtradb/trx/trx0sys.c +++ b/storage/xtradb/trx/trx0sys.c @@ -541,8 +541,8 @@ start_again: log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE); fprintf(stderr, "InnoDB: Doublewrite buffer created in the doublewrite file\n"); + trx_sys_multiple_tablespace_format = TRUE; } - trx_doublewrite_buf_is_being_created = FALSE; } } diff --git a/storage/xtradb/trx/trx0undo.c b/storage/xtradb/trx/trx0undo.c index 063a2f2b8a6..ec4beb5660a 100644 --- a/storage/xtradb/trx/trx0undo.c +++ b/storage/xtradb/trx/trx0undo.c @@ -1976,7 +1976,8 @@ trx_undo_update_cleanup( UT_LIST_ADD_FIRST(undo_list, rseg->update_undo_cached, undo); } else { - ut_ad(undo->state == TRX_UNDO_TO_PURGE); + ut_ad(undo->state == TRX_UNDO_TO_PURGE + || undo->state == TRX_UNDO_TO_FREE); trx_undo_mem_free(undo); } diff --git a/storage/xtradb/ut/ut0mem.c b/storage/xtradb/ut/ut0mem.c index 35a325b9ccd..bf55e4273b6 100644 --- a/storage/xtradb/ut/ut0mem.c +++ b/storage/xtradb/ut/ut0mem.c @@ -290,7 +290,8 @@ ut_test_malloc( #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** -Frees a memory block allocated with ut_malloc. */ +Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is +a nop. */ UNIV_INTERN void ut_free( @@ -300,7 +301,9 @@ ut_free( #ifndef UNIV_HOTBACKUP ut_mem_block_t* block; - if (UNIV_LIKELY(srv_use_sys_malloc)) { + if (ptr == NULL) { + return; + } else if (UNIV_LIKELY(srv_use_sys_malloc)) { free(ptr); return; } diff --git a/strings/Makefile.am b/strings/Makefile.am index 9b0c1a33250..6a09abe7479 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -17,6 +17,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include pkglib_LIBRARIES = libmystrings.a +noinst_LTLIBRARIES = libmystrings.la # Exact one of ASSEMBLER_X if ASSEMBLER_x86 @@ -37,7 +38,7 @@ CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend. endif endif -libmystrings_a_SOURCES = $(ASRCS) $(CSRCS) +libmystrings_la_SOURCES = $(ASRCS) $(CSRCS) noinst_PROGRAMS = conf_to_src CLEANFILES = str_test uctypedump test_decimal # Default charset definitions @@ -56,9 +57,9 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc t_ctype.h my_strchr.c CMakeLists.txt \ CHARSET_INFO.txt strmov_overlapp.c -libmystrings_a_LIBADD= -conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c bcmp.c -conf_to_src_LDADD= +libmystrings_la_LIBADD= +conf_to_src_SOURCES = conf_to_src.c +conf_to_src_LDADD = libmystrings.a #force static linking of conf_to_src - essential when linking against #custom installation of libc conf_to_src_LDFLAGS= @NOINST_LDFLAGS@ @@ -66,6 +67,9 @@ conf_to_src_LDFLAGS= @NOINST_LDFLAGS@ # This is because the dependency tracking misses @FOO@ vars in sources. #strtoull.o: @CHARSET_OBJS@ +libmystrings_a_SOURCES= +libmystrings.a: libmystrings.la + $(CP) .libs/libmystrings.a $@ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@ diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index 17a7ddb5855..27ef0e5cc07 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -25,7 +25,7 @@ socket = @MYSQL_UNIX_ADDR@ [mysqld] port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ -skip-locking +skip-external-locking key_buffer_size = 384M max_allowed_packet = 1M table_open_cache = 512 diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh index 305a6ee3006..da2b35b8950 100644 --- a/support-files/my-innodb-heavy-4G.cnf.sh +++ b/support-files/my-innodb-heavy-4G.cnf.sh @@ -109,6 +109,16 @@ binlog_cache_size = 1M # table which could otherwise use up all memory resources. max_heap_table_size = 64M +# Size of the buffer used for doing full table scans. +# Allocated per thread, if a full scan is needed. +read_buffer_size = 2M + +# When reading rows in sorted order after a sort, the rows are read +# through this buffer to avoid disk seeks. You can improve ORDER BY +# performance a lot, if set this to a high value. +# Allocated per thread, when needed. +read_rnd_buffer_size = 16M + # Sort buffer is used to perform sorts for some ORDER BY and GROUP BY # queries. If sorted data does not fit into the sort buffer, a disk # based merge sort is used instead - See the "Sort_merge_passes" @@ -310,16 +320,6 @@ server-id = 1 # used for internal temporary disk tables. key_buffer_size = 32M -# Size of the buffer used for doing full table scans of MyISAM tables. -# Allocated per thread, if a full scan is needed. -read_buffer_size = 2M - -# When reading rows in sorted order after a sort, the rows are read -# through this buffer to avoid disk seeks. You can improve ORDER BY -# performance a lot, if set this to a high value. -# Allocated per thread, when needed. -read_rnd_buffer_size = 16M - # MyISAM uses special tree-like cache to make bulk inserts (that is, # INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., and LOAD DATA # INFILE) faster. This variable limits the size of the cache tree in diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index bbdfdb32a96..812009136f1 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -25,7 +25,7 @@ socket = @MYSQL_UNIX_ADDR@ [mysqld] port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ -skip-locking +skip-external-locking key_buffer_size = 256M max_allowed_packet = 1M table_open_cache = 256 diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh index 88113d0a8d4..8fd62eaf958 100644 --- a/support-files/my-medium.cnf.sh +++ b/support-files/my-medium.cnf.sh @@ -26,7 +26,7 @@ socket = @MYSQL_UNIX_ADDR@ [mysqld] port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ -skip-locking +skip-external-locking key_buffer_size = 16M max_allowed_packet = 1M table_open_cache = 64 diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index 7dce9e60ed9..c0a86ae9671 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -26,7 +26,7 @@ socket = @MYSQL_UNIX_ADDR@ [mysqld] port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ -skip-locking +skip-external-locking key_buffer_size = 16K max_allowed_packet = 1M table_open_cache = 4 diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 0b8781210e5..b1b10225940 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -18340,6 +18340,107 @@ static void test_bug54041() } +/** + Bug#47485: mysql_store_result returns a result set for a prepared statement +*/ +static void test_bug47485() +{ + MYSQL_STMT *stmt; + MYSQL_RES *res; + MYSQL_BIND bind[2]; + int rc; + const char* sql_select = "SELECT 1, 'a'"; + int int_data; + char str_data[16]; + my_bool is_null[2]; + my_bool error[2]; + unsigned long length[2]; + + DBUG_ENTER("test_bug47485"); + myheader("test_bug47485"); + + stmt= mysql_stmt_init(mysql); + check_stmt(stmt); + rc= mysql_stmt_prepare(stmt, sql_select, strlen(sql_select)); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + res = mysql_store_result(mysql); + DIE_UNLESS(res == NULL); + + mysql_stmt_reset(stmt); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + res = mysql_use_result(mysql); + DIE_UNLESS(res == NULL); + + mysql_stmt_reset(stmt); + + memset(bind, 0, sizeof(bind)); + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].buffer= (char *)&int_data; + bind[0].is_null= &is_null[0]; + bind[0].length= &length[0]; + bind[0].error= &error[0]; + + bind[1].buffer_type= MYSQL_TYPE_STRING; + bind[1].buffer= (char *)str_data; + bind[1].buffer_length= sizeof(str_data); + bind[1].is_null= &is_null[1]; + bind[1].length= &length[1]; + bind[1].error= &error[1]; + + rc= mysql_stmt_bind_result(stmt, bind); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_store_result(stmt); + check_execute(stmt, rc); + + while (!(rc= mysql_stmt_fetch(stmt))) + ; + + DIE_UNLESS(rc == MYSQL_NO_DATA); + + mysql_stmt_reset(stmt); + + memset(bind, 0, sizeof(bind)); + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].buffer= (char *)&int_data; + bind[0].is_null= &is_null[0]; + bind[0].length= &length[0]; + bind[0].error= &error[0]; + + bind[1].buffer_type= MYSQL_TYPE_STRING; + bind[1].buffer= (char *)str_data; + bind[1].buffer_length= sizeof(str_data); + bind[1].is_null= &is_null[1]; + bind[1].length= &length[1]; + bind[1].error= &error[1]; + + rc= mysql_stmt_bind_result(stmt, bind); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + while (!(rc= mysql_stmt_fetch(stmt))) + ; + + DIE_UNLESS(rc == MYSQL_NO_DATA); + + mysql_stmt_close(stmt); + + DBUG_VOID_RETURN; +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -18663,6 +18764,7 @@ static struct my_tests_st my_tests[]= { { "test_bug44495", test_bug44495 }, { "test_bug42373", test_bug42373 }, { "test_bug54041", test_bug54041 }, + { "test_bug47485", test_bug47485 }, { 0, 0 } }; diff --git a/unittest/unit.pl b/unittest/unit.pl index a1aab376fdf..be6424ec798 100644 --- a/unittest/unit.pl +++ b/unittest/unit.pl @@ -65,7 +65,7 @@ sub _find_test_files (@) { my @dirs = @_; my @files; find sub { - $File::Find::prune = 1 if /^SCCS$/; + $File::Find::prune = 1 if /^(SCCS|\.libs)$/; push(@files, $File::Find::name) if -x _ && (/-t\z/ || /-t\.exe\z/); }, @dirs; return @files; diff --git a/vio/Makefile.am b/vio/Makefile.am index c70af1008cd..588cd3ea0c4 100644 --- a/vio/Makefile.am +++ b/vio/Makefile.am @@ -17,9 +17,15 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(openssl_includes) LDADD = @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) $(yassl_libs) pkglib_LIBRARIES = libvio.a +noinst_LTLIBRARIES = libvio.la noinst_HEADERS = vio_priv.h -libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c +libvio_la_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c EXTRA_DIST= CMakeLists.txt + +libvio_a_SOURCES= +libvio.a: libvio.la + $(CP) .libs/libvio.a $@ + diff --git a/win/configure-mariadb.sh b/win/configure-mariadb.sh index 294b1530788..b3433ee568f 100644 --- a/win/configure-mariadb.sh +++ b/win/configure-mariadb.sh @@ -12,7 +12,7 @@ cscript win/configure.js \ WITH_BLACKHOLE_STORAGE_ENGINE \ WITH_CSV_STORAGE_ENGINE \ WITH_EXAMPLE_STORAGE_ENGINE \ - WITH_FEDERATED_STORAGE_ENGINE \ + WITH_FEDERATEDX_STORAGE_ENGINE \ WITH_MERGE_STORAGE_ENGINE \ WITH_PARTITION_STORAGE_ENGINE \ WITH_MARIA_STORAGE_ENGINE \ |